Skip to content

Fix ArrayIndexOutOfBoundsException in Extended XMP processing#712

Merged
drewnoakes merged 3 commits intodrewnoakes:mainfrom
alicanalbayrak:fix/extended-xmp-bounds-check
Feb 2, 2026
Merged

Fix ArrayIndexOutOfBoundsException in Extended XMP processing#712
drewnoakes merged 3 commits intodrewnoakes:mainfrom
alicanalbayrak:fix/extended-xmp-bounds-check

Conversation

@alicanalbayrak
Copy link
Copy Markdown
Contributor

@alicanalbayrak alicanalbayrak commented Jan 30, 2026

Summary

Adds bounds validation before System.arraycopy in XmpReader.processExtendedXMPChunk() to prevent crashes when processing malformed Extended XMP metadata.

Fixes #711

The Bug

When processing Extended XMP chunks, the code allocates a buffer based on the declared fullLength, then copies chunk data at chunkOffset. However, there was no validation that chunkOffset + copyLength <= buffer.length, causing ArrayIndexOutOfBoundsException:

 java.lang.ArrayIndexOutOfBoundsException: arraycopy: last destination index 15334120 out of bounds for byte[15262528]
      at com.drew.metadata.xmp.XmpReader.processExtendedXMPChunk(XmpReader.java:296)

The Fix

The bounds check handles:

  1. Buffer overflow: chunkOffset + copyLength > buffer.length
  2. Negative offset: uint32 values > Integer.MAX_VALUE become negative when cast to int
  3. Integer overflow: Uses subtraction instead of addition to avoid overflow

Sample Image

Included Tests/Data/malformed_extended_xmp.jpg - a minimal (847 bytes) 1x1 pixel JPEG that reproduces the bug for regression testing.

These tests demonstrate an ArrayIndexOutOfBoundsException in
XmpReader.processExtendedXMPChunk() when processing malformed
Extended XMP segments where:

1. chunkOffset exceeds the declared fullLength (buffer size)
2. chunkOffset + chunkDataLength exceeds the buffer bounds

The current code at XmpReader.java:296 does:
 System.arraycopy(segmentBytes, totalOffset, extendedXMPBuffer, chunkOffset, segmentLength - totalOffset)

It validates extendedXMPBuffer.length == fullLength, but doesn't validate -
 chunkOffset + (segmentLength - totalOffset) <= extendedXMPBuffer.length

This causes crashes when processing JPEGs with corrupted or
malformed Extended XMP metadata.
Add bounds validation before System.arraycopy in processExtendedXMPChunk()
to prevent crashes when processing malformed Extended XMP metadata.

The fix handles two edge cases:
- chunkOffset + copyLength exceeds buffer size
- chunkOffset is negative (from uint32 > Integer.MAX_VALUE cast to int)

Uses subtraction instead of addition to avoid integer overflow:
  if (chunkOffset < 0 || chunkOffset > buffer.length - copyLength)

Includes sample JPEG file (malformed_extended_xmp.jpg) for regression testing.

Fixes drewnoakes#308
drewnoakes added a commit to drewnoakes/metadata-extractor-images that referenced this pull request Feb 2, 2026
Adds an image provided by @alicanalbayrak in
drewnoakes/metadata-extractor#712 that
reproduces a bug in how we handle extended XMP data.
@drewnoakes
Copy link
Copy Markdown
Owner

Thanks very much for the fix here, and for providing a sample image.

It's customary in this repo that we don't add test images to the tree here. Instead, they go into a separate repo which is used for regression testing. I've pushed the image there already (drewnoakes/metadata-extractor-images@651ad0e). Please remove it and the unit test from this PR. There are just too many combinations of inputs for us to have unit tests for all of them, and the regression suite gives excellent coverage.

@alicanalbayrak
Copy link
Copy Markdown
Contributor Author

Hi @drewnoakes, I've addressed your comment. Cheers

Copy link
Copy Markdown
Owner

@drewnoakes drewnoakes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much!

@drewnoakes drewnoakes merged commit 5fe5f17 into drewnoakes:main Feb 2, 2026
4 checks passed
don-vip pushed a commit to don-vip/metadata-extractor that referenced this pull request Feb 13, 2026
…akes#712)

Add bounds validation before System.arraycopy in processExtendedXMPChunk()
to prevent crashes when processing malformed Extended XMP metadata.

The fix handles two edge cases:
- chunkOffset + copyLength exceeds buffer size
- chunkOffset is negative (from uint32 > Integer.MAX_VALUE cast to int)

Uses subtraction instead of addition to avoid integer overflow:
  if (chunkOffset < 0 || chunkOffset > buffer.length - copyLength)

Fixes drewnoakes#308
don-vip pushed a commit to don-vip/metadata-extractor that referenced this pull request Feb 13, 2026
…akes#712)

Add bounds validation before System.arraycopy in processExtendedXMPChunk()
to prevent crashes when processing malformed Extended XMP metadata.

The fix handles two edge cases:
- chunkOffset + copyLength exceeds buffer size
- chunkOffset is negative (from uint32 > Integer.MAX_VALUE cast to int)

Uses subtraction instead of addition to avoid integer overflow:
  if (chunkOffset < 0 || chunkOffset > buffer.length - copyLength)

Fixes drewnoakes#308
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ArrayIndexOutOfBoundsException in XmpReader.processExtendedXMPChunk with malformed Extended XMP

2 participants