Skip to content

Commit b7c02e9

Browse files
authored
fixes #25240; forbids modifying a Deque changed while iterating over it (#25242)
fixes #25240 > Deque items behavior is not the same on 2.0.16 and 2.2.0 The behavior seems to be caused by the temp introduced for the parameter `deq.len`, which prevents it from being evaluated multiple times
1 parent 544c26c commit b7c02e9

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

lib/pure/collections/deques.nim

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,10 @@ iterator items*[T](deq: Deque[T]): lent T =
200200
let a = [10, 20, 30, 40, 50].toDeque
201201
assert toSeq(a.items) == @[10, 20, 30, 40, 50]
202202

203-
for c in 0 ..< deq.len:
203+
let L = len(deq)
204+
for c in 0 ..< L:
204205
yield deq.data[(deq.head + c.uint) and deq.mask]
206+
assert(len(deq) == L, "the length of the Deque changed while iterating over it")
205207

206208
iterator mitems*[T](deq: var Deque[T]): var T =
207209
## Yields every element of `deq`, which can be modified.
@@ -215,8 +217,10 @@ iterator mitems*[T](deq: var Deque[T]): var T =
215217
x = 5 * x - 1
216218
assert $a == "[49, 99, 149, 199, 249]"
217219

218-
for c in 0 ..< deq.len:
220+
let L = len(deq)
221+
for c in 0 ..< L:
219222
yield deq.data[(deq.head + c.uint) and deq.mask]
223+
assert(len(deq) == L, "the length of the Deque changed while iterating over it")
220224

221225
iterator pairs*[T](deq: Deque[T]): tuple[key: int, val: T] =
222226
## Yields every `(position, value)`-pair of `deq`.
@@ -226,8 +230,10 @@ iterator pairs*[T](deq: Deque[T]): tuple[key: int, val: T] =
226230
let a = [10, 20, 30].toDeque
227231
assert toSeq(a.pairs) == @[(0, 10), (1, 20), (2, 30)]
228232

229-
for c in 0 ..< deq.len:
233+
let L = len(deq)
234+
for c in 0 ..< L:
230235
yield (c, deq.data[(deq.head + c.uint) and deq.mask])
236+
assert(len(deq) == L, "the length of the Deque changed while iterating over it")
231237

232238
proc contains*[T](deq: Deque[T], item: T): bool {.inline.} =
233239
## Returns true if `item` is in `deq` or false if not found.

0 commit comments

Comments
 (0)