Skip to content

Commit

Permalink
[parser] don't explode on numbers > 2^32-1
Browse files Browse the repository at this point in the history
Summary:
js_of_ocaml's ints are 32-bit, and `int_of_string` throws when you give
it a bigger number. floats are IEEE 754 double precision in both js_of_ocaml and
ocaml, so they're fine.

when parsing octal and binary numbers, we were using `int_of_string` because it
supports `0o` and `0b` prefixes while `float_of_string` doesn't (but
`float_of_string` does support `0x`, so large hex numbers were not affected).

instead, if we use the `Int64` versions, it also works in js_of_ocaml.

Fixes #3238

Reviewed By: gabelevi

Differential Revision: D4448945

fbshipit-source-id: 26e5c956442819e03e199139582f9020d225072a
  • Loading branch information
mroch authored and facebook-github-bot committed Jan 23, 2017
1 parent bad78b1 commit 6ed6132
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/parser/expression_parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,10 @@ module Expression
let value = match number_type with
| LEGACY_OCTAL ->
strict_error env Error.StrictOctalLiteral;
float (int_of_string ("0o"^value))
Int64.to_float (Int64.of_string ("0o"^value))
| BINARY
| OCTAL ->
float (int_of_string value)
Int64.to_float (Int64.of_string value)
| NORMAL ->
try Lexer_flow.FloatOfString.float_of_string value
with _ when Sys.win32 ->
Expand Down
4 changes: 2 additions & 2 deletions src/parser/lexer_flow.mll
Original file line number Diff line number Diff line change
Expand Up @@ -654,10 +654,10 @@ end
(* convert singleton number type into a float *)
let value = match number_type with
| LEGACY_OCTAL ->
float (int_of_string ("0o"^num))
Int64.to_float (Int64.of_string ("0o"^num))
| BINARY
| OCTAL ->
float (int_of_string num)
Int64.to_float (Int64.of_string num)
| NORMAL ->
FloatOfString.float_of_string num
in
Expand Down
53 changes: 53 additions & 0 deletions src/parser/test/hardcoded_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2590,6 +2590,27 @@ module.exports = {
'raw': '- 123',
}
},
'var a: 25257156155': {
'body.0.declarations.0.id.typeAnnotation.typeAnnotation': {
'type': 'NumberLiteralTypeAnnotation',
'value': 25257156155,
'raw': '25257156155',
}
},
'var a: 0x5E1719E3B': {
'body.0.declarations.0.id.typeAnnotation.typeAnnotation': {
'type': 'NumberLiteralTypeAnnotation',
'value': 25257156155,
'raw': '0x5E1719E3B',
}
},
'var a: 0o274134317073': {
'body.0.declarations.0.id.typeAnnotation.typeAnnotation': {
'type': 'NumberLiteralTypeAnnotation',
'value': 25257156155,
'raw': '0o274134317073',
}
},
},
'Invalid Number Literal Types': {
'var a: 0173': {
Expand Down Expand Up @@ -5318,5 +5339,37 @@ module.exports = {
'errors.0.message': 'Missing comma between import specifiers'
},
},
'Large numbers (ints are 32-bit in js_of_ocaml)': {
'25257156155': {
'body.0.expression': {
'value': 25257156155,
'raw':'25257156155',
},
},
'0274134317073': {
'body.0.expression': {
'value': 25257156155,
'raw':'0274134317073',
},
},
'0o274134317073': {
'body.0.expression': {
'value': 25257156155,
'raw':'0o274134317073',
},
},
'0x5E1719E3B': {
'body.0.expression': {
'value': 25257156155,
'raw':'0x5E1719E3B',
},
},
'0b10111100001011100011001111000111011': {
'body.0.expression': {
'value': 25257156155,
'raw':'0b10111100001011100011001111000111011',
},
},
}
}
};

0 comments on commit 6ed6132

Please # to comment.