Skip to content

Commit 28a28a0

Browse files
committed
fix: enforce underscore separator restrictions in hex, binary, and octal literals
1 parent ba16a39 commit 28a28a0

3 files changed

Lines changed: 418 additions & 30 deletions

File tree

src/lexer/numbers.js

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,22 @@ module.exports = {
2323
if (ch === "x" || ch === "X") {
2424
ch = this.input();
2525
if (ch !== "_" && this.is_HEX()) {
26-
return this.consume_HNUM();
26+
return this.consume_hexadecimal();
2727
} else {
2828
this.unput(ch ? 2 : 1);
2929
}
3030
// check binary notation
3131
} else if (ch === "b" || ch === "B") {
3232
ch = this.input();
3333
if ((ch !== "_" && ch === "0") || ch === "1") {
34-
return this.consume_BNUM();
34+
return this.consume_binary();
3535
} else {
3636
this.unput(ch ? 2 : 1);
3737
}
3838
} else if (ch === "o" || ch === "O") {
3939
ch = this.input();
4040
if (ch !== "_" && this.is_OCTAL()) {
41-
return this.consume_ONUM();
41+
return this.consume_octal();
4242
} else {
4343
this.unput(ch ? 2 : 1);
4444
}
@@ -94,7 +94,7 @@ module.exports = {
9494
ch = this.input();
9595
}
9696
if (this.is_NUM_START()) {
97-
this.consume_LNUM();
97+
this.consume_decimal_digits();
9898
return this.tok.T_DNUMBER;
9999
}
100100
this.unput(ch ? undo : undo - 1); // keep only 1
@@ -123,49 +123,43 @@ module.exports = {
123123
return this.tok.T_DNUMBER;
124124
}
125125
},
126-
// read hexa
127-
consume_HNUM() {
126+
consume_prefixed_digits(isValid) {
127+
let prev = this._input[this.offset - 1];
128128
while (this.offset < this.size) {
129129
const ch = this.input();
130-
if (!this.is_HEX()) {
130+
if (!isValid.call(this)) {
131131
if (ch) this.unput(1);
132132
break;
133133
}
134-
}
135-
return this.tok.T_LNUMBER;
136-
},
137-
// read a generic number
138-
consume_LNUM() {
139-
while (this.offset < this.size) {
140-
const ch = this.input();
141-
if (!this.is_NUM()) {
142-
if (ch) this.unput(1);
134+
if (ch === "_" && prev === "_") {
135+
this.unput(2);
143136
break;
144137
}
138+
prev = ch;
145139
}
140+
if (prev === "_") this.unput(1);
146141
return this.tok.T_LNUMBER;
147142
},
148-
// read binary
149-
consume_BNUM() {
150-
let ch;
151-
while (this.offset < this.size) {
152-
ch = this.input();
153-
if (ch !== "0" && ch !== "1" && ch !== "_") {
154-
if (ch) this.unput(1);
155-
break;
156-
}
157-
}
158-
return this.tok.T_LNUMBER;
143+
consume_hexadecimal() {
144+
return this.consume_prefixed_digits(this.is_HEX);
159145
},
160-
// read an octal number
161-
consume_ONUM() {
146+
consume_decimal_digits() {
162147
while (this.offset < this.size) {
163148
const ch = this.input();
164-
if (!this.is_OCTAL()) {
149+
if (!this.is_NUM()) {
165150
if (ch) this.unput(1);
166151
break;
167152
}
168153
}
169154
return this.tok.T_LNUMBER;
170155
},
156+
consume_binary() {
157+
return this.consume_prefixed_digits(function () {
158+
const ch = this._input[this.offset - 1];
159+
return ch === "0" || ch === "1" || ch === "_";
160+
});
161+
},
162+
consume_octal() {
163+
return this.consume_prefixed_digits(this.is_OCTAL);
164+
},
171165
};

0 commit comments

Comments
 (0)