diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2007-10-29 13:51:10 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2007-10-29 13:51:10 -0200 |
| commit | c06cc609466d4527848bbf87268ec714942d554a (patch) | |
| tree | 34fa2d66dfaf077ab194a9b1c997a5deeb1910e9 | |
| parent | 2fa476655fb1a733bcf8c408f14103bd7abed1b8 (diff) | |
| download | lua-c06cc609466d4527848bbf87268ec714942d554a.tar.gz lua-c06cc609466d4527848bbf87268ec714942d554a.tar.bz2 lua-c06cc609466d4527848bbf87268ec714942d554a.zip | |
BUG: 'gsub' may go wild when wrongly called without its third
> argument and with a large subject.
| -rw-r--r-- | bugs | 31 | ||||
| -rw-r--r-- | lstrlib.c | 21 |
2 files changed, 41 insertions, 11 deletions
| @@ -1539,6 +1539,37 @@ lua.c: | |||
| 1539 | } | 1539 | } |
| 1540 | 1540 | ||
| 1541 | Bug{ | 1541 | Bug{ |
| 1542 | what = [['gsub' may go wild when wrongly called without its third | ||
| 1543 | argument and with a large subject]], | ||
| 1544 | report = [[Florian Berger, on 10/2007]], | ||
| 1545 | since = [[5.1]], | ||
| 1546 | example = [[ | ||
| 1547 | x = string.rep('a', 10000) .. string.rep('b', 10000) | ||
| 1548 | print(#string.gsub(x, 'b')) | ||
| 1549 | ]], | ||
| 1550 | patch = [[ | ||
| 1551 | lstrlib.c: | ||
| 1552 | @@ -631,6 +631,2 @@ | ||
| 1553 | } | ||
| 1554 | - default: { | ||
| 1555 | - luaL_argerror(L, 3, "string/function/table expected"); | ||
| 1556 | - return; | ||
| 1557 | - } | ||
| 1558 | } | ||
| 1559 | @@ -650,2 +646,3 @@ | ||
| 1560 | const char *p = luaL_checkstring(L, 2); | ||
| 1561 | + int tr = lua_type(L, 3); | ||
| 1562 | int max_s = luaL_optint(L, 4, srcl+1); | ||
| 1563 | @@ -655,2 +652,5 @@ | ||
| 1564 | luaL_Buffer b; | ||
| 1565 | + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || | ||
| 1566 | + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, | ||
| 1567 | + "string/function/table expected"); | ||
| 1568 | luaL_buffinit(L, &b); | ||
| 1569 | ]], | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | Bug{ | ||
| 1542 | what = [[ ]], | 1573 | what = [[ ]], |
| 1543 | report = [[ , on ]], | 1574 | report = [[ , on ]], |
| 1544 | since = [[i ]], | 1575 | since = [[i ]], |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.136 2007/02/07 17:53:08 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.137 2007/10/25 19:30:36 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 | */ |
| @@ -611,14 +611,9 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, | |||
| 611 | 611 | ||
| 612 | 612 | ||
| 613 | static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, | 613 | static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, |
| 614 | const char *e) { | 614 | const char *e, int tr) { |
| 615 | lua_State *L = ms->L; | 615 | lua_State *L = ms->L; |
| 616 | switch (lua_type(L, 3)) { | 616 | switch (tr) { |
| 617 | case LUA_TNUMBER: | ||
| 618 | case LUA_TSTRING: { | ||
| 619 | add_s(ms, b, s, e); | ||
| 620 | return; | ||
| 621 | } | ||
| 622 | case LUA_TFUNCTION: { | 617 | case LUA_TFUNCTION: { |
| 623 | int n; | 618 | int n; |
| 624 | lua_pushvalue(L, 3); | 619 | lua_pushvalue(L, 3); |
| @@ -631,8 +626,8 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, | |||
| 631 | lua_gettable(L, 3); | 626 | lua_gettable(L, 3); |
| 632 | break; | 627 | break; |
| 633 | } | 628 | } |
| 634 | default: { | 629 | default: { /* LUA_TNUMBER or LUA_TSTRING */ |
| 635 | luaL_argerror(L, 3, "string/function/table expected"); | 630 | add_s(ms, b, s, e); |
| 636 | return; | 631 | return; |
| 637 | } | 632 | } |
| 638 | } | 633 | } |
| @@ -650,11 +645,15 @@ static int str_gsub (lua_State *L) { | |||
| 650 | size_t srcl; | 645 | size_t srcl; |
| 651 | const char *src = luaL_checklstring(L, 1, &srcl); | 646 | const char *src = luaL_checklstring(L, 1, &srcl); |
| 652 | const char *p = luaL_checkstring(L, 2); | 647 | const char *p = luaL_checkstring(L, 2); |
| 648 | int tr = lua_type(L, 3); | ||
| 653 | size_t max_s = luaL_optinteger(L, 4, srcl+1); | 649 | size_t max_s = luaL_optinteger(L, 4, srcl+1); |
| 654 | int anchor = (*p == '^') ? (p++, 1) : 0; | 650 | int anchor = (*p == '^') ? (p++, 1) : 0; |
| 655 | size_t n = 0; | 651 | size_t n = 0; |
| 656 | MatchState ms; | 652 | MatchState ms; |
| 657 | luaL_Buffer b; | 653 | luaL_Buffer b; |
| 654 | luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || | ||
| 655 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, | ||
| 656 | "string/function/table expected"); | ||
| 658 | luaL_buffinit(L, &b); | 657 | luaL_buffinit(L, &b); |
| 659 | ms.L = L; | 658 | ms.L = L; |
| 660 | ms.src_init = src; | 659 | ms.src_init = src; |
| @@ -665,7 +664,7 @@ static int str_gsub (lua_State *L) { | |||
| 665 | e = match(&ms, src, p); | 664 | e = match(&ms, src, p); |
| 666 | if (e) { | 665 | if (e) { |
| 667 | n++; | 666 | n++; |
| 668 | add_value(&ms, &b, src, e); | 667 | add_value(&ms, &b, src, e, tr); |
| 669 | } | 668 | } |
| 670 | if (e && e>src) /* non empty match? */ | 669 | if (e && e>src) /* non empty match? */ |
| 671 | src = e; /* skip it */ | 670 | src = e; /* skip it */ |
