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 | } |