format: XML in UTF-16, and a size range that stops failing on sizes a format cannot write - #88
Merged
Conversation
… format cannot write Two changes, and the second was found by the first. XML gains encoding and bom, through the textenc package txt and md already stand on. Both default to what these documents have always been, so the ten pinned hashes are unchanged whether a recipe says nothing or says utf-8 out loud. XML is the first format here whose file SAYS which encoding it is in, so it is the first that can disagree with itself: the declaration follows the bytes, and a guard reads that from the bytes rather than through a decoder, which would have to be told what to expect and would then agree with itself. Measured before any of it was written. Expat refuses a declaration that disagrees with the bytes in both directions, so there is a witness outside this project. It ACCEPTS a UTF-16 document with no byte order mark, though, and reads it correctly - so nothing here could go red on one, and asking for utf-16 without a mark is refused rather than written. Then the range. Some formats cannot write every byte count: a UTF-16 file is always an even number of bytes, and a picture cannot use the handful just above its encoded size. A drawn size landing on one of those took the whole run down, and whether that happened depended on the seed and the count. A range asks for some size between two ends rather than for a number, so a drawn size is now moved to the nearest writable one inside the range, and files that moved carry a note. The comment here said closing this needed formats to declare their unreachable bands, a change to format.Descriptor. It needed no such thing - the refusal already names the next writable size. A range starting below what a format can do at all is still refused, and --size 1001 still refuses, because that one named a number. Ten runs across ten formats come out byte for byte what they were. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Two changes, and the second was found while measuring the first.
XML can be written in UTF-16
encoding(utf-8,utf-16le,utf-16be) andbom, through thetextencpackage
txtandmdalready stand on. Both default to what these documentshave always been.
XML is the first format here whose file says which encoding it is in, so it
is the first that can disagree with itself. A document announcing UTF-8 while
holding UTF-16 is the classic parser trap, and it stays the right size, hashes
stably and parses under the encoding it really is.
Measured before any of it was written, seven cases with the expected answer
written down first:
So there is a witness outside this project, in both directions.
The fifth row decided the shape of the setting. The XML specification requires a
mark on a UTF-16 entity, and expat accepts a document without one and reads it
correctly - checked by comparing the content, not just the verdict. Nothing
here could go red on such a file, so
utf-16withbom=falseis refused ratherthan written.
Costs, both stated in the refusals: a UTF-16 file always has an even number of
bytes, so half of every size is unreachable and an odd size is refused naming
the nearest above and below. The smallest XML file grows from 264 B to 532 B.
A size range stops failing on sizes a format cannot write
Some formats cannot produce every byte count. A UTF-16 file is always even. A
picture cannot use the eleven byte counts just above its encoded size, because
the smallest padding chunk costs twelve, and the three OPC formats have the same
shape. A size drawn onto one of those took the whole run down, and whether
that happened depended on the seed and the number of files.
A range asks for some size between two ends rather than for a number, so a
drawn size is now moved to the nearest writable one inside the range.
The comment in
drawSizeshad said since 2026-09-06 that closing this "needs theformat to declare its unreachable bands, which is a change to
format.Descriptorand the owner's call". It needed no such thing - a refusal already names the
next writable size, so probing and jumping does it with no new surface. PNG
answers 143 B with 154 B, and a wide encoding answers an odd size with the next
even one.
Two things are deliberately unchanged, and the first version of this got the
line wrong until an existing guard said so:
naming the floor.
zip 2000-9000briefly produced four identical files on thefloor instead - that is a recipe worth correcting, not a run worth filling.
--size 1001still refuses, because that one named a number.Snapping is not silent: a file whose size moved carries
size_movedin themanifest, and the run says so once. The note text carries no number on purpose,
since notes group by text and a number would give one line per file.
What holds
utf-8out loud - two different routes through the parser.same bytes as before.
retargeted after
drawSizesmoved to its own file -staleness.pywas theonly thing that noticed.
engine.gowent past the size ceiling, sodrawSizeswas cut out rather thanthe ceiling raised.
Analysis written before the code, with what was not measured:
docs/XML-ENCODING-2026-09-08.md. Verdict for the range:O190.🤖 Generated with Claude Code