mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Make string to number conversions fail on NUL char.
Contributed by Igor Munkin.
This commit is contained in:
parent
d85d6b3c1b
commit
0ad60ccbc3
@ -169,7 +169,8 @@ static CPToken cp_number(CPState *cp)
|
|||||||
TValue o;
|
TValue o;
|
||||||
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
|
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
|
||||||
cp_save(cp, '\0');
|
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;
|
if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
|
||||||
else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
|
else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
|
||||||
else if (!(cp->mode & CPARSE_MODE_SKIP))
|
else if (!(cp->mode & CPARSE_MODE_SKIP))
|
||||||
|
@ -105,7 +105,7 @@ static void lex_number(LexState *ls, TValue *tv)
|
|||||||
lex_savenext(ls);
|
lex_savenext(ls);
|
||||||
}
|
}
|
||||||
lex_save(ls, '\0');
|
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_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
|
||||||
(LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
|
(LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
|
||||||
if (LJ_DUALNUM && fmt == STRSCAN_INT) {
|
if (LJ_DUALNUM && fmt == STRSCAN_INT) {
|
||||||
|
@ -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);
|
||||||
|
@ -22,7 +22,8 @@ typedef enum {
|
|||||||
STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64,
|
STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64,
|
||||||
} StrScanFmt;
|
} 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);
|
LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o);
|
||||||
#if LJ_DUALNUM
|
#if LJ_DUALNUM
|
||||||
LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o);
|
LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o);
|
||||||
|
Loading…
Reference in New Issue
Block a user