CI: Run test suite on Java 8 matrix; make tests Java 8 compatible. - #4
Merged
Conversation
Jamesr51d
approved these changes
Jul 7, 2026
18 tasks
jwrosewell
added a commit
that referenced
this pull request
Aug 31, 2026
* Check the declared payload length against the bytes present before allocating Io.Reader.readByteArray took the sender's declared payload count and passed it to readBytes, which checked the count against the end of the buffer before sizing the copy, so this port never allocated from the declared number alone. What it did not check was that the payload is followed by exactly the 64 byte signature and nothing else. A declared count short of the bytes present parsed, with the signature read from the middle of the envelope and the remainder ignored, and an envelope with bytes after the signature parsed with those bytes ignored. The reference fix in owid-dotnet sets the rule every port now follows, so the same malformed envelopes are refused the same way everywhere. The count is now checked against the bytes present before anything is sized by it. A valid OWID is the declared payload followed by the 64 byte signature and nothing else, so the count must equal the bytes remaining less the signature length, and any other count, short or long, is refused with the existing OwidException, which names the declared length and the bytes present. Envelopes with a byte after the signature, previously ignored, are now refused as malformed. The separate Integer.MAX_VALUE check is gone because the new check covers it. The other length driven reads were checked and none needed changing, being the domain terminator scan, which stops at the end of the buffer, and the date and signature reads, which go through the bounded readBytes. PayloadLengthTest covers a matching envelope, the library's own signed output, off-by-one counts, a trailing byte, a short signature, declared lengths of 64 MiB, 2 GiB and 0xFFFFFFFF each refused with under 64 KiB allocated on the thread, and an empty payload. The Javadoc on Owid.fromByteArray and on the serialized form now say the signature ends the envelope. Files changed: src/main/java/com/swancommunity/owid/Io.java src/main/java/com/swancommunity/owid/Owid.java src/test/java/com/swancommunity/owid/PayloadLengthTest.java * Clarify and optimize large payload handling * Bound the domain read at the published maximum The creator domain is stored as text followed by a zero terminator, and the reader found the end of it by walking forward to that terminator. A missing or corrupted terminator sent the walk to the end of the buffer, so the cost of parsing was set by the length of the input rather than by the size of the field, which is the same class of attacker controlled work as the declared payload length this branch already checks. RFC 1035 section 2.3.4, "Size limits", restricts the total length of a domain name to 255 octets or less. That number counts the wire format, which spends one length octet on every label and one zero octet on the root. An OWID stores the presentation form instead, being the text "example.com", where the dots stand in for the label length octets and the root has no text at all, so the same published limit is two characters shorter here. The new constant MAXIMUM_DOMAIN_LENGTH in Io carries that reasoning next to the number. The reader now stops at the maximum rather than at the end of the buffer, so an unterminated field costs no more than the maximum however long the buffer is, and a domain over the maximum is refused without reading past it. The refusal uses the existing OwidException with a new message, because the module has one exception type and no error variants to add to. Nothing about a valid envelope changes. New tests cover a domain at the maximum parsing and round tripping, one character over being refused, a buffer with no terminator at all being refused, a sixteen mebibyte domain field being refused while allocating under 64 KiB, and the library's own signed output still parsing and verifying. The suite goes from 43 to 48 tests, all passing. * Refuse to write a domain longer than the maximum Reading an OWID has been bounded at the published maximum for a domain name since the previous commit, but writing one was not, so a creator configured with a longer domain still produced an OWID that this same library would refuse to parse. A library that can emit what it cannot read leaves the fault to surface at the consumer rather than at the creator. The one constant, Io.MAXIMUM_DOMAIN_LENGTH, now bounds both halves. Creator.create refuses a domain over the maximum when the caller supplies it, before the crypto instance is looked at and before any OWID exists, and Io.writeString refuses one that reaches serialisation by another route such as Owid.setDomain. Both raise the OwidException the read raises, through one shared factory, so the two halves report the one condition in the same words. The length counted is the UTF-8 bytes, being what the read counts as it walks to the terminator. Nothing at or under the maximum behaves differently. Four tests cover a creator holding a domain of exactly the maximum signing an OWID that round trips and verifies, a creator refused one character over with the maximum named in the message, the refusal arriving before the private key is used, and serialisation refusing a domain that arrived by another route. Removing only the two new checks fails three of the four.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.