[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Patch for luaossl for Lua 5.4.3 (warning for users of luaL_Buffer!)
- From: Paul Ducklin <pducklin@...>
- Date: Thu, 8 Apr 2021 16:14:58 +0000
Luaossl's bindings to the OpenSSL cipher functions don't work under Lua 5.4.3. You need to make the changes shown below.
Importantly, you can't rely on lua_gettop() to tell you the stack position of the caller's last argument after you have done a luaL_buffinit(), because buffinit now pushes a temporary value on the stack when you use it. (See the 5.4.2 -> 5.4.3 diffs for lauxlib.c.)
The manual has long warned about luaL_Buffer functions using the stack: "During its normal operation, a string buffer uses a variable number of stack slots. So, while using a buffer, you cannot assume that you know where the top of the stack is."
But until 5.4.3 the code in luaossl worked in practice even though it was wrong in theory. I was perplexed and even annoyed by this bug at first until it occurred to me to RTFM, after which I was annoyed at myself, because although I clearly remembered having read the above warning before, I did not remember the actual content of what I had read ;-)
---change this code (and anything like it you have)---
static int cipher_update(lua_State *L) {
EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
luaL_buffinit(L, &B);
if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L)))
goto sslerr;
[. . . .]
static int cipher_final(lua_State *L) {
EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
size_t block;
int out;
luaL_buffinit(L, &B);
if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L)))
goto sslerr;
[. . . .]
----end---
---to look like this instead---
static int cipher_update(lua_State *L) {
EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
int lastarg = lua_gettop(L); /* buffinit changes stack top */
luaL_buffinit(L, &B);
if (!cipher_update_(L, ctx, &B, 2, lastarg))
goto sslerr;
[. . . .]
static int cipher_final(lua_State *L) {
EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
int lastarg = lua_gettop(L); /* buffinit changes stack top */
size_t block;
int out;
luaL_buffinit(L, &B);
if (!cipher_update_(L, ctx, &B, 2, lastarg))
goto sslerr;
[. . . .]
---end---