nssalian commented on code in PR #16568:
URL: https://github.com/apache/iceberg/pull/16568#discussion_r3555529419
##########
api/src/main/java/org/apache/iceberg/variants/SerializedMetadata.java:
##########
@@ -59,15 +59,32 @@ static SerializedMetadata from(ByteBuffer metadata) {
private SerializedMetadata(ByteBuffer metadata, int header) {
this.isSorted = (header & SORTED_STRINGS) == SORTED_STRINGS;
this.offsetSize = 1 + ((header & OFFSET_SIZE_MASK) >> OFFSET_SIZE_SHIFT);
+ Preconditions.checkArgument(
+ metadata.remaining() >= HEADER_SIZE + offsetSize,
+ "Invalid variant metadata: buffer too small for dictionary size
field");
int dictSize = ByteBuffers.readLittleEndianUnsigned(metadata, HEADER_SIZE,
offsetSize);
- this.dict = new String[dictSize];
+ Preconditions.checkArgument(
+ dictSize >= 0, "Invalid variant metadata: negative dictionary size
%s", dictSize);
this.offsetListOffset = HEADER_SIZE + offsetSize;
+ long offsetTableEnd = (long) offsetListOffset + ((long) dictSize + 1L) *
offsetSize;
+ Preconditions.checkArgument(
+ offsetTableEnd <= metadata.remaining(),
+ "Invalid variant metadata: dictionary size %s exceeds buffer",
+ dictSize);
+ this.dict = new String[dictSize];
this.dataOffset = offsetListOffset + ((1 + dictSize) * offsetSize);
- int endOffset =
- dataOffset
- + ByteBuffers.readLittleEndianUnsigned(
- metadata, offsetListOffset + (offsetSize * dictSize),
offsetSize);
- if (endOffset < metadata.limit()) {
+ int lastOffset =
+ ByteBuffers.readLittleEndianUnsigned(
+ metadata, offsetListOffset + (offsetSize * dictSize), offsetSize);
+ Preconditions.checkArgument(
+ lastOffset >= 0, "Invalid variant metadata: negative end offset %s",
lastOffset);
+ long endOffsetLong = (long) dataOffset + lastOffset;
+ Preconditions.checkArgument(
+ endOffsetLong <= metadata.remaining(),
+ "Invalid variant metadata: end offset %s exceeds buffer",
+ endOffsetLong);
+ int endOffset = (int) endOffsetLong;
+ if (endOffset < metadata.remaining()) {
Review Comment:
Agreed, this is a genuine behavioral fix rather than just hardening - the
old `endOffset`-vs-`limit` comparison was wrong for any buffer with a non-zero
position. Called it out in the PR description as a separate change.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]