diff options
| author | Mike Pall <mike> | 2012-10-24 23:46:21 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2012-10-24 23:46:21 +0200 |
| commit | c7990063e0f1a522724a5c21845c2ea698d0f5bf (patch) | |
| tree | e317fb85f8f7324e5e18bc455dc58ad83b884182 /src | |
| parent | f874452ddb9d094e1ed845e835bf11fc26216e51 (diff) | |
| download | luajit-c7990063e0f1a522724a5c21845c2ea698d0f5bf.tar.gz luajit-c7990063e0f1a522724a5c21845c2ea698d0f5bf.tar.bz2 luajit-c7990063e0f1a522724a5c21845c2ea698d0f5bf.zip | |
Fix builtin string to number conversion for INT_MIN.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_strscan.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/src/lj_strscan.c b/src/lj_strscan.c index 1e4b235c..1b7243fe 100644 --- a/src/lj_strscan.c +++ b/src/lj_strscan.c | |||
| @@ -122,14 +122,14 @@ static StrScanFmt strscan_hex(const uint8_t *p, TValue *o, | |||
| 122 | switch (fmt) { | 122 | switch (fmt) { |
| 123 | case STRSCAN_INT: | 123 | case STRSCAN_INT: |
| 124 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { | 124 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { |
| 125 | o->i = neg ? -(int)x : (int)x; | 125 | o->i = neg ? -(int32_t)x : (int32_t)x; |
| 126 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ | 126 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ |
| 127 | } | 127 | } |
| 128 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; } | 128 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; } |
| 129 | /* fallthrough */ | 129 | /* fallthrough */ |
| 130 | case STRSCAN_U32: | 130 | case STRSCAN_U32: |
| 131 | if (dig > 8) return STRSCAN_ERROR; | 131 | if (dig > 8) return STRSCAN_ERROR; |
| 132 | o->i = neg ? -(int)x : (int)x; | 132 | o->i = neg ? -(int32_t)x : (int32_t)x; |
| 133 | return STRSCAN_U32; | 133 | return STRSCAN_U32; |
| 134 | case STRSCAN_I64: | 134 | case STRSCAN_I64: |
| 135 | case STRSCAN_U64: | 135 | case STRSCAN_U64: |
| @@ -166,7 +166,7 @@ static StrScanFmt strscan_oct(const uint8_t *p, TValue *o, | |||
| 166 | /* fallthrough */ | 166 | /* fallthrough */ |
| 167 | case STRSCAN_U32: | 167 | case STRSCAN_U32: |
| 168 | if ((x >> 32)) return STRSCAN_ERROR; | 168 | if ((x >> 32)) return STRSCAN_ERROR; |
| 169 | o->i = neg ? -(int)x : (int)x; | 169 | o->i = neg ? -(int32_t)x : (int32_t)x; |
| 170 | break; | 170 | break; |
| 171 | default: | 171 | default: |
| 172 | case STRSCAN_I64: | 172 | case STRSCAN_I64: |
| @@ -227,14 +227,14 @@ static StrScanFmt strscan_dec(const uint8_t *p, TValue *o, | |||
| 227 | switch (fmt) { | 227 | switch (fmt) { |
| 228 | case STRSCAN_INT: | 228 | case STRSCAN_INT: |
| 229 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { | 229 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { |
| 230 | o->i = neg ? -(int)x : (int)x; | 230 | o->i = neg ? -(int32_t)x : (int32_t)x; |
| 231 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ | 231 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ |
| 232 | } | 232 | } |
| 233 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; goto plainnumber; } | 233 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; goto plainnumber; } |
| 234 | /* fallthrough */ | 234 | /* fallthrough */ |
| 235 | case STRSCAN_U32: | 235 | case STRSCAN_U32: |
| 236 | if ((x >> 32) != 0) return STRSCAN_ERROR; | 236 | if ((x >> 32) != 0) return STRSCAN_ERROR; |
| 237 | o->i = neg ? -(int)x : (int)x; | 237 | o->i = neg ? -(int32_t)x : (int32_t)x; |
| 238 | return STRSCAN_U32; | 238 | return STRSCAN_U32; |
| 239 | case STRSCAN_I64: | 239 | case STRSCAN_I64: |
| 240 | case STRSCAN_U64: | 240 | case STRSCAN_U64: |
| @@ -394,7 +394,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) | |||
| 394 | if (dp) { | 394 | if (dp) { |
| 395 | fmt = STRSCAN_NUM; | 395 | fmt = STRSCAN_NUM; |
| 396 | if (dig) { | 396 | if (dig) { |
| 397 | ex = (int)(dp-(p-1)); dp = p-1; | 397 | ex = (int32_t)(dp-(p-1)); dp = p-1; |
| 398 | while (ex < 0 && *dp-- == '0') ex++, dig--; /* Skip trailing zeros. */ | 398 | while (ex < 0 && *dp-- == '0') ex++, dig--; /* Skip trailing zeros. */ |
| 399 | if (base == 16) ex *= 4; | 399 | if (base == 16) ex *= 4; |
| 400 | } | 400 | } |
| @@ -412,7 +412,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) | |||
| 412 | if (xx < 65536) xx = xx * 10 + (*p & 15); | 412 | if (xx < 65536) xx = xx * 10 + (*p & 15); |
| 413 | p++; | 413 | p++; |
| 414 | } | 414 | } |
| 415 | ex += negx ? -(int)xx : (int)xx; | 415 | ex += negx ? -(int32_t)xx : (int32_t)xx; |
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | /* Parse suffix. */ | 418 | /* Parse suffix. */ |
| @@ -443,13 +443,12 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt) | |||
| 443 | /* Fast path for decimal 32 bit integers. */ | 443 | /* Fast path for decimal 32 bit integers. */ |
| 444 | if (fmt == STRSCAN_INT && base == 10 && | 444 | if (fmt == STRSCAN_INT && base == 10 && |
| 445 | (dig < 10 || (dig == 10 && *sp <= '2' && x < 0x80000000u+neg))) { | 445 | (dig < 10 || (dig == 10 && *sp <= '2' && x < 0x80000000u+neg))) { |
| 446 | int32_t y = neg ? -(int32_t)x : (int32_t)x; | ||
| 446 | if ((opt & STRSCAN_OPT_TONUM)) { | 447 | if ((opt & STRSCAN_OPT_TONUM)) { |
| 447 | double n = (double)(int32_t)x; | 448 | o->n = (double)y; |
| 448 | if (neg) n = -n; | ||
| 449 | o->n = n; | ||
| 450 | return STRSCAN_NUM; | 449 | return STRSCAN_NUM; |
| 451 | } else { | 450 | } else { |
| 452 | o->i = neg ? -(int)x : (int)x; | 451 | o->i = y; |
| 453 | return STRSCAN_INT; | 452 | return STRSCAN_INT; |
| 454 | } | 453 | } |
| 455 | } | 454 | } |
