Commit eabe3b6
authored
Bump iterator state before pushing on sexp stack (#1913)
Fixes #1911.
`sexp_next_incoming()` (`src/rlang/walk.c`) receives `p_info` as a raw
pointer into the traversal stack's dyn-array buffer. The child push
could resize the stack — reallocating the buffer and dropping the old
one's protection — after which the parent's state bump and
incoming→outgoing flip were written through the stale pointer into the
dead buffer. The live (copied) entry kept its pre-bump state, so the
iterator revisited the same edge and re-traversed entire subtrees once
depth exceeded the initial stack capacity of 256. It was also a latent
use-after-free write, benign today only because no allocation happens
between the resize and the writes.
This PR moves the state bump before the push. All reads of `p_info` used
to build `child` happen earlier, so the reorder is behavior-preserving
apart from the fix.
Since this code is only compiled under `RLANG_USE_PRIVATE_ACCESSORS`
(and currently doesn't build on R >= 4.5, see the issue), there's no
regression test in the default configuration. Verified in a flagged dev
build with accessor stubs: before the fix, a depth-300 nested list
yields 690 `sexp_iterate()` callback visits with 44 nodes visited twice
as incoming; after the fix, exactly 601 visits (2n + 1) with no
duplicates, and the depth-250 control is unchanged.1 parent a18c5e7 commit eabe3b6
1 file changed
Lines changed: 15 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
209 | 209 | | |
210 | 210 | | |
211 | 211 | | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
225 | 215 | | |
226 | 216 | | |
227 | 217 | | |
| |||
239 | 229 | | |
240 | 230 | | |
241 | 231 | | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
242 | 244 | | |
243 | 245 | | |
244 | 246 | | |
| |||
0 commit comments