Skip to content

Commit 32cf0f1

Browse files
authored
Merge pull request github#3179 from asger-semmle/js/underscore_int_literals
Approved by erik-krogh
2 parents bbb69d5 + 541ff40 commit 32cf0f1

File tree

7 files changed

+177
-2
lines changed

7 files changed

+177
-2
lines changed

javascript/extractor/src/com/semmle/jcorn/ESNextParser.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ protected Number readInt(int radix, Integer len) {
482482

483483
if (code == '_') {
484484
if (underscoreAllowed) {
485+
seenUnderscoreNumericSeparator = true;
485486
// no adjacent underscores
486487
underscoreAllowed = false;
487488
++this.pos;

javascript/extractor/src/com/semmle/jcorn/Parser.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ public class Parser {
145145
private Stack<LabelInfo> labels;
146146
protected int yieldPos, awaitPos;
147147

148+
/**
149+
* Set to true by {@link ESNextParser#readInt} if the parsed integer contains an underscore.
150+
*/
151+
protected boolean seenUnderscoreNumericSeparator = false;
152+
148153
/**
149154
* For readability purposes, we pass this instead of false as the argument to the
150155
* hasDeclareKeyword parameter (which only exists in TypeScript).
@@ -654,7 +659,7 @@ protected Token getTokenFromCode(int code) {
654659
case 58:
655660
++this.pos;
656661
return this.finishToken(TokenType.colon);
657-
case 35:
662+
case 35:
658663
++this.pos;
659664
return this.finishToken(TokenType.pound);
660665
case 63:
@@ -847,6 +852,10 @@ else if (Identifiers.isIdentifierStart(this.fullCharCodeAtPos(), false))
847852
}
848853

849854
String str = inputSubstring(start, this.pos);
855+
if (seenUnderscoreNumericSeparator) {
856+
str = str.replace("_", "");
857+
seenUnderscoreNumericSeparator = false;
858+
}
850859
Number val = null;
851860
if (isFloat) val = parseFloat(str);
852861
else if (!octal || str.length() == 1) val = parseInt(str, 10);

javascript/extractor/src/com/semmle/js/extractor/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class Main {
3838
* A version identifier that should be updated every time the extractor changes in such a way that
3939
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
4040
*/
41-
public static final String EXTRACTOR_VERSION = "2020-02-14";
41+
public static final String EXTRACTOR_VERSION = "2020-04-01";
4242

4343
public static final Pattern NEWLINE = Pattern.compile("\n");
4444

javascript/ql/test/library-tests/Constants/Constants.expected

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,123 @@
1+
getIntValue
2+
| tst2.ts:1:21:1:21 | 1 | 1 |
3+
| tst.js:6:1:6:1 | 1 | 1 |
4+
| tst.js:11:1:11:2 | -1 | -1 |
5+
| tst.js:11:2:11:2 | 1 | 1 |
6+
| tst.js:12:2:12:2 | 0 | 0 |
7+
| tst.js:26:3:26:3 | 0 | 0 |
8+
| tst.js:29:6:29:6 | 0 | 0 |
9+
| tst.js:35:1:35:1 | 1 | 1 |
10+
| tst.js:35:5:35:5 | 2 | 2 |
11+
| tst.js:35:9:35:9 | 3 | 3 |
12+
| tst.js:37:1:37:3 | (1) | 1 |
13+
| tst.js:37:2:37:2 | 1 | 1 |
14+
| tst.js:39:4:39:4 | 1 | 1 |
15+
| tst.js:40:1:40:1 | 1 | 1 |
16+
| tst.js:42:1:42:1 | 1 | 1 |
17+
| tst.js:42:4:42:4 | 2 | 2 |
18+
| tst.js:42:7:42:7 | 3 | 3 |
19+
| tst.js:43:4:43:4 | 2 | 2 |
20+
| tst.js:43:7:43:7 | 3 | 3 |
21+
| tst.js:44:1:44:1 | 1 | 1 |
22+
| tst.js:44:7:44:7 | 3 | 3 |
23+
| tst.js:45:1:45:1 | 1 | 1 |
24+
| tst.js:45:4:45:4 | 2 | 2 |
25+
| tst.js:47:5:47:5 | 1 | 1 |
26+
| tst.js:48:7:48:7 | 1 | 1 |
27+
| tst.js:49:6:49:6 | 1 | 1 |
28+
| tst.js:52:5:52:9 | 1_000 | 1000 |
29+
| tst.js:53:5:53:13 | 1_000_123 | 1000123 |
30+
| tst.js:54:5:54:17 | 1_000_000_000 | 1000000000 |
31+
| tst.js:56:5:56:10 | 123_00 | 12300 |
32+
| tst.js:57:5:57:10 | 12_300 | 12300 |
33+
| tst.js:58:5:58:12 | 12345_00 | 1234500 |
34+
| tst.js:59:5:59:12 | 123_4500 | 1234500 |
35+
| tst.js:60:5:60:13 | 1_234_500 | 1234500 |
36+
| tst.js:62:5:62:14 | 0xaa_bb_cc | 11189196 |
37+
getFloatValue
38+
| tst2.ts:1:21:1:21 | 1 | 1.0 |
39+
| tst.js:6:1:6:1 | 1 | 1.0 |
40+
| tst.js:11:2:11:2 | 1 | 1.0 |
41+
| tst.js:12:2:12:2 | 0 | 0.0 |
42+
| tst.js:26:3:26:3 | 0 | 0.0 |
43+
| tst.js:29:6:29:6 | 0 | 0.0 |
44+
| tst.js:35:1:35:1 | 1 | 1.0 |
45+
| tst.js:35:5:35:5 | 2 | 2.0 |
46+
| tst.js:35:9:35:9 | 3 | 3.0 |
47+
| tst.js:37:2:37:2 | 1 | 1.0 |
48+
| tst.js:39:4:39:4 | 1 | 1.0 |
49+
| tst.js:40:1:40:1 | 1 | 1.0 |
50+
| tst.js:42:1:42:1 | 1 | 1.0 |
51+
| tst.js:42:4:42:4 | 2 | 2.0 |
52+
| tst.js:42:7:42:7 | 3 | 3.0 |
53+
| tst.js:43:4:43:4 | 2 | 2.0 |
54+
| tst.js:43:7:43:7 | 3 | 3.0 |
55+
| tst.js:44:1:44:1 | 1 | 1.0 |
56+
| tst.js:44:7:44:7 | 3 | 3.0 |
57+
| tst.js:45:1:45:1 | 1 | 1.0 |
58+
| tst.js:45:4:45:4 | 2 | 2.0 |
59+
| tst.js:47:5:47:5 | 1 | 1.0 |
60+
| tst.js:48:7:48:7 | 1 | 1.0 |
61+
| tst.js:49:6:49:6 | 1 | 1.0 |
62+
| tst.js:52:5:52:9 | 1_000 | 1000.0 |
63+
| tst.js:53:5:53:13 | 1_000_123 | 1000123.0 |
64+
| tst.js:54:5:54:17 | 1_000_000_000 | 1.0E9 |
65+
| tst.js:55:5:55:18 | 101_475_938.38 | 1.0147593838E8 |
66+
| tst.js:56:5:56:10 | 123_00 | 12300.0 |
67+
| tst.js:57:5:57:10 | 12_300 | 12300.0 |
68+
| tst.js:58:5:58:12 | 12345_00 | 1234500.0 |
69+
| tst.js:59:5:59:12 | 123_4500 | 1234500.0 |
70+
| tst.js:60:5:60:13 | 1_234_500 | 1234500.0 |
71+
| tst.js:61:5:61:10 | 1e1_00 | 1.0E100 |
72+
| tst.js:62:5:62:14 | 0xaa_bb_cc | 1.1189196E7 |
73+
getLiteralValue
74+
| tst2.ts:1:21:1:21 | 1 | 1 |
75+
| tst.js:1:1:1:3 | "a" | a |
76+
| tst.js:2:1:2:3 | "b" | b |
77+
| tst.js:2:7:2:9 | "c" | c |
78+
| tst.js:3:1:3:3 | "d" | d |
79+
| tst.js:3:7:3:9 | "e" | e |
80+
| tst.js:3:13:3:15 | "f" | f |
81+
| tst.js:6:1:6:1 | 1 | 1 |
82+
| tst.js:8:1:8:5 | false | false |
83+
| tst.js:9:1:9:4 | true | true |
84+
| tst.js:11:2:11:2 | 1 | 1 |
85+
| tst.js:12:2:12:2 | 0 | 0 |
86+
| tst.js:14:1:14:4 | null | null |
87+
| tst.js:20:1:20:3 | /x/ | /x/ |
88+
| tst.js:24:5:24:7 | "x" | x |
89+
| tst.js:26:3:26:3 | 0 | 0 |
90+
| tst.js:29:6:29:6 | 0 | 0 |
91+
| tst.js:35:1:35:1 | 1 | 1 |
92+
| tst.js:35:5:35:5 | 2 | 2 |
93+
| tst.js:35:9:35:9 | 3 | 3 |
94+
| tst.js:37:2:37:2 | 1 | 1 |
95+
| tst.js:39:4:39:4 | 1 | 1 |
96+
| tst.js:40:1:40:1 | 1 | 1 |
97+
| tst.js:42:1:42:1 | 1 | 1 |
98+
| tst.js:42:4:42:4 | 2 | 2 |
99+
| tst.js:42:7:42:7 | 3 | 3 |
100+
| tst.js:43:4:43:4 | 2 | 2 |
101+
| tst.js:43:7:43:7 | 3 | 3 |
102+
| tst.js:44:1:44:1 | 1 | 1 |
103+
| tst.js:44:7:44:7 | 3 | 3 |
104+
| tst.js:45:1:45:1 | 1 | 1 |
105+
| tst.js:45:4:45:4 | 2 | 2 |
106+
| tst.js:47:5:47:5 | 1 | 1 |
107+
| tst.js:48:7:48:7 | 1 | 1 |
108+
| tst.js:49:6:49:6 | 1 | 1 |
109+
| tst.js:52:5:52:9 | 1_000 | 1000 |
110+
| tst.js:53:5:53:13 | 1_000_123 | 1000123 |
111+
| tst.js:54:5:54:17 | 1_000_000_000 | 1000000000 |
112+
| tst.js:55:5:55:18 | 101_475_938.38 | 1.0147593838E8 |
113+
| tst.js:56:5:56:10 | 123_00 | 12300 |
114+
| tst.js:57:5:57:10 | 12_300 | 12300 |
115+
| tst.js:58:5:58:12 | 12345_00 | 1234500 |
116+
| tst.js:59:5:59:12 | 123_4500 | 1234500 |
117+
| tst.js:60:5:60:13 | 1_234_500 | 1234500 |
118+
| tst.js:61:5:61:10 | 1e1_00 | 1.0E100 |
119+
| tst.js:62:5:62:14 | 0xaa_bb_cc | 11189196 |
120+
#select
1121
| tst2.ts:1:13:1:21 | <number>1 |
2122
| tst2.ts:1:21:1:21 | 1 |
3123
| tst.js:1:1:1:3 | "a" |
@@ -61,3 +181,25 @@
61181
| tst.js:48:1:48:7 | x.p = 1 |
62182
| tst.js:48:7:48:7 | 1 |
63183
| tst.js:49:6:49:6 | 1 |
184+
| tst.js:52:1:52:9 | x = 1_000 |
185+
| tst.js:52:5:52:9 | 1_000 |
186+
| tst.js:53:1:53:13 | x = 1_000_123 |
187+
| tst.js:53:5:53:13 | 1_000_123 |
188+
| tst.js:54:1:54:17 | x = 1_000_000_000 |
189+
| tst.js:54:5:54:17 | 1_000_000_000 |
190+
| tst.js:55:1:55:18 | x = 101_475_938.38 |
191+
| tst.js:55:5:55:18 | 101_475_938.38 |
192+
| tst.js:56:1:56:10 | x = 123_00 |
193+
| tst.js:56:5:56:10 | 123_00 |
194+
| tst.js:57:1:57:10 | x = 12_300 |
195+
| tst.js:57:5:57:10 | 12_300 |
196+
| tst.js:58:1:58:12 | x = 12345_00 |
197+
| tst.js:58:5:58:12 | 12345_00 |
198+
| tst.js:59:1:59:12 | x = 123_4500 |
199+
| tst.js:59:5:59:12 | 123_4500 |
200+
| tst.js:60:1:60:13 | x = 1_234_500 |
201+
| tst.js:60:5:60:13 | 1_234_500 |
202+
| tst.js:61:1:61:10 | x = 1e1_00 |
203+
| tst.js:61:5:61:10 | 1e1_00 |
204+
| tst.js:62:1:62:14 | x = 0xaa_bb_cc |
205+
| tst.js:62:5:62:14 | 0xaa_bb_cc |

javascript/ql/test/library-tests/Constants/Constants.ql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@ import javascript
22

33
from ConstantExpr c
44
select c
5+
6+
query int getIntValue(Expr e) { result = e.getIntValue() }
7+
8+
query float getFloatValue(NumberLiteral e) { result = e.getFloatValue() }
9+
10+
query string getLiteralValue(Literal lit) { result = lit.getValue() }

javascript/ql/test/library-tests/Constants/tst.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,15 @@ x = 1;
4848
x.p = 1;
4949
x += 1;
5050
x += x;
51+
52+
x = 1_000;
53+
x = 1_000_123;
54+
x = 1_000_000_000;
55+
x = 101_475_938.38;
56+
x = 123_00;
57+
x = 12_300;
58+
x = 12345_00;
59+
x = 123_4500;
60+
x = 1_234_500;
61+
x = 1e1_00;
62+
x = 0xaa_bb_cc;

javascript/ql/test/library-tests/RangeAnalysis/constants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ function f() {
66
if (two > one) {} // NOT OK - always true
77
if (two <= one) {} // NOT OK - always false
88
}
9+
10+
function underscores(x) {
11+
if (x >= 1_000_000) return; // OK
12+
if (x >= 1_000) return; // OK
13+
}

0 commit comments

Comments
 (0)