aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-04 17:29:51 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-04 17:29:51 -0200
commit1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9 (patch)
treee486eb5a38c884294355183488c948e5a0f5d8c5
parent76179a1014430f42148822ac2db23a9491817a0b (diff)
downloadlua-1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9.tar.gz
lua-1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9.tar.bz2
lua-1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9.zip
format "%s" may break limit of "sprintf" on some machines.
-rw-r--r--bugs3
-rw-r--r--lstrlib.c23
2 files changed, 17 insertions, 9 deletions
diff --git a/bugs b/bugs
index 4646057f..199c881f 100644
--- a/bugs
+++ b/bugs
@@ -67,3 +67,6 @@ Wed Feb 3 14:40:21 EDT 1999
67>> getlocal cannot return the local itself, since lua_isstring and 67>> getlocal cannot return the local itself, since lua_isstring and
68lua_isnumber can modify it. 68lua_isnumber can modify it.
69 69
70** lstrlib.c
71Thu Feb 4 17:08:50 EDT 1999
72>> format "%s" may break limit of "sprintf" on some machines.
diff --git a/lstrlib.c b/lstrlib.c
index 719b7823..b50d165b 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.22 1998/12/28 13:44:54 roberto Exp $ 2** $Id: lstrlib.c,v 1.24 1999/02/04 19:10:30 roberto Exp roberto $
3** Standard library for strings and pattern-matching 3** Standard library for strings and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -462,8 +462,6 @@ static void luaI_addquoted (int arg) {
462static void str_format (void) { 462static void str_format (void) {
463 int arg = 1; 463 int arg = 1;
464 char *strfrmt = luaL_check_string(arg); 464 char *strfrmt = luaL_check_string(arg);
465 struct Capture cap;
466 cap.src_end = strfrmt+strlen(strfrmt)+1;
467 luaL_resetbuffer(); 465 luaL_resetbuffer();
468 while (*strfrmt) { 466 while (*strfrmt) {
469 if (*strfrmt != '%') 467 if (*strfrmt != '%')
@@ -471,33 +469,40 @@ static void str_format (void) {
471 else if (*++strfrmt == '%') 469 else if (*++strfrmt == '%')
472 luaL_addchar(*strfrmt++); /* %% */ 470 luaL_addchar(*strfrmt++); /* %% */
473 else { /* format item */ 471 else { /* format item */
472 struct Capture cap;
474 char form[MAX_FORMAT]; /* store the format ('%...') */ 473 char form[MAX_FORMAT]; /* store the format ('%...') */
475 char *buff; 474 char *buff;
476 char *initf = strfrmt; 475 char *initf = strfrmt;
477 form[0] = '%'; 476 form[0] = '%';
478 cap.level = 0;
479 if (isdigit((unsigned char)initf[0]) && initf[1] == '$') { 477 if (isdigit((unsigned char)initf[0]) && initf[1] == '$') {
480 arg = initf[0] - '0'; 478 arg = initf[0] - '0';
481 initf += 2; /* skip the 'n$' */ 479 initf += 2; /* skip the 'n$' */
482 } 480 }
483 arg++; 481 arg++;
482 cap.src_end = strfrmt+strlen(strfrmt)+1;
483 cap.level = 0;
484 strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); 484 strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
485 if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */ 485 if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
486 strfrmt-initf > MAX_FORMAT-2) 486 strfrmt-initf > MAX_FORMAT-2)
487 lua_error("invalid format (width or precision too long)"); 487 lua_error("invalid format (width or precision too long)");
488 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ 488 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
489 form[strfrmt-initf+2] = 0; 489 form[strfrmt-initf+2] = 0;
490 /* to store the formatted value 490 buff = luaL_openspace(450); /* 450 > size of format('%99.99f', -1e308) */
491 (450 > size of format('%99.99f', -1e308) */
492 buff = luaL_openspace(450);
493 switch (*strfrmt++) { 491 switch (*strfrmt++) {
494 case 'q': 492 case 'q':
495 luaI_addquoted(arg); 493 luaI_addquoted(arg);
496 continue; 494 continue;
497 case 's': { 495 case 's': {
498 char *s = luaL_check_string(arg); 496 char *s = luaL_check_string(arg);
499 buff = luaL_openspace(strlen(s)); 497 int l = strlen(s);
500 sprintf(buff, form, s); 498 buff = luaL_openspace(l+1);
499 if (cap.capture[1].len == 0 && l >= 100) {
500 /* no precision and string is too big to be formated;
501 keep original string */
502 strcpy(buff, s);
503 }
504 else
505 sprintf(buff, form, s);
501 break; 506 break;
502 } 507 }
503 case 'c': case 'd': case 'i': 508 case 'c': case 'd': case 'i':