lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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---