Personage
Personage

Reputation: 484

Converting a Lua function chunk to a C string

I am working on a project that takes a Lua string and converts it into a C string – not at all difficult, of course. However, I run into trouble when attempting to convert a binary representation of a function, i.e. one produced by a call to string.dump, to a C string. I am having trouble reading the entire string.

While it is not the ultimate goal of the project, consider the following simple example where I print out the characters in a string one-by-one using a C function called chars that I have registered for use in Lua:

static void chars(char* cp) {
    char* pointer = cp;
    while (*pointer) {
        printf("%c\n", *pointer);
        ++pointer;
    }
    return;
}

static int lua_chars(lua_State* L) {
    lua_len(L, 1);
    size_t len = static_cast<size_t>(lua_tonumber(L, -1)) + 1;
    lua_pop(L, 1);
    if (len > 0) {
        char* cp = static_cast<char*>(malloc(len));
        strcat(cp, lua_tostring(L, 1));
        chars(cp);
        free(cp);
    }
    return 0;
}

Calling chars from a Lua script would look like this:

chars("Hello World!")

and would print out the characters one by one with each followed by a newline.

Now to the actual issue. Consider this example where I declare a function in Lua, dump it with string.dump, and then pass that string to the function chars to print out its characters individually:

local function foo()
    print("foo")
    return
end

local s = assert(string.dump(foo))
chars(s)

The string s in its entirety, not printed with my function chars, looks something like this:

uaS?

xV(w@=stdin@A@$@&?&?printfoo_ENV

However, chars only prints the first five bytes:

u
a
S

(Note there are supposed to be two lines of whitespace before the 'u'.)

I am almost certain that this is due to null characters within the string, which I think interferes with lua_tostring's functionality. I have come across lua_Writer for reading chunks, but I have no idea how to use/code it. How can I successfully convert the entire string on the Lua stack to a C string?

Upvotes: 2

Views: 1388

Answers (2)

Vlad
Vlad

Reputation: 5847

I am almost certain that this is due to null characters within the string

Yes, it's exactly because Lua strings can contain zeroes.

which I think interferes with lua_tostring's functionality.

And this is false. lua_tostring() works as intended. It's just strcat() you're using will only copy the data up to the nearest zero byte.

If you need to copy the string, use memcpy, passing it both the pointer to Lua string data and Lua string length (lua_len, lua_rawlen, etc).

But just for printing you don't even need to copy anything. Pass the len variable as an argument to chars(), and check that length instead of waiting for zero byte.

Upvotes: 2

gotocoffee
gotocoffee

Reputation: 199

The Problem isn't lua_tostring but strcat which copies until it finds an null characters. Same Problem with your chars function. That should work:

memcpy(cp, lua_tostring(L, 1), len);
chars(cp, len);
...
static void chars(char* cp, size_t len) {
    for (size_t i = 0; i < len; ++i, ++cp) {
        putchar(*cp);
    }
}

Upvotes: 2

Related Questions