Skip to content

Commit 6f25137

Browse files
committed
Check overwritten value in parentUpdater callback
Currently, in parentUpdater callback, parent array/map resets same child value. Child value ID should match overwritten SlabIDStorable or Slab.SlabID(). This commit adds check to make sure same child value is being reset.
1 parent d6f3daa commit 6f25137

File tree

3 files changed

+81
-5
lines changed

3 files changed

+81
-5
lines changed

array.go

+33-2
Original file line numberDiff line numberDiff line change
@@ -2725,8 +2725,39 @@ func (a *Array) setCallbackWithChild(i uint64, child Value) {
27252725
return err
27262726
}
27272727

2728-
if existingValueStorable == nil {
2729-
return NewFatalError(fmt.Errorf("failed to reset child value in parent updater callback because previous value is nil"))
2728+
// Verify overwritten storable has identical value ID.
2729+
2730+
switch x := existingValueStorable.(type) {
2731+
case SlabIDStorable:
2732+
sid := SlabID(x)
2733+
if !vid.equal(sid) {
2734+
return NewFatalError(
2735+
fmt.Errorf(
2736+
"failed to reset child value in parent updater callback: overwritten SlabIDStorable %s != value ID %s",
2737+
sid,
2738+
vid))
2739+
}
2740+
2741+
case Slab:
2742+
sid := x.SlabID()
2743+
if !vid.equal(sid) {
2744+
return NewFatalError(
2745+
fmt.Errorf(
2746+
"failed to reset child value in parent updater callback: overwritten Slab ID %s != value ID %s",
2747+
sid,
2748+
vid))
2749+
}
2750+
2751+
case nil:
2752+
return NewFatalError(
2753+
fmt.Errorf(
2754+
"failed to reset child value in parent updater callback: overwritten value is nil"))
2755+
2756+
default:
2757+
return NewFatalError(
2758+
fmt.Errorf(
2759+
"failed to reset child value in parent updater callback: overwritten value is wrong type %T",
2760+
existingValueStorable))
27302761
}
27312762

27322763
return nil

map.go

+35-3
Original file line numberDiff line numberDiff line change
@@ -4523,6 +4523,8 @@ func (m *OrderedMap) setCallbackWithChild(
45234523
return
45244524
}
45254525

4526+
vid := c.ValueID()
4527+
45264528
c.setParentUpdater(func() error {
45274529
// Set child value with parent map using same key.
45284530
// Set() calls c.Storable() which returns inlined or not-inlined child storable.
@@ -4531,10 +4533,40 @@ func (m *OrderedMap) setCallbackWithChild(
45314533
return err
45324534
}
45334535

4534-
if existingValueStorable == nil {
4535-
return NewFatalError(fmt.Errorf("failed to reset child value in parent updater callback because previous value is nil"))
4536-
}
4536+
// Verify overwritten storable has identical value ID.
4537+
4538+
switch x := existingValueStorable.(type) {
4539+
case SlabIDStorable:
4540+
sid := SlabID(x)
4541+
if !vid.equal(sid) {
4542+
return NewFatalError(
4543+
fmt.Errorf(
4544+
"failed to reset child value in parent updater callback: overwritten SlabIDStorable %s != value ID %s",
4545+
sid,
4546+
vid))
4547+
}
4548+
4549+
case Slab:
4550+
sid := x.SlabID()
4551+
if !vid.equal(sid) {
4552+
return NewFatalError(
4553+
fmt.Errorf(
4554+
"failed to reset child value in parent updater callback: overwritten Slab ID %s != value ID %s",
4555+
sid,
4556+
vid))
4557+
}
4558+
4559+
case nil:
4560+
return NewFatalError(
4561+
fmt.Errorf(
4562+
"failed to reset child value in parent updater callback: overwritten value is nil"))
45374563

4564+
default:
4565+
return NewFatalError(
4566+
fmt.Errorf(
4567+
"failed to reset child value in parent updater callback: overwritten value is wrong type %T",
4568+
existingValueStorable))
4569+
}
45384570
return nil
45394571
})
45404572
}

storage.go

+13
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ func slabIDToValueID(sid SlabID) ValueID {
4141
return id
4242
}
4343

44+
func (vid ValueID) equal(sid SlabID) bool {
45+
return bytes.Equal(vid[:8], sid.address[:]) &&
46+
bytes.Equal(vid[8:], sid.index[:])
47+
}
48+
49+
func (vid ValueID) String() string {
50+
return fmt.Sprintf(
51+
"0x%x.%d",
52+
binary.BigEndian.Uint64(vid[:8]),
53+
binary.BigEndian.Uint64(vid[8:]),
54+
)
55+
}
56+
4457
type (
4558
Address [8]byte
4659
SlabIndex [8]byte

0 commit comments

Comments
 (0)