Search code examples
luastring.formatopenwrt

Lua string.format %c versus string.char


Should Lua string.format( "%c", value ) be equivalent to string.char( value )?

It seems not when character value is zero.

string.format( "%c", 0 ):len()

returns 0

string.char( 0 ):len()

returns 1

Even stranger,

string.format( "%c%s", 0, "abc" ):len()

returns 3; where any other non-zero-modulo-256 value for %c returns 4, so string.format is not truncating the whole string at null byte like C sprintf, just collapsing %c field to empty string instead of one-byte string. Note that C sprintf writes the zero byte followed by the abc bytes in this case.

I couldn't find anything in the Lua docs describing expected behavior in this case. Most other string handling in Lua seems to treat zero byte as valid string character.

This is on Lua 5.1.4-8 on OpenWrt.

Idiosyncracy or bug?


Solution

  • I think this is a bug.

    In Lua 5.1 and LuaJIT 2.0, string.format formats one item at a time (using the sprintf provided by the host C runtime.) It then calls strlen to update the length of the output string. Since strlen stops at the null character, this character will be overwritten.

    This is documented behaviour for %s, but probably unintentional for %c

    This is fixed in Lua 5.2. I wouldn't expect any more updates to 5.1.