Repository navigation
Conversation
SigmaByteWriter.write() used a bare Uint8Array index assignment, so a write past the fixed buffer capacity was silently dropped while the cursor advanced past the end; writeBits() had the same flaw. Callers size buffers with exact estimates (ErgoTree total size, box size, exact VLQ test lengths), so an overflow means the estimate was wrong — and the writer returned a silently truncated serialization instead of failing. toBytes() then clamped the over-advanced cursor, hiding the corruption entirely. write() and writeBits() now throw a RangeError naming the position and the buffer capacity, checked before any byte or bit is written so a failed write leaves the cursor and content untouched. writeBytes() already failed closed via Uint8Array.set and is unchanged. This mirrors the SigmaByteReader out-of-bounds fix: the codec fails closed on length mismatches in both directions.
🦋 Changeset detectedLatest commit: f3c3c27 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
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.
Summary
SigmaByteWriterfails open when a write exceeds its fixed buffer capacity:write(byte)assigns through a bareUint8Arrayindex. An out-of-bounds assignment is silently ignored by the platform, but#cursor++still advances past the end — so the byte vanishes and the cursor claims it was written.writeBits(bits)has the same flaw: bits past the capacity are computed againstundefinedand dropped while the cursor advances.toBytes()then returnssubarray(0, cursor), which clamps to the real buffer length, hiding the corruption entirely. The caller gets a silently truncated serialization that parses as a different value (or fails downstream with an unrelated error).Every in-repo caller sizes its writer with an exact estimate — ErgoTree's computed total size, the box serializer's 4096-byte maximum,
SConstant's guessed size, even the test suite'snew SigmaByteWriter(tv.hex.length)exact-length writers — so an overflow can only mean the estimate was wrong, and wrong estimates were being converted into corrupt output instead of an error.Fix
write()throws aRangeErrornaming the position and the buffer capacity when the cursor is already at the end, checked before writing, so a failed write leaves the cursor and the written bytes untouched.writeBits()performs the same check upfront for theceil(bits / 8)bytes it needs.writeBytes()is deliberately unchanged: it delegates toUint8Array.set, which already throws aRangeErroron overflow without copying anything (pinned by a regression test here).writeBool, the VLQ writers behindwriteUInt/writeBigUInt, the zig-zag integer writers,writeHex,writeChecksum) now fails closed through them.This is the write-side mirror of the
SigmaByteReaderout-of-bounds fix (out-of-bounds reads now throw instead of inventing data): the codec fails closed on length mismatches in both directions. One design note: the reference Scala writer appends to a growable buffer, but Fleet's writers are deliberately fixed-capacity with exact up-front estimates, so failing loudly on an exceeded estimate is the behavior consistent with this codebase rather than silently growing the buffer and masking the estimation bug.Deliberate non-change: the byte value passed to
write()is still not range-checked (e.g. 256 wraps to 0 via the typed array, as before) — the typed writers are the checked layer, as with the earlier range fixes in this series.Tests
Tests first: on pristine
master, the newwrite, VLQ-overflow, andwriteBitstests fail (nothing is thrown; bytes are silently dropped), while thewriteBytestest already passes viaUint8Array.set. With the fix:sigmaByteWriter.spec.ts: single-byte overflow (with cursor/content untouched after the throw), byte-array overflow plus exact-fit success, multi-byte VLQ overflow through bothwriteUIntandwriteBigUInt, and bit overflow plus an exact-fit 8-bit write.Changeset included:
@fleet-sdk/serializer, patch.— @Kshot9000