fix(store): prevent delete out of bounds in spliceDynamicData
#3521
+20
−3
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.
In
spliceDynamicData
, we’re checking thatstart
is within the bounds of the previous field length but aren’t consideringdeleteCount
in that check. There is another check that checks thatstart + deleteCount
lines up with the previous length of the field if the total length of the field changed, but this only applies if the length changed. That means if the length of the data to insert is the same asdeleteCount
, it is possible to “insert data after the length of the field” (ie by settingstart
to the end of the field). I put “insert data after the length of the field” in quotes, since the length of the field is not actually changed, which means when retrieving the whole field onchain the data appended at the end would not be included, similar to how items that are pop’ed from a dynamic field are not actually cleared from storage but just the field length is reduced.But means indexers/clients need to be aware of this nuance and use
encodedLengths
as source of truth (like we do onchain).We can remove this edge case by changing the check to
if(startWithinField > previousFieldLength - deleteCount)
.When using our table libraries this does not happen since they don't call
spliceDynamicData
with an invalidstart
value, but it’s possible to trigger this by callingworld.spliceDynamicData
manually.