fix: use minimal integer encoding and decode fixint bytes#13
Merged
Conversation
Encoder now routes all integer types through encode_int/encode_uint so the smallest format that fits is always selected (positive/negative fixint, u8/u16/u32/u64, i8/i16/i32/i64), per the MessagePack spec's minimal-encoding requirement. Default config flips positive_int_unsigned to true so non-negative values use the more compact unsigned family. Decoder gains match arms for positive fixint (0x00-0x7f) and negative fixint (0xe0-0xff) in both decode_integer and decode_to_json, fixing inability to decode output from spec-compliant implementations (Python, Rust, Go) and from this library's own corrected encoder. Test assertions updated to spec-compliant bytes. Reported in vlang/v#26644.
This was referenced May 26, 2026
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
Fixes three interop-breaking bugs in the integer encode/decode paths, reported in vlang/v#26644.
encode(0)producedd2 00 00 00 00instead of00. The genericencode[T]()dispatcher bypassed the existingencode_int/encode_uintfunctions (which already implement minimal encoding) and called fixed-width helpers directly. Now all integer types route throughencode_int/encode_uint. The missingi32case is also added.positive_int_unsigneddefaulted tofalse. Non-negative values 128–255 took the signed branch and encoded as 3-byte int16 instead of 2-byte uint8. Default config now sets it totrue.decode_integeranddecode_to_jsonhad nomatcharms for0x00–0x7for0xe0–0xff, so any value in-32..127encoded by a spec-compliant library (Python, Rust, Go) — or by this library after the encoder fix — could not be decoded. Both functions now handle the fixint ranges.encode_test.vassertions are updated to the spec-compliant minimal bytes.Test plan
v test .— all 3 test files pass (decode, encode, decode_to_json)encode(0)→00,encode(42)→2a,encode(127)→7fencode(-32)→e0,encode(-123)→d0 85,encode(-1)→ffencode(200)→cc c8(uint8, not signed int16)encode([1,2,3])→93 01 02 03decode(encode(x))for fixint and uint8 ranges2a,00,fb,e0,ff)