Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rather subtle defect in path_translate #7

Open
assarbad opened this issue May 19, 2016 · 0 comments
Open

Rather subtle defect in path_translate #7

assarbad opened this issue May 19, 2016 · 0 comments

Comments

@assarbad
Copy link

This took me a while to track down.

In path_translate from path_translate.c the handling is wrong in cases where a table is passed. The lua_next function requires that the keys in the table not be changed (or new values inserted, which also means a change of keys).

However, the luaL_checkstring will just do that in cases where the key is not a string and convert it into a string.

Reference: http://stackoverflow.com/a/6142700

The error would then be invalid key to 'next' which indicates that the key of a table was changed mid-iteration:

invalid key to 'next'
stack traceback:
        [C]: in function 'builtin_translate'
        src/base/path.lua:148: in function 'translate'
        D:/premake-wds/src/actions/vstudio/vs200x_vcproj.lua:366: in function '?'
        D:/premake-wds/src/actions/vstudio/vs200x_vcproj.lua:743: in function 'callback'
        D:/premake-wds/src/base/premake.lua:32: in function 'orig_generate'
        D:/premake-wds/premake4.lua:72: in function 'generate'
        D:/premake-wds/src/actions/vstudio/_vstudio.lua:322: in function 'onproject'
        D:/premake-wds/src/base/action.lua:59: in function 'call'
        src/_premake_main.lua:155: in function <src/_premake_main.lua:53>

(it's from my fork of premake4, but the same generally applies to other premake4 flavors and possibly even premake5).

The fix is trivial. Take a copy of the key, then use luaL_checkstring on the copy and pop 2 values from the stack instead of one.

Here's the changed condition:

    if (lua_istable(L, 1)) {
        int i = 0;
        lua_newtable(L);
        lua_pushnil(L);
        while (lua_next(L, 1)) {
            const char* key;
            lua_pushvalue(L, 4); // copy the key
            key = luaL_checkstring(L, 5);
            translate(buffer, key, sep[0]);
            lua_pop(L, 2);

            lua_pushstring(L, buffer);
            lua_rawseti(L, -3, ++i);
        }
        return 1;
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant