From ba1d0aba9aef2f88bfdb05758d4636ec44a3a9b6 Mon Sep 17 00:00:00 2001 From: roundspring2003 Date: Wed, 25 Mar 2026 19:11:22 +0800 Subject: [PATCH] fix: align constrained INTEGER length encoding with decoder --- aper_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ marshal.go | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/aper_test.go b/aper_test.go index 3b48be2..f6d8a05 100644 --- a/aper_test.go +++ b/aper_test.go @@ -581,6 +581,46 @@ func TestStructInteger(t *testing.T) { } } +type intMarshalRegressionLargeRange4096To131071 struct { + Value int64 `aper:"valueLB:4096,valueUB:131071"` +} + +type intMarshalRegressionLargeRange0To100000 struct { + Value int64 `aper:"valueLB:0,valueUB:100000"` +} + +func TestMarshalIntegerLengthRegression(t *testing.T) { + tests := []struct { + name string + input interface{} + expected []byte + }{ + { + name: "range_4096_131071_value_5000", + input: intMarshalRegressionLargeRange4096To131071{Value: 5000}, + expected: []byte{0x40, 0x03, 0x88}, + }, + { + name: "range_0_100000_value_65535", + input: intMarshalRegressionLargeRange0To100000{Value: 65535}, + expected: []byte{0x40, 0xFF, 0xFF}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + encoded, err := Marshal(tc.input) + assert.NoError(t, err) + assert.Equal(t, tc.expected, encoded) + + out := reflect.New(reflect.TypeOf(tc.input)) + err = Unmarshal(encoded, out.Interface()) + assert.NoError(t, err) + assert.Equal(t, tc.input, out.Elem().Interface()) + }) + } +} + // TEST ENUMERATED // value is unconstraint diff --git a/marshal.go b/marshal.go index 898d01a..e9c1d34 100644 --- a/marshal.go +++ b/marshal.go @@ -453,7 +453,7 @@ func (pd *perRawBitData) appendInteger(value int64, extensive bool, lowerBoundPt unsignedValueRange := uint64(valueRange - 1) for byteLen = 1; byteLen <= 127; byteLen++ { unsignedValueRange >>= 8 - if unsignedValueRange <= 1 { + if unsignedValueRange == 0 { break } }