imageFile.hpp from the libjimage library has this comment about ATTRIBUTE_END:
// - Even though ATTRIBUTE_END is used to mark the end of the attribute stream,
// streams will contain non-zero byte values to represent lesser significant bits.
// Thus, detecting a zero byte is not sufficient to detect the end of an attribute
// stream.
Yet, the libjimage code doesn't handle non-zero bytes when it reads an image file here:
// Inflates the attribute stream into individual values stored in the long
// array _attributes. This allows an attribute value to be quickly accessed by
// direct indexing. Unspecified values default to zero (from constructor.)
void ImageLocation::set_data(u1* data) {
// Deflate the attribute stream into an array of attributes.
u1 byte;
// Repeat until end header is found.
while ((data != NULL) && (byte = *data)) {
// Extract kind from header byte.
u1 kind = attribute_kind(byte);
assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
if (kind == ATTRIBUTE_END) {
break;
}
// Extract length of data (in bytes).
u1 n = attribute_length(byte);
// Read value (most significant first.)
_attributes[kind] = attribute_value(data + 1, n);
// Position to next attribute by skipping attribute header and data bytes.
data += n + 1;
}
}
So if a JDK would produce a lib/modules file with this patch, for example (setting all 3 lower length bits, thus making the byte non-zero):
diff --git a/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java b/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
index f31c7291927..a7de4f9a6c2 100644
--- a/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
+++ b/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
@@ -99,7 +99,7 @@ public class ImageLocation {
}
}
- stream.put(ATTRIBUTE_END << 3);
+ stream.put(ATTRIBUTE_END << 3 | 0x7);
return stream.toArray();
}
... it segfaults early on:
build/linux-x86_64-server-release/support/interim-image/bin/java -version
Segmentation fault (core dumped)
// - Even though ATTRIBUTE_END is used to mark the end of the attribute stream,
// streams will contain non-zero byte values to represent lesser significant bits.
// Thus, detecting a zero byte is not sufficient to detect the end of an attribute
// stream.
Yet, the libjimage code doesn't handle non-zero bytes when it reads an image file here:
// Inflates the attribute stream into individual values stored in the long
// array _attributes. This allows an attribute value to be quickly accessed by
// direct indexing. Unspecified values default to zero (from constructor.)
void ImageLocation::set_data(u1* data) {
// Deflate the attribute stream into an array of attributes.
u1 byte;
// Repeat until end header is found.
while ((data != NULL) && (byte = *data)) {
// Extract kind from header byte.
u1 kind = attribute_kind(byte);
assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
if (kind == ATTRIBUTE_END) {
break;
}
// Extract length of data (in bytes).
u1 n = attribute_length(byte);
// Read value (most significant first.)
_attributes[kind] = attribute_value(data + 1, n);
// Position to next attribute by skipping attribute header and data bytes.
data += n + 1;
}
}
So if a JDK would produce a lib/modules file with this patch, for example (setting all 3 lower length bits, thus making the byte non-zero):
diff --git a/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java b/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
index f31c7291927..a7de4f9a6c2 100644
--- a/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
+++ b/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
@@ -99,7 +99,7 @@ public class ImageLocation {
}
}
- stream.put(ATTRIBUTE_END << 3);
+ stream.put(ATTRIBUTE_END << 3 | 0x7);
return stream.toArray();
}
... it segfaults early on:
build/linux-x86_64-server-release/support/interim-image/bin/java -version
Segmentation fault (core dumped)