mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Issue #2060 Disallow uppercase radix prefixes and exponential notation
This commit is contained in:
parent
8ac440fd52
commit
34e517de09
3 changed files with 30 additions and 19 deletions
|
@ -109,19 +109,23 @@
|
|||
};
|
||||
|
||||
Lexer.prototype.numberToken = function() {
|
||||
var binaryLiteral, dec, lexedLength, match, nonStrictOctalLiteral, number, oct, octalLiteral;
|
||||
var binaryLiteral, lexedLength, match, number, octalLiteral;
|
||||
if (!(match = NUMBER.exec(this.chunk))) return 0;
|
||||
number = match[0];
|
||||
lexedLength = number.length;
|
||||
if (nonStrictOctalLiteral = /^0\d+/.test(number)) {
|
||||
dec = /[89]/.test(number) ? "\"" + number + "\" " : '';
|
||||
oct = dec ? '' : "\"" + number + "\" ";
|
||||
this.error("decimal literals " + dec + "must not be prefixed with '0'; octal literals " + oct + "must be prefixed with '0o'");
|
||||
if (/[E]/.test(number)) {
|
||||
this.error("exponential notation must be indicated with a lowercase 'e'");
|
||||
} else if (/[BOX]/.test(number)) {
|
||||
this.error("radix prefixes must be lowercase '" + number + "'");
|
||||
} else if (/^0[89]/.test(number)) {
|
||||
this.error("decimal literals '" + number + "' must not be prefixed with '0'");
|
||||
} else if (/^0[0-7]/.test(number)) {
|
||||
this.error("octal literals '" + number + "' must be prefixed with '0o'");
|
||||
}
|
||||
if (octalLiteral = /0o([0-7]+)/i.exec(number)) {
|
||||
lexedLength = number.length;
|
||||
if (octalLiteral = /0o([0-7]+)/.exec(number)) {
|
||||
number = (parseInt(octalLiteral[1], 8)).toString();
|
||||
}
|
||||
if (binaryLiteral = /0b([01]+)/i.exec(number)) {
|
||||
if (binaryLiteral = /0b([01]+)/.exec(number)) {
|
||||
number = (parseInt(binaryLiteral[1], 2)).toString();
|
||||
}
|
||||
this.token('NUMBER', number);
|
||||
|
@ -645,7 +649,7 @@
|
|||
|
||||
IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
|
||||
|
||||
NUMBER = /^0x[\da-f]+|^0b[01]+|^0o[0-7]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
|
||||
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
|
||||
|
||||
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
|
||||
|
||||
|
|
|
@ -133,14 +133,18 @@ exports.Lexer = class Lexer
|
|||
numberToken: ->
|
||||
return 0 unless match = NUMBER.exec @chunk
|
||||
number = match[0]
|
||||
if /[E]/.test number
|
||||
@error "exponential notation must be indicated with a lowercase 'e'"
|
||||
else if /[BOX]/.test number
|
||||
@error "radix prefixes must be lowercase '#{number}'"
|
||||
else if /^0[89]/.test number
|
||||
@error "decimal literals '#{number}' must not be prefixed with '0'"
|
||||
else if /^0[0-7]/.test number
|
||||
@error "octal literals '#{number}' must be prefixed with '0o'"
|
||||
lexedLength = number.length
|
||||
if nonStrictOctalLiteral = /^0\d+/.test number
|
||||
dec = if /[89]/.test number then "\"#{number}\" " else ''
|
||||
oct = if dec then '' else "\"#{number}\" "
|
||||
@error "decimal literals #{dec}must not be prefixed with '0'; octal literals #{oct}must be prefixed with '0o'"
|
||||
if octalLiteral = /0o([0-7]+)/i.exec number
|
||||
if octalLiteral = /0o([0-7]+)/.exec number
|
||||
number = (parseInt octalLiteral[1], 8).toString()
|
||||
if binaryLiteral = /0b([01]+)/i.exec number
|
||||
if binaryLiteral = /0b([01]+)/.exec number
|
||||
number = (parseInt binaryLiteral[1], 2).toString()
|
||||
@token 'NUMBER', number
|
||||
lexedLength
|
||||
|
@ -596,9 +600,9 @@ IDENTIFIER = /// ^
|
|||
///
|
||||
|
||||
NUMBER = ///
|
||||
^ 0x[\da-f]+ | # hex
|
||||
^ 0b[01]+ | # binary
|
||||
^ 0o[0-7]+ | # octal
|
||||
^ 0x[\da-f]+ | # hex
|
||||
^ \d*\.?\d+ (?:e[+-]?\d+)? # decimal
|
||||
///i
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
test "Parser recognises binary numbers", ->
|
||||
eq 4, 0b100
|
||||
eq 5, 0B101
|
||||
|
||||
# Decimal Integer Literals
|
||||
|
||||
|
@ -57,12 +56,16 @@ test '#1168: leading floating point suppresses newline', ->
|
|||
|
||||
test "Python-style octal literal notation '0o777'", ->
|
||||
eq 511, 0o777
|
||||
eq 511, 0O777
|
||||
eq 1, 0o1
|
||||
eq 1, 0O1
|
||||
eq 1, 0o00001
|
||||
eq parseInt('0777', 8), 0o777
|
||||
eq '777', 0o777.toString 8
|
||||
eq 4, 0o4.valueOf()
|
||||
eq Number::toString, 0o777['toString']
|
||||
eq Number::toString, 0o777.toString
|
||||
|
||||
test "#2060: Disallow uppercase radix prefixes and exponential notation", ->
|
||||
for char in ['b', 'o', 'x', 'e']
|
||||
program = "0#{char}0"
|
||||
doesNotThrow -> CoffeeScript.compile program, bare: yes
|
||||
throws -> CoffeeScript.compile program.toUpperCase(), bare: yes
|
||||
|
|
Loading…
Reference in a new issue