Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullRestricted attribute cant be in primitive or array field #18006

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions runtime/bcutil/ClassFileOracle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,15 @@ ClassFileOracle::walkFields()
break;
#if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES)
case CFR_ATTRIBUTE_NullRestricted:
/* JVMS: There must not be a NullRestricted attribute in the attributes table of a field_info
* structure whose descriptor_index references a primitive type or an array type.*/
if (!IS_REF_OR_VAL_SIGNATURE(fieldChar)) {
if ('[' == fieldChar) {
throwGenericErrorWithCustomMsg(J9NLS_CFR_NO_NULLRESTRICTED_IN_ARRAYFIELD__ID, fieldIndex);
} else { /* primitive type*/
throwGenericErrorWithCustomMsg(J9NLS_CFR_NO_NULLRESTRICTED_IN_PRIMITIVEFIELD__ID, fieldIndex);
}
}
_fieldsInfo[fieldIndex].isNullRestricted = true;
break;
#endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */
Expand Down
16 changes: 16 additions & 0 deletions runtime/nls/cfre/cfrerr.nls
Original file line number Diff line number Diff line change
Expand Up @@ -1758,3 +1758,19 @@ J9NLS_CFR_ERR_IMPLICITCREATION_ILLEGAL_CLASS_MODIFIERS.explanation=Please consul
J9NLS_CFR_ERR_IMPLICITCREATION_ILLEGAL_CLASS_MODIFIERS.system_action=The JVM will throw a verification or classloading related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_IMPLICITCREATION_ILLEGAL_CLASS_MODIFIERS.user_response=Contact the provider of the classfile for a corrected version.
# END NON-TRANSLATABLE

# NullRestricted is not translatable
J9NLS_CFR_NO_NULLRESTRICTED_IN_ARRAYFIELD=A field with an array type cannot have a NullRestricted attribute
# START NON-TRANSLATABLE
J9NLS_CFR_NO_NULLRESTRICTED_IN_ARRAYFIELD.explanation=Please consult the Java Virtual Machine Specification for a detailed explanation.
J9NLS_CFR_NO_NULLRESTRICTED_IN_ARRAYFIELD.system_action=The JVM will throw a verification or classloading related exception such as java.lang.ClassFormatError.
J9NLS_CFR_NO_NULLRESTRICTED_IN_ARRAYFIELD.user_response=Contact the provider of the classfile for a corrected version.
# END NON-TRANSLATABLE

# NullRestricted is not translatable
J9NLS_CFR_NO_NULLRESTRICTED_IN_PRIMITIVEFIELD=A field with a primitive type cannot have a NullRestricted attribute
# START NON-TRANSLATABLE
J9NLS_CFR_NO_NULLRESTRICTED_IN_PRIMITIVEFIELD.explanation=Please consult the Java Virtual Machine Specification for a detailed explanation.
J9NLS_CFR_NO_NULLRESTRICTED_IN_PRIMITIVEFIELD.system_action=The JVM will throw a verification or classloading related exception such as java.lang.ClassFormatError.
J9NLS_CFR_NO_NULLRESTRICTED_IN_PRIMITIVEFIELD.user_response=Contact the provider of the classfile for a corrected version.
# END NON-TRANSLATABLE
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,36 @@ public static Class<?> generateValidClassWithImplicitCreationAttribute(String na
return generator.defineClass(name, bytes, 0, bytes.length);
}

public static Class<?> generateFieldWithMultipleNullRestrictedAttributes(String className, String fieldClassName) throws Throwable {
/* Generate field class - value class with ImplicitCreation attribute and ACC_DEFAULT flag set */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute(ValhallaUtils.ACC_DEFAULT)});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

