|
@@ -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. */
|
|
/* 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;
|
|
int32_t neg = 0;
|
|
|
|
+ const uint8_t *pe = p + len;
|
|
|
|
|
|
/* Remove leading space, parse sign and non-numbers. */
|
|
/* Remove leading space, parse sign and non-numbers. */
|
|
if (LJ_UNLIKELY(!lj_char_isdigit(*p))) {
|
|
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;
|
|
p += 3;
|
|
}
|
|
}
|
|
while (lj_char_isspace(*p)) p++;
|
|
while (lj_char_isspace(*p)) p++;
|
|
- if (*p) return STRSCAN_ERROR;
|
|
|
|
|
|
+ if (*p || p < pe) return STRSCAN_ERROR;
|
|
o->u64 = tmp.u64;
|
|
o->u64 = tmp.u64;
|
|
return STRSCAN_NUM;
|
|
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++;
|
|
while (lj_char_isspace(*p)) p++;
|
|
if (*p) return STRSCAN_ERROR;
|
|
if (*p) return STRSCAN_ERROR;
|
|
}
|
|
}
|
|
|
|
+ if (p < pe) return STRSCAN_ERROR;
|
|
|
|
|
|
/* Fast path for decimal 32 bit integers. */
|
|
/* Fast path for decimal 32 bit integers. */
|
|
if (fmt == STRSCAN_INT && base == 10 &&
|
|
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)
|
|
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);
|
|
STRSCAN_OPT_TONUM);
|
|
lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM);
|
|
lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM);
|
|
return (fmt != STRSCAN_ERROR);
|
|
return (fmt != STRSCAN_ERROR);
|
|
@@ -532,7 +535,7 @@ int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o)
|
|
#if LJ_DUALNUM
|
|
#if LJ_DUALNUM
|
|
int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o)
|
|
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);
|
|
STRSCAN_OPT_TOINT);
|
|
lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM || fmt == STRSCAN_INT);
|
|
lua_assert(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM || fmt == STRSCAN_INT);
|
|
if (fmt == STRSCAN_INT) setitype(o, LJ_TISNUM);
|
|
if (fmt == STRSCAN_INT) setitype(o, LJ_TISNUM);
|