Skip to content

Rather subtle defect in path_translate #7

@assarbad

Description

@assarbad

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions