11var utils = require ( './utils' ) ,
2- stringSaveRE = / " (?: [ ^ " \\ ] | \\ .) * " | ' (?: [ ^ ' \\ ] | \\ .) * ' / g,
3- stringRestoreRE = / " ( \d + ) " / g,
4- constructorRE = new RegExp ( 'constructor' . split ( '' ) . join ( '[\'"+, ]*' ) ) ,
5- unicodeRE = / \\ u \d \d \d \d /
2+ STR_SAVE_RE = / " (?: [ ^ " \\ ] | \\ .) * " | ' (?: [ ^ ' \\ ] | \\ .) * ' / g,
3+ STR_RESTORE_RE = / " ( \d + ) " / g,
4+ CTOR_RE = new RegExp ( 'constructor' . split ( '' ) . join ( '[\'"+, ]*' ) ) ,
5+ UNICODE_RE = / \\ u \d \d \d \d / ,
6+ QUOTE_RE = / " / g
67
78// Variable extraction scooped from https://github.com/RubyLouvre/avalon
89
@@ -94,7 +95,7 @@ function makeGetter (exp, raw) {
9495 try {
9596 fn = new Function ( exp )
9697 } catch ( e ) {
97- utils . warn ( 'Invalid expression: ' + raw )
98+ utils . warn ( 'Error parsing expression: ' + raw )
9899 }
99100 return fn
100101}
@@ -108,14 +109,24 @@ function escapeDollar (v) {
108109 : v
109110}
110111
112+ /**
113+ * Convert double quotes to single quotes
114+ * so they don't mess up the generated function body
115+ */
116+ function escapeQuote ( v ) {
117+ return v . indexOf ( '"' ) > - 1
118+ ? v . replace ( QUOTE_RE , '\'' )
119+ : v
120+ }
121+
111122/**
112123 * Parse and return an anonymous computed property getter function
113124 * from an arbitrary expression, together with a list of paths to be
114125 * created as bindings.
115126 */
116127exports . parse = function ( exp , compiler , data , filters ) {
117128 // unicode and 'constructor' are not allowed for XSS security.
118- if ( unicodeRE . test ( exp ) || constructorRE . test ( exp ) ) {
129+ if ( UNICODE_RE . test ( exp ) || CTOR_RE . test ( exp ) ) {
119130 utils . warn ( 'Unsafe expression: ' + exp )
120131 return
121132 }
@@ -138,15 +149,15 @@ exports.parse = function (exp, compiler, data, filters) {
138149 ")[$\\w\\.]*\\b" , 'g'
139150 ) ,
140151 body = ( ' ' + exp )
141- . replace ( stringSaveRE , saveStrings )
152+ . replace ( STR_SAVE_RE , saveStrings )
142153 . replace ( pathRE , replacePath )
143- . replace ( stringRestoreRE , restoreStrings )
154+ . replace ( STR_RESTORE_RE , restoreStrings )
144155
145156 // wrap expression with computed filters
146157 if ( filters ) {
147158 filters . forEach ( function ( filter ) {
148159 var args = filter . args
149- ? ',"' + filter . args . join ( '","' ) + '"'
160+ ? ',"' + filter . args . map ( escapeQuote ) . join ( '","' ) + '"'
150161 : ''
151162 body =
152163 'this.$compiler.getOption("filters", "' +
0 commit comments