diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lua/lstrlib.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/lua/lstrlib.c b/src/lua/lstrlib.c index c7242ea..47e5b27 100644 --- a/src/lua/lstrlib.c +++ b/src/lua/lstrlib.c | |||
| @@ -152,8 +152,9 @@ static int str_rep (lua_State *L) { | |||
| 152 | const char *s = luaL_checklstring(L, 1, &l); | 152 | const char *s = luaL_checklstring(L, 1, &l); |
| 153 | lua_Integer n = luaL_checkinteger(L, 2); | 153 | lua_Integer n = luaL_checkinteger(L, 2); |
| 154 | const char *sep = luaL_optlstring(L, 3, "", &lsep); | 154 | const char *sep = luaL_optlstring(L, 3, "", &lsep); |
| 155 | if (n <= 0) lua_pushliteral(L, ""); | 155 | if (n <= 0) |
| 156 | else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ | 156 | lua_pushliteral(L, ""); |
| 157 | else if (l_unlikely(l + lsep < l || l + lsep > MAXSIZE / n)) | ||
| 157 | return luaL_error(L, "resulting string too large"); | 158 | return luaL_error(L, "resulting string too large"); |
| 158 | else { | 159 | else { |
| 159 | size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; | 160 | size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; |
| @@ -181,7 +182,7 @@ static int str_byte (lua_State *L) { | |||
| 181 | size_t pose = getendpos(L, 3, pi, l); | 182 | size_t pose = getendpos(L, 3, pi, l); |
| 182 | int n, i; | 183 | int n, i; |
| 183 | if (posi > pose) return 0; /* empty interval; return no values */ | 184 | if (posi > pose) return 0; /* empty interval; return no values */ |
| 184 | if (pose - posi >= (size_t)INT_MAX) /* arithmetic overflow? */ | 185 | if (l_unlikely(pose - posi >= (size_t)INT_MAX)) /* arithmetic overflow? */ |
| 185 | return luaL_error(L, "string slice too long"); | 186 | return luaL_error(L, "string slice too long"); |
| 186 | n = (int)(pose - posi) + 1; | 187 | n = (int)(pose - posi) + 1; |
| 187 | luaL_checkstack(L, n, "string slice too long"); | 188 | luaL_checkstack(L, n, "string slice too long"); |
| @@ -235,7 +236,7 @@ static int str_dump (lua_State *L) { | |||
| 235 | luaL_checktype(L, 1, LUA_TFUNCTION); | 236 | luaL_checktype(L, 1, LUA_TFUNCTION); |
| 236 | lua_settop(L, 1); /* ensure function is on the top of the stack */ | 237 | lua_settop(L, 1); /* ensure function is on the top of the stack */ |
| 237 | state.init = 0; | 238 | state.init = 0; |
| 238 | if (lua_dump(L, writer, &state, strip) != 0) | 239 | if (l_unlikely(lua_dump(L, writer, &state, strip) != 0)) |
| 239 | return luaL_error(L, "unable to dump given function"); | 240 | return luaL_error(L, "unable to dump given function"); |
| 240 | luaL_pushresult(&state.B); | 241 | luaL_pushresult(&state.B); |
| 241 | return 1; | 242 | return 1; |
| @@ -275,7 +276,8 @@ static int tonum (lua_State *L, int arg) { | |||
| 275 | 276 | ||
| 276 | static void trymt (lua_State *L, const char *mtname) { | 277 | static void trymt (lua_State *L, const char *mtname) { |
| 277 | lua_settop(L, 2); /* back to the original arguments */ | 278 | lua_settop(L, 2); /* back to the original arguments */ |
| 278 | if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname)) | 279 | if (l_unlikely(lua_type(L, 2) == LUA_TSTRING || |
| 280 | !luaL_getmetafield(L, 2, mtname))) | ||
| 279 | luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, | 281 | luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, |
| 280 | luaL_typename(L, -2), luaL_typename(L, -1)); | 282 | luaL_typename(L, -2), luaL_typename(L, -1)); |
| 281 | lua_insert(L, -3); /* put metamethod before arguments */ | 283 | lua_insert(L, -3); /* put metamethod before arguments */ |
| @@ -383,7 +385,8 @@ static const char *match (MatchState *ms, const char *s, const char *p); | |||
| 383 | 385 | ||
| 384 | static int check_capture (MatchState *ms, int l) { | 386 | static int check_capture (MatchState *ms, int l) { |
| 385 | l -= '1'; | 387 | l -= '1'; |
| 386 | if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) | 388 | if (l_unlikely(l < 0 || l >= ms->level || |
| 389 | ms->capture[l].len == CAP_UNFINISHED)) | ||
| 387 | return luaL_error(ms->L, "invalid capture index %%%d", l + 1); | 390 | return luaL_error(ms->L, "invalid capture index %%%d", l + 1); |
| 388 | return l; | 391 | return l; |
| 389 | } | 392 | } |
| @@ -400,14 +403,14 @@ static int capture_to_close (MatchState *ms) { | |||
| 400 | static const char *classend (MatchState *ms, const char *p) { | 403 | static const char *classend (MatchState *ms, const char *p) { |
| 401 | switch (*p++) { | 404 | switch (*p++) { |
| 402 | case L_ESC: { | 405 | case L_ESC: { |
| 403 | if (p == ms->p_end) | 406 | if (l_unlikely(p == ms->p_end)) |
| 404 | luaL_error(ms->L, "malformed pattern (ends with '%%')"); | 407 | luaL_error(ms->L, "malformed pattern (ends with '%%')"); |
| 405 | return p+1; | 408 | return p+1; |
| 406 | } | 409 | } |
| 407 | case '[': { | 410 | case '[': { |
| 408 | if (*p == '^') p++; | 411 | if (*p == '^') p++; |
| 409 | do { /* look for a ']' */ | 412 | do { /* look for a ']' */ |
| 410 | if (p == ms->p_end) | 413 | if (l_unlikely(p == ms->p_end)) |
| 411 | luaL_error(ms->L, "malformed pattern (missing ']')"); | 414 | luaL_error(ms->L, "malformed pattern (missing ']')"); |
| 412 | if (*(p++) == L_ESC && p < ms->p_end) | 415 | if (*(p++) == L_ESC && p < ms->p_end) |
| 413 | p++; /* skip escapes (e.g. '%]') */ | 416 | p++; /* skip escapes (e.g. '%]') */ |
| @@ -482,7 +485,7 @@ static int singlematch (MatchState *ms, const char *s, const char *p, | |||
| 482 | 485 | ||
| 483 | static const char *matchbalance (MatchState *ms, const char *s, | 486 | static const char *matchbalance (MatchState *ms, const char *s, |
| 484 | const char *p) { | 487 | const char *p) { |
| 485 | if (p >= ms->p_end - 1) | 488 | if (l_unlikely(p >= ms->p_end - 1)) |
| 486 | luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); | 489 | luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); |
| 487 | if (*s != *p) return NULL; | 490 | if (*s != *p) return NULL; |
| 488 | else { | 491 | else { |
| @@ -565,7 +568,7 @@ static const char *match_capture (MatchState *ms, const char *s, int l) { | |||
| 565 | 568 | ||
| 566 | 569 | ||
| 567 | static const char *match (MatchState *ms, const char *s, const char *p) { | 570 | static const char *match (MatchState *ms, const char *s, const char *p) { |
| 568 | if (ms->matchdepth-- == 0) | 571 | if (l_unlikely(ms->matchdepth-- == 0)) |
| 569 | luaL_error(ms->L, "pattern too complex"); | 572 | luaL_error(ms->L, "pattern too complex"); |
| 570 | init: /* using goto's to optimize tail recursion */ | 573 | init: /* using goto's to optimize tail recursion */ |
| 571 | if (p != ms->p_end) { /* end of pattern? */ | 574 | if (p != ms->p_end) { /* end of pattern? */ |
| @@ -599,7 +602,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { | |||
| 599 | case 'f': { /* frontier? */ | 602 | case 'f': { /* frontier? */ |
| 600 | const char *ep; char previous; | 603 | const char *ep; char previous; |
| 601 | p += 2; | 604 | p += 2; |
| 602 | if (*p != '[') | 605 | if (l_unlikely(*p != '[')) |
| 603 | luaL_error(ms->L, "missing '[' after '%%f' in pattern"); | 606 | luaL_error(ms->L, "missing '[' after '%%f' in pattern"); |
| 604 | ep = classend(ms, p); /* points to what is next */ | 607 | ep = classend(ms, p); /* points to what is next */ |
| 605 | previous = (s == ms->src_init) ? '\0' : *(s - 1); | 608 | previous = (s == ms->src_init) ? '\0' : *(s - 1); |
| @@ -699,7 +702,7 @@ static const char *lmemfind (const char *s1, size_t l1, | |||
| 699 | static size_t get_onecapture (MatchState *ms, int i, const char *s, | 702 | static size_t get_onecapture (MatchState *ms, int i, const char *s, |
| 700 | const char *e, const char **cap) { | 703 | const char *e, const char **cap) { |
| 701 | if (i >= ms->level) { | 704 | if (i >= ms->level) { |
| 702 | if (i != 0) | 705 | if (l_unlikely(i != 0)) |
| 703 | luaL_error(ms->L, "invalid capture index %%%d", i + 1); | 706 | luaL_error(ms->L, "invalid capture index %%%d", i + 1); |
| 704 | *cap = s; | 707 | *cap = s; |
| 705 | return e - s; | 708 | return e - s; |
| @@ -707,7 +710,7 @@ static size_t get_onecapture (MatchState *ms, int i, const char *s, | |||
| 707 | else { | 710 | else { |
| 708 | ptrdiff_t capl = ms->capture[i].len; | 711 | ptrdiff_t capl = ms->capture[i].len; |
| 709 | *cap = ms->capture[i].init; | 712 | *cap = ms->capture[i].init; |
| 710 | if (capl == CAP_UNFINISHED) | 713 | if (l_unlikely(capl == CAP_UNFINISHED)) |
| 711 | luaL_error(ms->L, "unfinished capture"); | 714 | luaL_error(ms->L, "unfinished capture"); |
| 712 | else if (capl == CAP_POSITION) | 715 | else if (capl == CAP_POSITION) |
| 713 | lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); | 716 | lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); |
| @@ -926,7 +929,7 @@ static int add_value (MatchState *ms, luaL_Buffer *b, const char *s, | |||
| 926 | luaL_addlstring(b, s, e - s); /* keep original text */ | 929 | luaL_addlstring(b, s, e - s); /* keep original text */ |
| 927 | return 0; /* no changes */ | 930 | return 0; /* no changes */ |
| 928 | } | 931 | } |
| 929 | else if (!lua_isstring(L, -1)) | 932 | else if (l_unlikely(!lua_isstring(L, -1))) |
| 930 | return luaL_error(L, "invalid replacement value (a %s)", | 933 | return luaL_error(L, "invalid replacement value (a %s)", |
| 931 | luaL_typename(L, -1)); | 934 | luaL_typename(L, -1)); |
| 932 | else { | 935 | else { |
| @@ -1058,7 +1061,7 @@ static int lua_number2strx (lua_State *L, char *buff, int sz, | |||
| 1058 | for (i = 0; i < n; i++) | 1061 | for (i = 0; i < n; i++) |
| 1059 | buff[i] = toupper(uchar(buff[i])); | 1062 | buff[i] = toupper(uchar(buff[i])); |
| 1060 | } | 1063 | } |
| 1061 | else if (fmt[SIZELENMOD] != 'a') | 1064 | else if (l_unlikely(fmt[SIZELENMOD] != 'a')) |
| 1062 | return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); | 1065 | return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); |
| 1063 | return n; | 1066 | return n; |
| 1064 | } | 1067 | } |
| @@ -1411,7 +1414,7 @@ static int getnum (const char **fmt, int df) { | |||
| 1411 | */ | 1414 | */ |
| 1412 | static int getnumlimit (Header *h, const char **fmt, int df) { | 1415 | static int getnumlimit (Header *h, const char **fmt, int df) { |
| 1413 | int sz = getnum(fmt, df); | 1416 | int sz = getnum(fmt, df); |
| 1414 | if (sz > MAXINTSIZE || sz <= 0) | 1417 | if (l_unlikely(sz > MAXINTSIZE || sz <= 0)) |
| 1415 | return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", | 1418 | return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", |
| 1416 | sz, MAXINTSIZE); | 1419 | sz, MAXINTSIZE); |
| 1417 | return sz; | 1420 | return sz; |
| @@ -1452,7 +1455,7 @@ static KOption getoption (Header *h, const char **fmt, int *size) { | |||
| 1452 | case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; | 1455 | case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; |
| 1453 | case 'c': | 1456 | case 'c': |
| 1454 | *size = getnum(fmt, -1); | 1457 | *size = getnum(fmt, -1); |
| 1455 | if (*size == -1) | 1458 | if (l_unlikely(*size == -1)) |
| 1456 | luaL_error(h->L, "missing size for format option 'c'"); | 1459 | luaL_error(h->L, "missing size for format option 'c'"); |
| 1457 | return Kchar; | 1460 | return Kchar; |
| 1458 | case 'z': return Kzstr; | 1461 | case 'z': return Kzstr; |
| @@ -1491,7 +1494,7 @@ static KOption getdetails (Header *h, size_t totalsize, | |||
| 1491 | else { | 1494 | else { |
| 1492 | if (align > h->maxalign) /* enforce maximum alignment */ | 1495 | if (align > h->maxalign) /* enforce maximum alignment */ |
| 1493 | align = h->maxalign; | 1496 | align = h->maxalign; |
| 1494 | if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ | 1497 | if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */ |
| 1495 | luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); | 1498 | luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); |
| 1496 | *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); | 1499 | *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); |
| 1497 | } | 1500 | } |
| @@ -1683,7 +1686,7 @@ static lua_Integer unpackint (lua_State *L, const char *str, | |||
| 1683 | else if (size > SZINT) { /* must check unread bytes */ | 1686 | else if (size > SZINT) { /* must check unread bytes */ |
| 1684 | int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; | 1687 | int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; |
| 1685 | for (i = limit; i < size; i++) { | 1688 | for (i = limit; i < size; i++) { |
| 1686 | if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) | 1689 | if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask)) |
| 1687 | luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); | 1690 | luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); |
| 1688 | } | 1691 | } |
| 1689 | } | 1692 | } |
