diff options
| author | Mike Pall <mike> | 2020-02-13 17:39:51 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2020-02-13 17:39:51 +0100 |
| commit | 0ad60ccbc3768fa8e3e726858adf261950edbc22 (patch) | |
| tree | 8f9822b7a3b82e3cd62732492339ae950ac5ca55 /src | |
| parent | d85d6b3c1b2c3d1ecf89ccff6ad7519e767fcebe (diff) | |
| download | luajit-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.c | 3 | ||||
| -rw-r--r-- | src/lj_lex.c | 2 | ||||
| -rw-r--r-- | src/lj_strscan.c | 11 | ||||
| -rw-r--r-- | src/lj_strscan.h | 3 |
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. */ |
| 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) | ||
| 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 | ||
| 524 | int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o) | 527 | int 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 |
| 533 | int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o) | 536 | int 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 | ||
| 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); | ||
| 26 | LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o); | 27 | LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o); |
| 27 | #if LJ_DUALNUM | 28 | #if LJ_DUALNUM |
| 28 | LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o); | 29 | LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o); |
