Skip to content

Commit 0ad60cc

Browse files
author
Mike Pall
committed
Make string to number conversions fail on NUL char.
Contributed by Igor Munkin.
1 parent d85d6b3 commit 0ad60cc

File tree

4 files changed

+12
-7
lines changed

4 files changed

+12
-7
lines changed

src/lj_cparse.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ static CPToken cp_number(CPState *cp)
169169
TValue o;
170170
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
171171
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);
173174
if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
174175
else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
175176
else if (!(cp->mode & CPARSE_MODE_SKIP))

src/lj_lex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static void lex_number(LexState *ls, TValue *tv)
105105
lex_savenext(ls);
106106
}
107107
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,
109109
(LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
110110
(LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
111111
if (LJ_DUALNUM && fmt == STRSCAN_INT) {

src/lj_strscan.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,11 @@ static StrScanFmt strscan_bin(const uint8_t *p, TValue *o,
370370
}
371371

372372
/* Scan string containing a number. Returns format. Returns value in o. */
373-
StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt)
373+
StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
374+
uint32_t opt)
374375
{
375376
int32_t neg = 0;
377+
const uint8_t *pe = p + len;
376378

377379
/* Remove leading space, parse sign and non-numbers. */
378380
if (LJ_UNLIKELY(!lj_char_isdigit(*p))) {
@@ -390,7 +392,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt)
390392
p += 3;
391393
}
392394
while (lj_char_isspace(*p)) p++;
393-
if (*p) return STRSCAN_ERROR;
395+
if (*p || p < pe) return STRSCAN_ERROR;
394396
o->u64 = tmp.u64;
395397
return STRSCAN_NUM;
396398
}
@@ -488,6 +490,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt)
488490
while (lj_char_isspace(*p)) p++;
489491
if (*p) return STRSCAN_ERROR;
490492
}
493+
if (p < pe) return STRSCAN_ERROR;
491494

492495
/* Fast path for decimal 32 bit integers. */
493496
if (fmt == STRSCAN_INT && base == 10 &&
@@ -523,7 +526,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt)
523526

524527
int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o)
525528
{
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,
527530
STRSCAN_OPT_TONUM);
528531
lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM);
529532
return (fmt != STRSCAN_ERROR);
@@ -532,7 +535,7 @@ int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o)
532535
#if LJ_DUALNUM
533536
int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o)
534537
{
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,
536539
STRSCAN_OPT_TOINT);
537540
lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM || fmt == STRSCAN_INT);
538541
if (fmt == STRSCAN_INT) setitype(o, LJ_TISNUM);

src/lj_strscan.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ typedef enum {
2222
STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64,
2323
} StrScanFmt;
2424

25-
LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt);
25+
LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
26+
uint32_t opt);
2627
LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o);
2728
#if LJ_DUALNUM
2829
LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o);

0 commit comments

Comments
 (0)