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) TValue o; do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); cp_save(cp, '\0'); - fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), &o, STRSCAN_OPT_C); + fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), sbuflen(&cp->sb)-1, + &o, STRSCAN_OPT_C); if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; 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) lex_savenext(ls); } lex_save(ls, '\0'); - fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), tv, + fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), sbuflen(&ls->sb)-1, tv, (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) | (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0)); 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, } /* Scan string containing a number. Returns format. Returns value in o. */ -StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) +StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, + uint32_t opt) { int32_t neg = 0; + const uint8_t *pe = p + len; /* Remove leading space, parse sign and non-numbers. */ if (LJ_UNLIKELY(!lj_char_isdigit(*p))) { @@ -390,7 +392,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) p += 3; } while (lj_char_isspace(*p)) p++; - if (*p) return STRSCAN_ERROR; + if (*p || p < pe) return STRSCAN_ERROR; o->u64 = tmp.u64; return STRSCAN_NUM; } @@ -488,6 +490,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) while (lj_char_isspace(*p)) p++; if (*p) return STRSCAN_ERROR; } + if (p < pe) return STRSCAN_ERROR; /* Fast path for decimal 32 bit integers. */ if (fmt == STRSCAN_INT && base == 10 && @@ -523,7 +526,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o) { - StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), o, + StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), str->len, o, STRSCAN_OPT_TONUM); lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM); return (fmt != STRSCAN_ERROR); @@ -532,7 +535,7 @@ int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o) #if LJ_DUALNUM int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o) { - StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), o, + StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), str->len, o, STRSCAN_OPT_TOINT); lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM || fmt == STRSCAN_INT); 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 { STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64, } StrScanFmt; -LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt); +LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, + uint32_t opt); LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o); #if LJ_DUALNUM LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o);