aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2020-02-13 17:39:51 +0100
committerMike Pall <mike>2020-02-13 17:39:51 +0100
commit0ad60ccbc3768fa8e3e726858adf261950edbc22 (patch)
tree8f9822b7a3b82e3cd62732492339ae950ac5ca55 /src
parentd85d6b3c1b2c3d1ecf89ccff6ad7519e767fcebe (diff)
downloadluajit-0ad60ccbc3768fa8e3e726858adf261950edbc22.tar.gz
luajit-0ad60ccbc3768fa8e3e726858adf261950edbc22.tar.bz2
luajit-0ad60ccbc3768fa8e3e726858adf261950edbc22.zip
Make string to number conversions fail on NUL char.
Contributed by Igor Munkin.
Diffstat (limited to 'src')
-rw-r--r--src/lj_cparse.c3
-rw-r--r--src/lj_lex.c2
-rw-r--r--src/lj_strscan.c11
-rw-r--r--src/lj_strscan.h3
4 files changed, 12 insertions, 7 deletions
diff --git a/src/lj_cparse.c b/src/lj_cparse.c
index 70b82af3..a393965e 100644
--- a/src/lj_cparse.c
+++ b/src/lj_cparse.c
@@ -169,7 +169,8 @@ static CPToken cp_number(CPState *cp)
169 TValue o; 169 TValue o;
170 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); 170 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
171 cp_save(cp, '\0'); 171 cp_save(cp, '\0');
172 fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), &o, STRSCAN_OPT_C); 172 fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), sbuflen(&cp->sb)-1,
173 &o, STRSCAN_OPT_C);
173 if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; 174 if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
174 else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; 175 else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
175 else if (!(cp->mode & CPARSE_MODE_SKIP)) 176 else if (!(cp->mode & CPARSE_MODE_SKIP))
diff --git a/src/lj_lex.c b/src/lj_lex.c
index 05a2efc3..ada0876e 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -105,7 +105,7 @@ static void lex_number(LexState *ls, TValue *tv)
105 lex_savenext(ls); 105 lex_savenext(ls);
106 } 106 }
107 lex_save(ls, '\0'); 107 lex_save(ls, '\0');
108 fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), tv, 108 fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), sbuflen(&ls->sb)-1, tv,
109 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) | 109 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
110 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0)); 110 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
111 if (LJ_DUALNUM && fmt == STRSCAN_INT) { 111 if (LJ_DUALNUM && fmt == STRSCAN_INT) {
diff --git a/src/lj_strscan.c b/src/lj_strscan.c
index 948c84a7..433b33a3 100644
--- a/src/lj_strscan.c
+++ b/src/lj_strscan.c
@@ -370,9 +370,11 @@ static StrScanFmt strscan_bin(const uint8_t *p, TValue *o,
370} 370}
371 371
372/* Scan string containing a number. Returns format. Returns value in o. */ 372/* Scan string containing a number. Returns format. Returns value in o. */
373StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) 373StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
374 uint32_t opt)
374{ 375{
375 int32_t neg = 0; 376 int32_t neg = 0;
377 const uint8_t *pe = p + len;
376 378
377 /* Remove leading space, parse sign and non-numbers. */ 379 /* Remove leading space, parse sign and non-numbers. */
378 if (LJ_UNLIKELY(!lj_char_isdigit(*p))) { 380 if (LJ_UNLIKELY(!lj_char_isdigit(*p))) {
@@ -390,7 +392,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt)
390 p += 3; 392 p += 3;
391 } 393 }
392 while (lj_char_isspace(*p)) p++; 394 while (lj_char_isspace(*p)) p++;
393 if (*p) return STRSCAN_ERROR; 395 if (*p || p < pe) return STRSCAN_ERROR;
394 o->u64 = tmp.u64; 396 o->u64 = tmp.u64;
395 return STRSCAN_NUM; 397 return STRSCAN_NUM;
396 } 398 }
@@ -488,6 +490,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt)
488 while (lj_char_isspace(*p)) p++; 490 while (lj_char_isspace(*p)) p++;
489 if (*p) return STRSCAN_ERROR; 491 if (*p) return STRSCAN_ERROR;
490 } 492 }
493 if (p < pe) return STRSCAN_ERROR;
491 494
492 /* Fast path for decimal 32 bit integers. */ 495 /* Fast path for decimal 32 bit integers. */
493 if (fmt == STRSCAN_INT && base == 10 && 496 if (fmt == STRSCAN_INT && base == 10 &&
@@ -523,7 +526,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt)
523 526
524int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o) 527int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o)
525{ 528{
526 StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), o, 529 StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), str->len, o,
527 STRSCAN_OPT_TONUM); 530 STRSCAN_OPT_TONUM);
528 lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM); 531 lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM);
529 return (fmt != STRSCAN_ERROR); 532 return (fmt != STRSCAN_ERROR);
@@ -532,7 +535,7 @@ int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o)
532#if LJ_DUALNUM 535#if LJ_DUALNUM
533int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o) 536int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o)
534{ 537{
535 StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), o, 538 StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), str->len, o,
536 STRSCAN_OPT_TOINT); 539 STRSCAN_OPT_TOINT);
537 lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM || fmt == STRSCAN_INT); 540 lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM || fmt == STRSCAN_INT);
538 if (fmt == STRSCAN_INT) setitype(o, LJ_TISNUM); 541 if (fmt == STRSCAN_INT) setitype(o, LJ_TISNUM);
diff --git a/src/lj_strscan.h b/src/lj_strscan.h
index 42aa1455..30e271b2 100644
--- a/src/lj_strscan.h
+++ b/src/lj_strscan.h
@@ -22,7 +22,8 @@ typedef enum {
22 STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64, 22 STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64,
23} StrScanFmt; 23} StrScanFmt;
24 24
25LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt); 25LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
26 uint32_t opt);
26LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o); 27LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o);
27#if LJ_DUALNUM 28#if LJ_DUALNUM
28LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o); 29LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o);