Visitar URL original
Bug (kind of) in 'isinstack' · lua/lua@e0260eb · GitHub
Skip to content

Commit e0260eb

Browse files
committed
Bug (kind of) in 'isinstack'
The function 'isinstack' tried to work around the undefined behavior of subtracting two pointers that do not point to the same object, but the compiler killed to trick. (It optimizes out the safety check, because in a correct execution it will be always true.)
1 parent 5205f07 commit e0260eb

2 files changed

Lines changed: 17 additions & 6 deletions

File tree

‎ldebug.c‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -638,14 +638,18 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
638638

639639

640640
/*
641-
** The subtraction of two potentially unrelated pointers is
642-
** not ISO C, but it should not crash a program; the subsequent
643-
** checks are ISO C and ensure a correct result.
641+
** Check whether pointer 'o' points to some value in the stack
642+
** frame of the current function. Because 'o' may not point to a
643+
** value in this stack, we cannot compare it with the region
644+
** boundaries (undefined behaviour in ISO C).
644645
*/
645646
static int isinstack (CallInfo *ci, const TValue *o) {
646-
StkId base = ci->func + 1;
647-
ptrdiff_t i = cast(StkId, o) - base;
648-
return (0 <= i && i < (ci->top - base) && s2v(base + i) == o);
647+
StkId pos;
648+
for (pos = ci->func + 1; pos < ci->top; pos++) {
649+
if (o == s2v(pos))
650+
return 1;
651+
}
652+
return 0; /* not found */
649653
}
650654

651655

‎testes/errors.lua‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,13 @@ checkmessage("a = 24 // 0", "divide by zero")
191191
checkmessage("a = 1 % 0", "'n%0'")
192192

193193

194+
-- type error for an object which is neither in an upvalue nor a register.
195+
-- The following code will try to index the value 10 that is stored in
196+
-- the metatable, without moving it to a register.
197+
checkmessage("local a = setmetatable({}, {__index = 10}).x",
198+
"attempt to index a number value")
199+
200+
194201
-- numeric for loops
195202
checkmessage("for i = {}, 10 do end", "table")
196203
checkmessage("for i = io.stdin, 10 do end", "FILE")

0 commit comments

Comments
 (0)