mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Escaped whitespace and slashes in Heregexes
* Resolves #3059: Don't remove escaped whitespace. * Fixes #2238: Prevent escaping slashes that are already escaped. * Fix detection of end of heregex with escaped slashes.
This commit is contained in:
parent
c22707cd53
commit
91ac3fa031
3 changed files with 23 additions and 8 deletions
|
@ -275,7 +275,7 @@
|
|||
var body, flags, flagsOffset, heregex, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
|
||||
heregex = match[0], body = match[1], flags = match[2];
|
||||
if (0 > body.indexOf('#{')) {
|
||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
|
||||
re = body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/');
|
||||
if (re.match(/^\*/)) {
|
||||
this.error('regular expressions cannot begin with `*`');
|
||||
}
|
||||
|
@ -294,7 +294,7 @@
|
|||
if (tag === 'TOKENS') {
|
||||
tokens.push.apply(tokens, value);
|
||||
} else if (tag === 'NEOSTRING') {
|
||||
if (!(value = value.replace(HEREGEX_OMIT, ''))) {
|
||||
if (!(value = value.replace(HEREGEX_OMIT, '$1$2'))) {
|
||||
continue;
|
||||
}
|
||||
value = value.replace(/\\/g, '\\\\');
|
||||
|
@ -858,9 +858,9 @@
|
|||
|
||||
REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
|
||||
|
||||
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
|
||||
HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
|
||||
|
||||
HEREGEX_OMIT = /\s+(?:#.*)?/g;
|
||||
HEREGEX_OMIT = /((?:\\\\)+)|\\([^\n\S]|\/)|\s+(?:#.*)?/g;
|
||||
|
||||
MULTILINER = /\n/g;
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ exports.Lexer = class Lexer
|
|||
heregexToken: (match) ->
|
||||
[heregex, body, flags] = match
|
||||
if 0 > body.indexOf '#{'
|
||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/')
|
||||
re = body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/')
|
||||
if re.match /^\*/ then @error 'regular expressions cannot begin with `*`'
|
||||
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}", 0, heregex.length
|
||||
return heregex.length
|
||||
|
@ -267,7 +267,7 @@ exports.Lexer = class Lexer
|
|||
if tag is 'TOKENS'
|
||||
tokens.push value...
|
||||
else if tag is 'NEOSTRING'
|
||||
continue unless value = value.replace HEREGEX_OMIT, ''
|
||||
continue unless value = value.replace HEREGEX_OMIT, '$1$2'
|
||||
# Convert NEOSTRING into STRING
|
||||
value = value.replace /\\/g, '\\\\'
|
||||
token[0] = 'STRING'
|
||||
|
@ -806,9 +806,13 @@ REGEX = /// ^
|
|||
/) ([imgy]{0,4}) (?!\w)
|
||||
///
|
||||
|
||||
HEREGEX = /// ^ /{3} ([\s\S]+?) /{3} ([imgy]{0,4}) (?!\w) ///
|
||||
HEREGEX = /// ^ /{3} ((?:\\?[\s\S])+?) /{3} ([imgy]{0,4}) (?!\w) ///
|
||||
|
||||
HEREGEX_OMIT = /\s+(?:#.*)?/g
|
||||
HEREGEX_OMIT = ///
|
||||
((?:\\\\)+) # consume (and preserve) an even number of backslashes
|
||||
| \\([^\n\S]|/) # preserve escaped spaces and "de-escape" slashes
|
||||
| \s+(?:#.*)? # remove whitespace and comments
|
||||
///g
|
||||
|
||||
# Token cleaning regexes.
|
||||
MULTILINER = /\n/g
|
||||
|
|
|
@ -61,3 +61,14 @@ test "empty regular expressions with flags", ->
|
|||
a = "" + //i
|
||||
fn ""
|
||||
eq '/(?:)/i', a
|
||||
|
||||
test "#3059: don't remove escaped whitespace", ->
|
||||
eq /// One\ cannot [\ ] escape \ \destiny. ///.source,
|
||||
/One cannot[ ]escape \destiny./.source
|
||||
|
||||
test "#2238: don't escape already escaped slashes", ->
|
||||
eq /// \\\/ \/ ///.source, /\\\/\//.source
|
||||
|
||||
test "escaped slashes don't close heregex", ->
|
||||
eq /// \/// ///.source, /\/\/\//.source
|
||||
eq /// \\\////.source, /\\\//.source
|
||||
|
|
Loading…
Reference in a new issue