[ 
https://issues.apache.org/jira/browse/VELOCITY-896?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16621253#comment-16621253
 ] 

Stephen Bolton commented on VELOCITY-896:
-----------------------------------------

I came on here to check this exact issue I was seeing with # and $ and this is 
the first issue I see.  I have some more info on the scope and cause of this 
issue.  In a set the contents when using double quotes is treated as its own 
velocity template.   This same issue occurs actually with any template that the 
last character is a $ or a #.   

The problem is related to this from 
[https://javacc.org/tutorials/tokenmanager|http://example.com]

"Whenever the end of file <EOF> is detected, it causes the creation of an <EOF> 
token (regardless of the current state of the lexical analyzer). However, if an 
<EOF> is detected in the middle of a match for a regular expression, or 
immediately after a MORE regular expression has been matched, an error is 
reported."

 

in Parser.jjt  we handle <HASH : "#" > as a MORE.  In this case it will always 
look ahead on the stream if it sees the # or $ and will fail when there are no 
more characters due to the stream already being closed.  I have been looking 
more at JavaCC to see how this could be resolved and have experimented with a 
separate token that matches #<EOF> explicitly then treating that as text so it 
then never attempts to hit this case as a MORE.  

Not sure if anyone who has more experience on JavaCC wants to take this on or 
collaborate on a fix

> Regression in the handling of String literal ending with a sharp sign
> ---------------------------------------------------------------------
>
>                 Key: VELOCITY-896
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-896
>             Project: Velocity
>          Issue Type: Bug
>    Affects Versions: 2.0
>            Reporter: Thomas Mortagne
>            Priority: Blocker
>
> The following produce a ParseErrorException after upgrading to Velocity 2:
> {code}
> #set($var = "#")
> {code}
> or 
> {code}
> #set($var = "toto#")
> {code}
> {noformat}
> org.xwiki.velocity.XWikiVelocityException: Failed to evaluate content with id 
> [mytemplate]
>       at 
> org.xwiki.velocity.internal.DefaultVelocityEngine.evaluate(DefaultVelocityEngine.java:279)
>       at 
> org.xwiki.velocity.internal.DefaultVelocityEngine.evaluate(DefaultVelocityEngine.java:244)
>       at 
> org.xwiki.velocity.internal.DefaultVelocityEngineTest.assertEvaluate(DefaultVelocityEngineTest.java:92)
>       at 
> org.xwiki.velocity.internal.DefaultVelocityEngineTest.assertEvaluate(DefaultVelocityEngineTest.java:85)
>       at 
> org.xwiki.velocity.internal.DefaultVelocityEngineTest.testMisc(DefaultVelocityEngineTest.java:287)
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.lang.reflect.Method.invoke(Method.java:498)
>       at 
> org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:436)
>       at 
> org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
>       at 
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
>       at 
> org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
>       at 
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
>       at 
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
>       at 
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:112)
>       at 
> org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
>       at 
> java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
>       at 
> java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
>       at java.util.Iterator.forEachRemaining(Iterator.java:116)
>       at 
> java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
>       at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
>       at 
> java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
>       at 
> java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
>       at 
> java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
>       at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
>       at 
> java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
>       at 
> org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
>       at 
> java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
>       at 
> java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
>       at java.util.Iterator.forEachRemaining(Iterator.java:116)
>       at 
> java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
>       at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
>       at 
> java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
>       at 
> java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
>       at 
> java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
>       at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
>       at 
> java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
>       at 
> org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
>       at 
> org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
>       at 
> org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
>       at 
> org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
>       at 
> org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
>       at 
> org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:86)
>       at 
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
> Caused by: org.apache.velocity.exception.ParseErrorException: Failed to parse 
> String literal at mytemplate[line 1, column 13]
>       at org.apache.velocity.Template.process(Template.java:160)
>       at 
> org.xwiki.velocity.internal.DefaultVelocityEngine.evaluate(DefaultVelocityEngine.java:268)
>       ... 60 more
> {noformat}
> Note: I agree that it would make more sense to use {{'#'}} in this code but 
> my concern is more undocumented regression and in some cases you do need to 
> need to interpret a string and also end it with #.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@velocity.apache.org
For additional commands, e-mail: dev-h...@velocity.apache.org

Reply via email to