Browse Source

Escape vertical tab as "\v", not "\x0B"

See #441.
redux
David Majda 5 years ago
parent
commit
9c04c94c85
  1. 12
      examples/javascript.pegjs
  2. 25
      lib/compiler/js.js
  3. 16
      lib/parser.js
  4. 20
      spec/unit/parser.spec.js
  5. 12
      src/parser.pegjs

12
examples/javascript.pegjs

@ -307,12 +307,12 @@ SingleEscapeCharacter
= "'"
/ '"'
/ "\\"
/ "b" { return "\b"; }
/ "f" { return "\f"; }
/ "n" { return "\n"; }
/ "r" { return "\r"; }
/ "t" { return "\t"; }
/ "v" { return "\x0B"; } // IE does not recognize "\v".
/ "b" { return "\b"; }
/ "f" { return "\f"; }
/ "n" { return "\n"; }
/ "r" { return "\r"; }
/ "t" { return "\t"; }
/ "v" { return "\v"; }
NonEscapeCharacter
= !(EscapeCharacter / LineTerminator) SourceCharacter { return text(); }

25
lib/compiler/js.js

@ -12,8 +12,6 @@ var js = {
* may appear in the form of an escape sequence.
*
* For portability, we also escape all control and non-ASCII characters.
* Note that the "\v" escape sequence is not used because IE does not like
* it.
*/
return s
.replace(/\\/g, '\\\\') // backslash
@ -22,6 +20,7 @@ var js = {
.replace(/\x08/g, '\\b') // backspace
.replace(/\t/g, '\\t') // horizontal tab
.replace(/\n/g, '\\n') // line feed
.replace(/\v/g, '\\v') // vertical tab
.replace(/\f/g, '\\f') // form feed
.replace(/\r/g, '\\r') // carriage return
.replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
@ -37,17 +36,17 @@ var js = {
* For portability, we also escape all control and non-ASCII characters.
*/
return s
.replace(/\\/g, '\\\\') // backslash
.replace(/\//g, '\\/') // closing slash
.replace(/\]/g, '\\]') // closing bracket
.replace(/\^/g, '\\^') // caret
.replace(/-/g, '\\-') // dash
.replace(/\0/g, '\\0') // null
.replace(/\t/g, '\\t') // horizontal tab
.replace(/\n/g, '\\n') // line feed
.replace(/\v/g, '\\x0B') // vertical tab
.replace(/\f/g, '\\f') // form feed
.replace(/\r/g, '\\r') // carriage return
.replace(/\\/g, '\\\\') // backslash
.replace(/\//g, '\\/') // closing slash
.replace(/\]/g, '\\]') // closing bracket
.replace(/\^/g, '\\^') // caret
.replace(/-/g, '\\-') // dash
.replace(/\0/g, '\\0') // null
.replace(/\t/g, '\\t') // horizontal tab
.replace(/\n/g, '\\n') // line feed
.replace(/\v/g, '\\v') // vertical tab
.replace(/\f/g, '\\f') // form feed
.replace(/\r/g, '\\r') // carriage return
.replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x7F-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
.replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })

16
lib/parser.js

@ -260,8 +260,8 @@ function peg$parse(input, options) {
peg$c35 = peg$otherExpectation("whitespace"),
peg$c36 = "\t",
peg$c37 = peg$literalExpectation("\t", false),
peg$c38 = "\x0B",
peg$c39 = peg$literalExpectation("\x0B", false),
peg$c38 = "\v",
peg$c39 = peg$literalExpectation("\v", false),
peg$c40 = "\f",
peg$c41 = peg$literalExpectation("\f", false),
peg$c42 = " ",
@ -353,22 +353,22 @@ function peg$parse(input, options) {
peg$c105 = function() { return "\0"; },
peg$c106 = "b",
peg$c107 = peg$literalExpectation("b", false),
peg$c108 = function() { return "\b"; },
peg$c108 = function() { return "\b"; },
peg$c109 = "f",
peg$c110 = peg$literalExpectation("f", false),
peg$c111 = function() { return "\f"; },
peg$c111 = function() { return "\f"; },
peg$c112 = "n",
peg$c113 = peg$literalExpectation("n", false),
peg$c114 = function() { return "\n"; },
peg$c114 = function() { return "\n"; },
peg$c115 = "r",
peg$c116 = peg$literalExpectation("r", false),
peg$c117 = function() { return "\r"; },
peg$c117 = function() { return "\r"; },
peg$c118 = "t",
peg$c119 = peg$literalExpectation("t", false),
peg$c120 = function() { return "\t"; },
peg$c120 = function() { return "\t"; },
peg$c121 = "v",
peg$c122 = peg$literalExpectation("v", false),
peg$c123 = function() { return "\x0B"; },
peg$c123 = function() { return "\v"; },
peg$c124 = "x",
peg$c125 = peg$literalExpectation("x", false),
peg$c126 = "u",

20
spec/unit/parser.spec.js

@ -384,7 +384,7 @@ describe("PEG.js grammar parser", function() {
/* Canonical WhiteSpace is " ". */
it("parses WhiteSpace", function() {
expect('start =\t"abcd"' ).toParseAs(trivialGrammar);
expect('start =\x0B"abcd"' ).toParseAs(trivialGrammar); // no "\v" in IE
expect('start =\v"abcd"' ).toParseAs(trivialGrammar);
expect('start =\f"abcd"' ).toParseAs(trivialGrammar);
expect('start = "abcd"' ).toParseAs(trivialGrammar);
expect('start =\u00A0"abcd"').toParseAs(trivialGrammar);
@ -588,15 +588,15 @@ describe("PEG.js grammar parser", function() {
/* Canonical SingleEscapeCharacter is "n". */
it("parses SingleEscapeCharacter", function() {
expect('start = "\\\'"').toParseAs(literalGrammar("'", false));
expect('start = "\\""' ).toParseAs(literalGrammar('"', false));
expect('start = "\\\\"').toParseAs(literalGrammar("\\", false));
expect('start = "\\b"' ).toParseAs(literalGrammar("\b", false));
expect('start = "\\f"' ).toParseAs(literalGrammar("\f", false));
expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false));
expect('start = "\\r"' ).toParseAs(literalGrammar("\r", false));
expect('start = "\\t"' ).toParseAs(literalGrammar("\t", false));
expect('start = "\\v"' ).toParseAs(literalGrammar("\x0B", false)); // no "\v" in IE
expect('start = "\\\'"').toParseAs(literalGrammar("'", false));
expect('start = "\\""' ).toParseAs(literalGrammar('"', false));
expect('start = "\\\\"').toParseAs(literalGrammar("\\", false));
expect('start = "\\b"' ).toParseAs(literalGrammar("\b", false));
expect('start = "\\f"' ).toParseAs(literalGrammar("\f", false));
expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false));
expect('start = "\\r"' ).toParseAs(literalGrammar("\r", false));
expect('start = "\\t"' ).toParseAs(literalGrammar("\t", false));
expect('start = "\\v"' ).toParseAs(literalGrammar("\v", false));
});
/* Canonical NonEscapeCharacter is "a". */

12
src/parser.pegjs

@ -404,12 +404,12 @@ SingleEscapeCharacter
= "'"
/ '"'
/ "\\"
/ "b" { return "\b"; }
/ "f" { return "\f"; }
/ "n" { return "\n"; }
/ "r" { return "\r"; }
/ "t" { return "\t"; }
/ "v" { return "\x0B"; } // IE does not recognize "\v".
/ "b" { return "\b"; }
/ "f" { return "\f"; }
/ "n" { return "\n"; }
/ "r" { return "\r"; }
/ "t" { return "\t"; }
/ "v" { return "\v"; }
NonEscapeCharacter
= !(EscapeCharacter / LineTerminator) SourceCharacter { return text(); }

Loading…
Cancel
Save