Преглед на файлове

BUG (when compiled with long double): buffer overflow when formatting
string.format("%.99f", 1e4930)

Roberto Ierusalimschy преди 10 години
родител
ревизия
3509914916
променени са 1 файла, в които са добавени 11 реда и са изтрити 5 реда
  1. 11 5
      lstrlib.c

+ 11 - 5
lstrlib.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstrlib.c,v 1.220 2014/12/11 13:40:40 roberto Exp roberto $
+** $Id: lstrlib.c,v 1.221 2014/12/11 14:03:07 roberto Exp roberto $
 ** Standard library for string operations and pattern-matching
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -797,8 +797,15 @@ static int str_gsub (lua_State *L) {
 ** =======================================================
 ** =======================================================
 */
 */
 
 
-/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
-#define MAX_ITEM	512
+/*
+** Maximum size of each formatted item. This maximum size is produced
+** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') +
+** number of decimal digits to represent minfloat (which is ~308 for
+** a double and ~4932 for long double).
+*/
+#define MAX_ITEM  \
+  (sizeof(lua_Number) <= 4 ? 150 : sizeof(lua_Number) <= 8 ? 450 : 5050)
+
 
 
 /* valid flags in a format specification */
 /* valid flags in a format specification */
 #define FLAGS	"-+ #0"
 #define FLAGS	"-+ #0"
@@ -921,13 +928,12 @@ static int str_format (lua_State *L) {
             /* no precision and string is too long to be formatted;
             /* no precision and string is too long to be formatted;
                keep original string */
                keep original string */
             luaL_addvalue(&b);
             luaL_addvalue(&b);
-            break;
           }
           }
           else {
           else {
             nb = sprintf(buff, form, s);
             nb = sprintf(buff, form, s);
             lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
             lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
-            break;
           }
           }
+          break;
         }
         }
         default: {  /* also treat cases 'pnLlh' */
         default: {  /* also treat cases 'pnLlh' */
           return luaL_error(L, "invalid option '%%%c' to 'format'",
           return luaL_error(L, "invalid option '%%%c' to 'format'",