Skip to content

Commit 6fb6e0f

Browse files
committed
FIX: disallowed loop variable context access
resolves: Oldes/Rebol-issues#2531
1 parent a27822c commit 6fb6e0f

File tree

4 files changed

+15
-1
lines changed

4 files changed

+15
-1
lines changed

src/core/n-data.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
** REBOL [R3] Language Interpreter and Run-time Environment
44
**
55
** Copyright 2012 REBOL Technologies
6-
** Copyright 2012-2022 Rebol Open Source Developers
6+
** Copyright 2012-2023 Rebol Open Source Developers
77
** REBOL is a trademark of REBOL Technologies
88
**
99
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -352,6 +352,9 @@ static int Check_Char_Range(REBVAL *val, REBINT limit)
352352
// case like: ` f: func[a][context? 'a] f 1 `
353353
*D_RET = frame[3];
354354
} else {
355+
if (IS_INT_SERIES(VAL_WORD_FRAME(word)))
356+
// in case like: ` foreach x [1] [context? 'x] `
357+
return R_NONE;
355358
SET_OBJECT(D_RET, VAL_WORD_FRAME(word));
356359
}
357360
return R_RET;

src/core/n-loop.c

+4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ enum loop_each_mode {
6464
SET_SELFLESS(frame);
6565
SERIES_TAIL(frame) = len+1;
6666
SERIES_TAIL(FRM_WORD_SERIES(frame)) = len+1;
67+
68+
// Mark the frame as internal series so it is not accessible!
69+
// See: https://github.com/Oldes/Rebol-issues/issues/2531
70+
INT_SERIES(frame);
6771

6872
// Setup for loop:
6973
word = FRM_WORD(frame, 1); // skip SELF

src/include/sys-value.h

+3
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ enum {
476476
SER_BARE = 1<<5, // Series has no links to GC-able values
477477
SER_PROT = 1<<6, // Series is protected from modification
478478
SER_MON = 1<<7, // Monitoring
479+
SER_INT = 1<<8, // Series data is internal (loop frames) and should not be accessed by users
479480
};
480481

481482
#define SERIES_SET_FLAG(s, f) (SERIES_FLAGS(s) |= ((f) << 8))
@@ -489,6 +490,8 @@ enum {
489490
#define KEEP_SERIES(s,l) do {SERIES_SET_FLAG(s, SER_KEEP); LABEL_SERIES(s,l);} while(0)
490491
#define EXT_SERIES(s) SERIES_SET_FLAG(s, SER_EXT)
491492
#define IS_EXT_SERIES(s) SERIES_GET_FLAG(s, SER_EXT)
493+
#define INT_SERIES(s) SERIES_SET_FLAG(s, SER_INT)
494+
#define IS_INT_SERIES(s) SERIES_GET_FLAG(s, SER_INT)
492495
#define LOCK_SERIES(s) SERIES_SET_FLAG(s, SER_LOCK)
493496
#define IS_LOCK_SERIES(s) SERIES_GET_FLAG(s, SER_LOCK)
494497
#define BARE_SERIES(s) SERIES_SET_FLAG(s, SER_BARE)

src/tests/units/object-test.r3

+4
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ Rebol [
380380
--assert object? o: context? use [x] ['x]
381381
--assert object? append o 'self
382382

383+
--test-- "issue-2531"
384+
;@@ https://github.com/Oldes/Rebol-issues/issues/2531
385+
--assert none? foreach x [1] [context? 'x]
386+
383387
===end-group===
384388

385389
===start-group=== "PROTECT object!"

0 commit comments

Comments
 (0)