BorisMoore / jsrender

A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.
http://www.jsviews.com
MIT License
2.67k stars 339 forks source link

non-standard regex problem #302

Closed enexusde closed 8 years ago

enexusde commented 8 years ago

Use canoo webtest

<dependency>
    <groupId>com.canoo.webtest</groupId>
    <artifactId>webtest</artifactId>
    <version>3.0</version>
    <scope>test</scope>
</dependency>

Results in

Exception in thread "HtmlUnit Managed Thread #83 for WebWindow : XMLHttpRequest.send" java.lang.IllegalArgumentException: Illegal group reference
    at java.util.regex.Matcher.appendReplacement(Matcher.java:857)
    at java.util.regex.Matcher.replaceAll(Matcher.java:955)
    at com.gargoylesoftware.htmlunit.javascript.regexp.HtmlUnitRegExpProxy.action(HtmlUnitRegExpProxy.java:75)
    at org.mozilla.javascript.NativeString.execIdCall(NativeString.java:380)
    at org.mozilla.javascript.IdFunctionObject.call(IdFunctionObject.java:129)
    at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3330)
    at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
    at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
    at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:398)
    at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:192)
    at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3065)
    at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:162)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:472)
    at com.gargoylesoftware.htmlunit.javascript.host.XMLHttpRequest.setState(XMLHttpRequest.java:142)
    at com.gargoylesoftware.htmlunit.javascript.host.XMLHttpRequest.doSend(XMLHttpRequest.java:413)
    at com.gargoylesoftware.htmlunit.javascript.host.XMLHttpRequest.access$000(XMLHttpRequest.java:54)
    at com.gargoylesoftware.htmlunit.javascript.host.XMLHttpRequest$1.run(XMLHttpRequest.java:361)
    at org.mozilla.javascript.Context.call(Context.java:515)
    at org.mozilla.javascript.ContextFactory.call(ContextFactory.java:507)
    at com.gargoylesoftware.htmlunit.javascript.host.XMLHttpRequest$2.run(XMLHttpRequest.java:367)
    at java.lang.Thread.run(Thread.java:745)
    at com.gargoylesoftware.htmlunit.ThreadManager$1.run(ThreadManager.java:116)
enexusde commented 8 years ago

By the way, the target of the replace-function is random but the value is \\$& i guess it is this line:

        // Compile to AST and then to compiled function
        tmplFn(tmplOrMarkup.replace(rEscapeQuotes, "\\$&"), tmpl);

I think it is a bug because

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch

sais its non-standard to use $&

BorisMoore commented 8 years ago

The MDN article you link to is for the non-standard RegEx.lastMatch() API, which is a programmatic way of accessing the last match. But JsRender is not using that API.

In fact JsRender is using "$&" as a replacement pattern in a replacement string, in the someString.replace(regex, replacementstring) call - which is standard usage in JavaScript RegEx scenarios.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace, where it says:

The replacement string can include the following special replacement patterns: ... $& Inserts the matched substring.

The regex in that line of code is rEscapeQuotes, which is declared as rEscapeQuotes = /['"\\]/g - and is a valid JavaScript regex.

That line is looking for ' " or\ and replacing them with the same character preceded by \.

Incidentally you should not be trying to run the same regex expressions used in JsRender as if they were Java regex expressions, since in Java the rules and validity of regex expressions can be quite different. JsRender of course runs in a JavaScript environment - the browser, or Node.js on the server...

Closing this, since it does not appear to me to be a JsRender bug.

enexusde commented 8 years ago

For your information, i created a bug-report at https://bugs.openjdk.java.net/browse/JDK-8162831 for supporting $& in regex.