diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-04 17:29:51 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-04 17:29:51 -0200 |
| commit | 1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9 (patch) | |
| tree | e486eb5a38c884294355183488c948e5a0f5d8c5 | |
| parent | 76179a1014430f42148822ac2db23a9491817a0b (diff) | |
| download | lua-1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9.tar.gz lua-1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9.tar.bz2 lua-1dcf1c9cbd2ec3c51f18124b032d4d4a917b3ca9.zip | |
format "%s" may break limit of "sprintf" on some machines.
Diffstat (limited to '')
| -rw-r--r-- | bugs | 3 | ||||
| -rw-r--r-- | lstrlib.c | 23 |
2 files changed, 17 insertions, 9 deletions
| @@ -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 |
| 68 | lua_isnumber can modify it. | 68 | lua_isnumber can modify it. |
| 69 | 69 | ||
| 70 | ** lstrlib.c | ||
| 71 | Thu Feb 4 17:08:50 EDT 1999 | ||
| 72 | >> format "%s" may break limit of "sprintf" on some machines. | ||
| @@ -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) { | |||
| 462 | static void str_format (void) { | 462 | static 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': |
