Skip to content

Fix MemoryMappedFileInputStream.read() returning sign-extended values for bytes over 0x7F - #875

Open
lenamonj wants to merge 1 commit into
apache:masterfrom
lenamonj:io-mmap-read-unsigned
Open

lenamonj wants to merge 1 commit into
apache:masterfrom
lenamonj:io-mmap-read-unsigned

Conversation

@lenamonj

@lenamonj lenamonj commented Sep 7, 2026

Copy link
Copy Markdown

MemoryMappedFileInputStream.read() returned Short.toUnsignedInt(buffer.get()), which widens the byte to a short with sign extension before masking, so every byte from 0x80 to 0xFF came back as 0xFF80 to 0xFFFF instead of 128 to 255. InputStream.read() promises 0 to 255, and a caller copying byte by byte writes the wrong values out. The existing testReadSingleByte casts each result back to byte before comparing, which hides the difference.

The change masks with & 0xFF, as the other single-byte read() implementations in this package do.

Test: testReadSingleByteIsUnsigned, red on master and green with the change. Default Maven goal green.

  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute? Claude (Anthropic) found the defect and drafted the fix and test; I reviewed them, reproduced the failure on a fresh clone of master, and ran the default Maven goal.
  • Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.

… for bytes over 0x7F

Short.toUnsignedInt(byte) sign-extends the byte to a short before masking,
so read() returned 0xFF80 to 0xFFFF for input bytes 0x80 to 0xFF where
InputStream.read() promises 0 to 255. Mask with 0xFF as the other read()
implementations in this package do.
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.

1 participant