diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-12 13:13:02 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-12 13:13:02 -0300 |
commit | fc6203ee4308173283f9ad9de6694d47f0908c4d (patch) | |
tree | 5ff648955f22bc66413857627318f2c36b890489 | |
parent | b2dd246b7a27445ba2daca17f80f6b95d6b685b1 (diff) | |
download | lua-fc6203ee4308173283f9ad9de6694d47f0908c4d.tar.gz lua-fc6203ee4308173283f9ad9de6694d47f0908c4d.tar.bz2 lua-fc6203ee4308173283f9ad9de6694d47f0908c4d.zip |
BUG: 'string.format' may get buffer when there are missing arguments
-rw-r--r-- | lstrlib.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstrlib.c,v 1.149 2010/04/09 16:14:46 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.150 2010/04/12 12:00:50 roberto Exp roberto $ |
3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -709,11 +709,18 @@ static int str_gsub (lua_State *L) { | |||
709 | /* }====================================================== */ | 709 | /* }====================================================== */ |
710 | 710 | ||
711 | 711 | ||
712 | |||
712 | /* | 713 | /* |
713 | ** length modifier for integer conversions ** in 'string.format' and | 714 | ** {====================================================== |
714 | ** integer type corresponding to the previous length | 715 | ** STRING FORMAT |
716 | ** ======================================================= | ||
715 | */ | 717 | */ |
716 | 718 | ||
719 | /* | ||
720 | ** LUA_INTFRMLEN is the length modifier for integer conversions in | ||
721 | ** 'string.format'; LUA_INTFRM_T is the integer type corresponding to | ||
722 | ** the previous length | ||
723 | */ | ||
717 | #if defined(LUA_USELONGLONG) | 724 | #if defined(LUA_USELONGLONG) |
718 | 725 | ||
719 | #define LUA_INTFRMLEN "ll" | 726 | #define LUA_INTFRMLEN "ll" |
@@ -797,6 +804,7 @@ static void addintlen (char *form) { | |||
797 | 804 | ||
798 | 805 | ||
799 | static int str_format (lua_State *L) { | 806 | static int str_format (lua_State *L) { |
807 | int top = lua_gettop(L); | ||
800 | int arg = 1; | 808 | int arg = 1; |
801 | size_t sfl; | 809 | size_t sfl; |
802 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); | 810 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); |
@@ -812,7 +820,8 @@ static int str_format (lua_State *L) { | |||
812 | char form[MAX_FORMAT]; /* to store the format (`%...') */ | 820 | char form[MAX_FORMAT]; /* to store the format (`%...') */ |
813 | char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ | 821 | char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ |
814 | int nb = 0; /* number of bytes in added item */ | 822 | int nb = 0; /* number of bytes in added item */ |
815 | arg++; | 823 | if (++arg > top) |
824 | luaL_argerror(L, arg, "no value"); | ||
816 | strfrmt = scanformat(L, strfrmt, form); | 825 | strfrmt = scanformat(L, strfrmt, form); |
817 | switch (*strfrmt++) { | 826 | switch (*strfrmt++) { |
818 | case 'c': { | 827 | case 'c': { |
@@ -864,6 +873,8 @@ static int str_format (lua_State *L) { | |||
864 | return 1; | 873 | return 1; |
865 | } | 874 | } |
866 | 875 | ||
876 | /* }====================================================== */ | ||
877 | |||
867 | 878 | ||
868 | static const luaL_Reg strlib[] = { | 879 | static const luaL_Reg strlib[] = { |
869 | {"byte", str_byte}, | 880 | {"byte", str_byte}, |