aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/lstrlib.c b/lstrlib.c
index c7242ea4..47e5b27a 100644
--- a/lstrlib.c
+++ b/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
276static void trymt (lua_State *L, const char *mtname) { 277static 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
384static int check_capture (MatchState *ms, int l) { 386static 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) {
400static const char *classend (MatchState *ms, const char *p) { 403static 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
483static const char *matchbalance (MatchState *ms, const char *s, 486static 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
567static const char *match (MatchState *ms, const char *s, const char *p) { 570static 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,
699static size_t get_onecapture (MatchState *ms, int i, const char *s, 702static 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*/
1412static int getnumlimit (Header *h, const char **fmt, int df) { 1415static 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 }