/* Generate class with field and multiple NullRestricted attributes */
byte[] classBytes = generateClassWithField(className, ValhallaUtils.ACC_IDENTITY,
"field", fieldClass.descriptorString(), new Attribute[]{new NullRestrictedAttribute(), new NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

public static Class<?> generateNullRestrictedAttributeInPrimitiveField(String className) throws Throwable {
/* Generate class with primitive field and a NullRestricted attribute */
byte[] classBytes = generateClassWithField(className, ValhallaUtils.ACC_IDENTITY,
"field", "I", new Attribute[]{new NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

public static Class<?> generateNullRestrictedAttributeInArrayField(String className, String fieldClassName) throws Throwable {
/* Generate field class - value class with ImplicitCreation attribute and ACC_DEFAULT flag set. */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute(ValhallaUtils.ACC_DEFAULT)});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

/* Generate class field field that is an array with a NullRestricted attribute */
byte[] classBytes = generateClassWithField(className, ValhallaUtils.ACC_IDENTITY,
"field", "[" + fieldClass.descriptorString(), new Attribute[]{new NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}
public static Class<?> findLoadedTestClass(String name) {
return generator.findLoadedClass(name);
}
Expand All @@ -76,6 +106,21 @@ public static byte[] generateClass(String name, int classFlags, Attribute[] attr
return classWriter.toByteArray();
}

public static byte[] generateClassWithField(String name, int classFlags, String fieldName, String fieldDescriptor, Attribute[] fieldAttributes) {
ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(ValhallaUtils.CLASS_FILE_MAJOR_VERSION, classFlags, name, null, "java/lang/Object", null);

FieldVisitor fieldVisitor = classWriter.visitField(0, fieldName, fieldDescriptor, null, null);
if (null != fieldAttributes) {
for (Attribute attr : fieldAttributes) {
fieldVisitor.visitAttribute(attr);
}
}

classWriter.visitEnd();
return classWriter.toByteArray();
}

final static class PreloadAttribute extends Attribute {
private final String[] classes;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,22 @@ static public void testNonValueTypeClassWithImplicitCreationAttribute() throws T
static public void testValueTypeClassWithImplicitCreationAttribute() throws Throwable {
ValhallaAttributeGenerator.generateValidClassWithImplicitCreationAttribute("ValueTypeClassWithImplicitCreationAttribute");
}

/* There must be no more than one NullRestricted attribute in the attributes table of a field_info structure */
@Test(expectedExceptions = java.lang.ClassFormatError.class, expectedExceptionsMessageRegExp = ".*Multiple NullRestricted attributes present.*")
static public void testMultipleNullRestrictedAttributes() throws Throwable {
ValhallaAttributeGenerator.generateFieldWithMultipleNullRestrictedAttributes("TestMultipleNullRestrictedAttributes", "TestMultipleNullRestrictedAttributesField");
}

/* There must not be a NullRestricted attribute in the attributes table of a field_info structure whose descriptor_index references a primitive type. */
@Test(expectedExceptions = java.lang.ClassFormatError.class, expectedExceptionsMessageRegExp = ".*A field with a primitive type cannot have a NullRestricted attribute.*")
static public void testNullRestrictedNotAllowedInPrimitiveField() throws Throwable {
ValhallaAttributeGenerator.generateNullRestrictedAttributeInPrimitiveField("TestNullRestrictedNotAllowedInPrimitiveField");
}

/* There must not be a NullRestricted attribute in the attributes table of a field_info structure whose descriptor_index references an array type */
@Test(expectedExceptions = java.lang.ClassFormatError.class, expectedExceptionsMessageRegExp = ".*A field with an array type cannot have a NullRestricted attribute.*")
static public void testNullRestrictedNotAllowedInArrayTypeField() throws Throwable {
ValhallaAttributeGenerator.generateNullRestrictedAttributeInArrayField("TestNullRestrictedNotAllowedInArrayTypeField", "TestNullRestrictedNotAllowedInArrayTypeFieldField");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ public class ValhallaUtils {
static final int ACC_IDENTITY = 0x20;
static final int ACC_VALUE_TYPE = 0x040;
static final int ACC_PRIMITIVE = 0x800;

/* ImplicitCreation flags */
static final int ACC_DEFAULT = 0x1;
static final int ACC_NON_ATOMIC = 0x2;

}