|
|
Hi list,
I've been reviewing some of my native code for safety and noticed that I've been assuming lua_next() will not raise arbitrary errors. In the 5.3 documentation however, lua_next is listed as 'e' meaning it can.
I couldn't think of any obvious reason how it could error, since there is no metamethod to override a next iteration, and I couldn't see anything in the implementation that would trigger an __index. Am I missing something or is the documentation incorrect?
Thanks,
Tom
|
|
Hi list,
I've been reviewing some of my native code for safety and noticed that I've been assuming lua_next() will not raise arbitrary errors. In the 5.3 documentation however, lua_next is listed as 'e' meaning it can.
I couldn't think of any obvious reason how it could error, since there is no metamethod to override a next iteration, and I couldn't see anything in the implementation that would trigger an __index. Am I missing something or is the documentation incorrect?
`lua_next` may raise error when you pass a key that is not exist in the table.
|
|
`lua_next` may raise error when you pass a key that is not exist in the table.
Good point, but that would qualify it for a "v" ("the function may raise an error on purpose") rather than an "e" ("the function may raise any errors (it can run arbitrary Lua code, either directly or through metamethods)" wouldn't it?
Is there any way in which a call to lua_next() (with a valid table index and a valid key on the stack) could result in arbitrary code being run?
Thanks,
Tom
|
|
> On Mon, Apr 16, 2018 at 2:22 PM, Tom Sutcliffe < [hidden email]> wrote:
>
> > I've been reviewing some of my native code for safety and noticed that
> I've been assuming lua_next() will not raise arbitrary errors.
>
> Not only can it raise an error, it can also crash.
>
> http://lua-users.org/lists/lua-l/2017-12/msg00057.htmlPractically all functions in the Lua-C API can crash, when called with
invalid arguments. It would be expensive, and often impossible, to check
for that kind of errors. (I believe this happens with most C libraries.)
-- Roberto
|
|
> `lua_next` may raise error when you pass a key that is not exist in the table.
>
> Good point, but that would qualify it for a "v" ("the function may raise an error on purpose") rather than an "e" ("the function may raise any errors (it can run arbitrary Lua code, either directly or through metamethods)" wouldn't it?
I have to recognize that the distinction between "e" and "v" here is not
very clear. By that comment, that "it can run arbitrary Lua code, either
directly or through metamethods", you are right that this one should
have a "v".
> Is there any way in which a call to lua_next() (with a valid table index and a valid key on the stack) could result in arbitrary code being run?
No.
-- Roberto
|
|
In reply to this post by Roberto Ierusalimschy
|
|
In reply to this post by Roberto Ierusalimschy
On 16 Apr 2018, at 17:12, Roberto Ierusalimschy < [hidden email]> wrote:
>
> I have to recognize that the distinction between "e" and "v" here is not
> very clear. By that comment, that "it can run arbitrary Lua code, either
> directly or through metamethods", you are right that this one should
> have a "v".
>
>
>> Is there any way in which a call to lua_next() (with a valid table index and a valid key on the stack) could result in arbitrary code being run?
>
> No.
>
Many thanks Roberto for clarifying! Panic averted :-)
Cheers,
Tom
|
|
2018-04-16 18:49 GMT+02:00 Viacheslav Usov < [hidden email]>:
> No, not really. It is one thing if a parameter in a C function is a pointer,
> then the argument simply has to point to a valid memory location. It is
> quite another when it is a kind of a "handle", then it is rather typical for
> a function to return an error result if the argument has an invalid or
> unsuitable value. See POSIX/read(), for example. Lua's stack indices look
> more like handles than pointers to me, but that, of course, can be just me.
The C API functions themselves do no type checking. The standard
library, wriiten using only the API, does it all the time. That should
serve as a model of what user functions based on the API should do. If
lua_next(), or any other API function, causes a crash, it is a bug in
the user program.
|
|
On 2018-04-16 01:49 PM, Viacheslav Usov wrote:
> On Mon, Apr 16, 2018 at 6:04 PM, Roberto Ierusalimschy
> < [hidden email] <mailto: [hidden email]>> wrote:
>
> > Practically all functions in the Lua-C API can crash, when called
> with invalid arguments.
>
> In the referenced thread, the C-language arguments given to the
> function were not invalid. It was the content of the Lua stack that
> was problematic for that function.
As far as the Lua C API is concerned, stack values are function
arguments. How else would you pass tables to functions? They don't exist
outside the Lua state.
>
> In the "checking for safety" context, that means the stack's content
> should be validated, if it is accepted from another party.
>
> > I believe this happens with most C libraries.
>
> No, not really. It is one thing if a parameter in a C function is a
> pointer, then the argument simply has to point to a valid memory
> location. It is quite another when it is a kind of a "handle", then it
> is rather typical for a function to return an error result if the
> argument has an invalid or unsuitable value. See POSIX/read(), for
> example. Lua's stack indices look more like handles than pointers to
> me, but that, of course, can be just me.
>
> Cheers,
> V.
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.
|
|
> Compare that with the current note for lua_tointegerx(): "The Lua value
> must be an integer, or a number or string convertible to an integer (see
> §3.4.3); otherwise, lua_tointegerx returns 0", and then compare with an
> *imaginary* note for lua_next(): "The value at the given index must be a
> table; otherwise, the behavior is undefined".
As far as my English goes, "undefined" means "not defined". So, if it
is not defined, it is undefined. We some times do it, but to say that
the behavior is undefined reminds me of "This page intentionally left
blank".
-- Roberto
|
|
> 在 2018年4月18日,上午2:04,Viacheslav Usov < [hidden email]> 写道:
>
> input will result in THAT kind of UB; for example, I expected a Lua error to be raised by lua_next() when given a non-table input (why? perhaps because it had the 'e" error category?). So even though it feels like stating the obvious, it helps.
You can turn on LUA_USE_APICHECK to do more checks on the C API .
|
|
In reply to this post by Roberto Ierusalimschy
On Wed, 18 Apr 2018, 01:34 Roberto Ierusalimschy, < [hidden email]> wrote: > Compare that with the current note for lua_tointegerx(): "The Lua value
> must be an integer, or a number or string convertible to an integer (see
> §3.4.3); otherwise, lua_tointegerx returns 0", and then compare with an
> *imaginary* note for lua_next(): "The value at the given index must be a
> table; otherwise, the behavior is undefined".
As far as my English goes, "undefined" means "not defined". So, if it
is not defined, it is undefined. We some times do it, but to say that
the behavior is undefined reminds me of "This page intentionally left
blank".
-- Roberto
I need to put undefined behaviour into my sequences.
;-)
Vaughan
|
|
2018-04-17 20:04 GMT+02:00 Viacheslav Usov < [hidden email]>: > When we read a spec that does not say that, we do not always > understand that some combinations of input will result in THAT kind of UB; > for example, I expected a Lua error to be raised by lua_next() when given a > non-table input (why? perhaps because it had the 'e" error category?). So > even though it feels like stating the obvious, it helps. How about this: put the third paragraph of "4 – The Application Program Interface" in technicolor? As in most C libraries, the Lua API functions do not check their arguments for validity or consistency.However, you can change this behavior by compiling Lua with the macro LUA_USE_APICHECK defined.
|
|