Skip to content

std: add checked accessors to StoragePackedArray - #1541

Open
Nirbhay007 wants to merge 1 commit into
argotorg:masterfrom
Nirbhay007:std/storage-packed-array-checked-accessors
Open

std: add checked accessors to StoragePackedArray#1541
Nirbhay007 wants to merge 1 commit into
argotorg:masterfrom
Nirbhay007:std/storage-packed-array-checked-accessors

Conversation

@Nirbhay007

Copy link
Copy Markdown

get/set on StoragePackedArray are deliberately unbounded: indices map arithmetically onto packed slot words, so an index past the caller's modeled domain silently spills into the next storage region instead of failing. A 16-cell board backed by StoragePackedArray<4> happily accepts set(16, v) and writes a lane into bits 64-67 of the second slot word — the footgun reported in #1538.

Add get_checked/set_checked which take a const-generic modeled length and revert with Solidity's standard Panic(uint256) payload (code 0x32, IndexOutOfBounds) when the index is out of domain — the same signal the compiler emits for failed fixed-array bounds checks.

Note: #1538's headline claim (fixed-array ADJACENCY[16] reading a default instead of trapping) does not reproduce: bounds-checked array indexing with an empty revert has been in place well before v26.2.0 (see checked_index_value in codegen). The silent-write behavior in that report comes from StorageMap/StoragePackedArray default-and-spill semantics, i.e. a caller-side missing guard, which these accessors now let callers express.

get/set on StoragePackedArray are deliberately unbounded: indices map
arithmetically onto packed slot words, so an index past the caller's
modeled domain silently spills into the next storage region instead of
failing. A 16-cell board backed by StoragePackedArray<4> happily accepts
set(16, v) and writes a lane into bits 64-67 of the second slot word —
the footgun reported in argotorg#1538.

Add get_checked/set_checked which take a const-generic modeled length
and revert with Solidity's standard Panic(uint256) payload (code 0x32,
IndexOutOfBounds) when the index is out of domain — the same signal the
compiler emits for failed fixed-array bounds checks.

Note: argotorg#1538's headline claim (fixed-array ADJACENCY[16] reading a
default instead of trapping) does not reproduce: bounds-checked array
indexing with an empty revert has been in place well before v26.2.0
(see checked_index_value in codegen). The silent-write behavior in that
report comes from StorageMap/StoragePackedArray default-and-spill
semantics, i.e. a caller-side missing guard, which these accessors now
let callers express.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1748cc9523

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +15 to +17
/// Revert with Solidity's standard `Panic(uint256)` payload carrying code
/// `0x32` (`IndexOutOfBounds`) — the same encoding the compiler emits for a
/// failed fixed-array bounds check, so callers observe one uniform signal.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Correct the claimed native-array panic parity

For callers that inspect revert data, these accessors do not currently produce the uniform signal claimed here: native fixed-array indexing still calls emit_empty_revert for dynamic indices and emit_unconditional_empty_revert for constant indices in crates/codegen/src/sonatina/lower_runtime.rs:4507-4521, whereas this helper returns a 36-byte Panic(0x32) payload. Either align the compiler's array bounds lowering with this payload or stop documenting the behaviors as equivalent, since error-handling code can distinguish them.

Useful? React with 👍 / 👎.

@cburgdorf

Copy link
Copy Markdown
Collaborator

Hey! Thanks for the PR, and sorry it took me so long to review it. I'm not entirely convinced by the proposed API: callers still have to supply LEN at each call site, so different callers can specify different bounds for the same array, or accidentally use the unchecked methods.

Would it make more sense to keep StoragePackedArray as it is and introduce a wrapper such as BoundedStoragePackedArray<4, 16>? That would make the length part of the type, allowing regular get/set calls and range-based operations such as search to enforce the same bound consistently.

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants