rlp: finalize listIterator on parse error to prevent non-advancing loops (#33245)

The list iterator previously returned true on parse errors without
advancing the input, which could lead to non-advancing infinite loops
for callers that do not check Err() inside the loop; to make iteration
safe while preserving error visibility, Next() now marks the iterator as
finished when readKind fails, returning true for the error step so
existing users that check Err() can handle it, and then false on
subsequent calls, and the function comment was updated to document this
behavior and the need to check Err().
This commit is contained in:
radik878 2025-11-26 12:30:05 +02:00 committed by Alvarez
parent 3690c9b945
commit bf41c073fd

View file

@ -37,15 +37,24 @@ func NewListIterator(data RawValue) (*listIterator, error) {
return it, nil return it, nil
} }
// Next forwards the iterator one step, returns true if it was not at end yet // Next forwards the iterator one step.
// Returns true if there is a next item or an error occurred on this step (check Err()).
// On parse error, the iterator is marked finished and subsequent calls return false.
func (it *listIterator) Next() bool { func (it *listIterator) Next() bool {
if len(it.data) == 0 { if len(it.data) == 0 {
return false return false
} }
_, t, c, err := readKind(it.data) _, t, c, err := readKind(it.data)
if err != nil {
it.next = nil
it.err = err
// Mark iteration as finished to avoid potential infinite loops on subsequent Next calls.
it.data = nil
return true
}
it.next = it.data[:t+c] it.next = it.data[:t+c]
it.data = it.data[t+c:] it.data = it.data[t+c:]
it.err = err it.err = nil
return true return true
} }