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.
-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': |