Ver código fonte

fix char escape in expressions (fix #1929)

Evan You 10 anos atrás
pai
commit
5710bc2714

+ 4 - 3
src/parsers/directive.js

@@ -10,7 +10,7 @@ const reservedArgRE = /^in$|^-?\d+/
  */
 
 var str, dir
-var c, i, l, lastFilterIndex
+var c, prev, i, l, lastFilterIndex
 var inSingle, inDouble, curly, square, paren
 
 /**
@@ -90,13 +90,14 @@ export function parseDirective (s) {
   dir = {}
 
   for (i = 0, l = str.length; i < l; i++) {
+    prev = c
     c = str.charCodeAt(i)
     if (inSingle) {
       // check single quote
-      if (c === 0x27) inSingle = !inSingle
+      if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle
     } else if (inDouble) {
       // check double quote
-      if (c === 0x22) inDouble = !inDouble
+      if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble
     } else if (
       c === 0x7C && // pipe
       str.charCodeAt(i + 1) !== 0x7C &&

+ 4 - 4
src/parsers/expression.js

@@ -23,11 +23,11 @@ const improperKeywordsRE =
 
 const wsRE = /\s/g
 const newlineRE = /\n/g
-const saveRE = /[\{,]\s*[\w\$_]+\s*:|('[^']*'|"[^"]*")|new |typeof |void /g
+const saveRE = /[\{,]\s*[\w\$_]+\s*:|('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")|new |typeof |void /g
 const restoreRE = /"(\d+)"/g
-const pathTestRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/
-const pathReplaceRE = /[^\w$\.]([A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\])*)/g
-const booleanLiteralRE = /^(true|false)$/
+const pathTestRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/
+const pathReplaceRE = /[^\w$\.](?:[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\])*)/g
+const booleanLiteralRE = /^(?:true|false)$/
 
 /**
  * Save / Rewrite / Restore

+ 8 - 0
test/unit/specs/parsers/directive_spec.js

@@ -78,6 +78,14 @@ describe('Directive Parser', function () {
     expect(res.filters[0].args).toBeUndefined()
   })
 
+  it('escape string', function () {
+    var res = parse("'a\\'b' | test")
+    expect(res.expression).toBe("'a\\'b'")
+    expect(res.filters.length).toBe(1)
+    expect(res.filters[0].name).toBe('test')
+    expect(res.filters[0].args).toBeUndefined()
+  })
+
   it('cache', function () {
     var res1 = parse('a || b | c')
     var res2 = parse('a || b | c')

+ 9 - 0
test/unit/specs/parsers/expression_spec.js

@@ -172,6 +172,15 @@ var testCases = [
     expected: 8,
     paths: ['$a', 'b', 'c', 'e']
   },
+  {
+    // string with escaped quotes
+    exp: "'a\\'b' + c",
+    scope: {
+      c: '\'c'
+    },
+    expected: "a\'b\'c",
+    paths: ['c']
+  },
   {
     // Math global, simple path
     exp: 'Math.PI',