@@ -3376,28 +3376,34 @@ func TestBitMapValidationFromDeserialization(t *testing.T) {
33763376 err error
33773377 }{
33783378 {
3379- name : "Corrupts Run Length vs Num Runs " ,
3379+ name : "Last Run Extends Past Container End " ,
33803380 loader : func (bm * Bitmap ) {
33813381 bm .AddRange (0 , 2 )
33823382 bm .AddRange (4 , 6 )
33833383 bm .AddRange (8 , 100 )
3384+ bm .RunOptimize () // one run container
33843385 },
33853386 corruptor : func (s []byte ) {
3386- // 21 is the length of the run of the last run/range
3387- // Shortening causes interval sum to be to short
3388- s [21 ] = 1
3387+ // 21-22 is the length of the last run, which starts at 8:
3388+ // 65535 makes it end past 65535
3389+ s [21 ] = 0xFF
3390+ s [22 ] = 0xFF
33893391 },
3390- err : ErrRunIntervalSize ,
3392+ err : ErrRunIntervalOutOfRange ,
33913393 },
33923394 {
3393- name : "Corrupts Run Length " ,
3395+ name : "Run Extends Past Container End " ,
33943396 loader : func (bm * Bitmap ) {
33953397 bm .AddRange (100 , 110 )
3398+ bm .RunOptimize () // one run container
33963399 },
33973400 corruptor : func (s []byte ) {
3398- s [13 ] = 0
3401+ // 13-14 is the length of the run, which starts at 100:
3402+ // 65535 makes it end past 65535
3403+ s [13 ] = 0xFF
3404+ s [14 ] = 0xFF
33993405 },
3400- err : ErrRunIntervalSize ,
3406+ err : ErrRunIntervalOutOfRange ,
34013407 },
34023408 {
34033409 name : "Creates Interval Overlap" ,
@@ -3467,7 +3473,7 @@ func TestBitMapValidationFromDeserialization(t *testing.T) {
34673473 if tt .err == nil {
34683474 assert .NoError (t , validateErr , "expected validation to succeed when tt.err is nil" )
34693475 } else {
3470- assert .Error (t , validateErr , "expected validation to fail when tt.err is not nil" )
3476+ assert .ErrorIs (t , validateErr , tt .err )
34713477 }
34723478
34733479 corruptedDeserializedBitMap = NewBitmap ()
@@ -4184,3 +4190,24 @@ func TestBitmapOrBulkMergeCopyOnWriteTailOwnership(t *testing.T) {
41844190 t .Fatalf ("source became invalid after tail mutations: %v" , err )
41854191 }
41864192}
4193+
4194+ func TestValidateAcceptsRunContainersThatAreNotTheSmallestEncoding (t * testing.T ) {
4195+ // AddOffset splits the run: the first container holds a run of two values,
4196+ // which takes more bytes than an array container would
4197+ bm := NewBitmap ()
4198+ bm .AddRange (0 , 10 )
4199+ bm .RunOptimize ()
4200+ shifted := AddOffset64 (bm , 65534 )
4201+ expected := NewBitmap ()
4202+ expected .AddRange (65534 , 65544 )
4203+ assert .True (t , expected .Equals (shifted ))
4204+ assert .NoError (t , shifted .Validate ())
4205+
4206+ serialized , err := shifted .ToBytes ()
4207+ assert .NoError (t , err )
4208+ deserialized := NewBitmap ()
4209+ _ , err = deserialized .ReadFrom (bytes .NewReader (serialized ))
4210+ assert .NoError (t , err )
4211+ assert .NoError (t , deserialized .Validate ())
4212+ assert .True (t , expected .Equals (deserialized ))
4213+ }
0 commit comments