Repository: juneau
Updated Branches:
  refs/heads/master fcdf5fe19 -> 80da4f69d


Add ability to restrict when SVL vars are recursively resolved.

Project: http://git-wip-us.apache.org/repos/asf/juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/juneau/commit/80da4f69
Tree: http://git-wip-us.apache.org/repos/asf/juneau/tree/80da4f69
Diff: http://git-wip-us.apache.org/repos/asf/juneau/diff/80da4f69

Branch: refs/heads/master
Commit: 80da4f69d4857d0d49c05ae5f5333466648971be
Parents: fcdf5fe
Author: JamesBognar <[email protected]>
Authored: Tue Nov 7 21:26:24 2017 -0800
Committer: JamesBognar <[email protected]>
Committed: Tue Nov 7 21:26:24 2017 -0800

----------------------------------------------------------------------
 .../juneau/svl/vars/RestrictedVarsTest.java     | 125 +++++++++++++++++++
 juneau-core/juneau-marshall/TODO.txt            |   4 +-
 .../main/java/org/apache/juneau/svl/Var.java    |  39 ++++++
 .../apache/juneau/svl/VarResolverSession.java   |   6 +-
 juneau-doc/src/main/javadoc/overview.html       |  18 +++
 .../apache/juneau/rest/test/PropertiesTest.java |   2 +-
 .../org/apache/juneau/rest/vars/RequestVar.java |  10 ++
 .../rest/vars/SerializedRequestAttrVar.java     |  10 ++
 8 files changed, 209 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/RestrictedVarsTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/RestrictedVarsTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/RestrictedVarsTest.java
new file mode 100644
index 0000000..4b4f834
--- /dev/null
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/RestrictedVarsTest.java
@@ -0,0 +1,125 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                
                                              * 
+// *                                                                           
                                              *
+// *  http://www.apache.org/licenses/LICENSE-2.0                               
                                              *
+// *                                                                           
                                              *
+// * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the 
License.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.svl.vars;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+
+import org.apache.juneau.svl.*;
+import org.junit.*;
+
+public class RestrictedVarsTest {
+
+       @Test
+       public void testNoNest() throws Exception {
+               VarResolver vr = new 
VarResolverBuilder().vars(NoNestVar.class).build();
+               
+               test(vr, "$NoNest{foo}", "foo");
+               test(vr, "$NoNest{$NoNest{foo}}", "$NoNest{foo}");
+               test(vr, "$NoNest{foo $NoNest{foo} bar}", "foo $NoNest{foo} 
bar");
+       }
+
+       public static class XVar extends SimpleVar {
+
+               public XVar() {
+                       super("X");
+               }
+
+               @Override
+               public String resolve(VarResolverSession session, String arg) 
throws Exception {
+                       return 'x' + arg + 'x';
+               }
+       }
+       
+       public static class NoNestVar extends SimpleVar {
+
+               public NoNestVar() {
+                       super("NoNest");
+               }
+
+               @Override
+               public String resolve(VarResolverSession session, String arg) 
throws Exception {
+                       return arg.replaceAll("\\$", "\\\\\\$");
+               }
+               
+               @Override 
+               protected boolean allowNested() {
+                       return false;
+               }
+       }
+
+       @Test
+       public void testNoRecurse() throws Exception {
+               VarResolver vr = new VarResolverBuilder().vars(XVar.class, 
NoRecurseVar.class).build();
+               
+               test(vr, "$NoRecurse{foo}", "$X{foo}");
+               test(vr, "$NoRecurse{$NoRecurse{foo}}", "$X{$X{foo}}");
+               test(vr, "$NoRecurse{foo $NoRecurse{foo} bar}", "$X{foo $X{foo} 
bar}");
+       }
+               
+       public static class NoRecurseVar extends SimpleVar {
+
+               public NoRecurseVar() {
+                       super("NoRecurse");
+               }
+
+               @Override
+               public String resolve(VarResolverSession session, String arg) 
throws Exception {
+                       return "$X{"+arg+"}";
+               }
+               
+               @Override 
+               protected boolean allowRecurse() {
+                       return false;
+               }
+       }
+
+       @Test
+       public void testNoNestOrRecurse() throws Exception {
+               VarResolver vr = new VarResolverBuilder().vars(XVar.class, 
NoEitherVar.class).build();
+               
+               test(vr, "$NoEither{foo}", "$X{foo}");
+               test(vr, "$NoEither{$NoEither{foo}}", "$X{$NoEither{foo}}");
+               test(vr, "$NoEither{foo $NoEither{foo} bar}", "$X{foo 
$NoEither{foo} bar}");
+       }
+       
+       public static class NoEitherVar extends SimpleVar {
+
+               public NoEitherVar() {
+                       super("NoEither");
+               }
+
+               @Override
+               public String resolve(VarResolverSession session, String arg) 
throws Exception {
+                       return "$X{" + arg + "}";
+               }
+               
+               @Override 
+               protected boolean allowNested() {
+                       return false;
+               }
+
+               @Override 
+               protected boolean allowRecurse() {
+                       return false;
+               }
+       }
+
+       private void test(VarResolver vr, String s, String expected) throws 
IOException {
+               StringWriter sw = new StringWriter();
+               vr.resolveTo(s, sw);
+               assertEquals(expected, sw.toString());
+               assertEquals(expected, vr.resolve(s));
+       }
+}

http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-core/juneau-marshall/TODO.txt
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/TODO.txt 
b/juneau-core/juneau-marshall/TODO.txt
index 74520e5..a3175a2 100644
--- a/juneau-core/juneau-marshall/TODO.txt
+++ b/juneau-core/juneau-marshall/TODO.txt
@@ -11,4 +11,6 @@
 * specific language governing permissions and limitations under the License.   
                                           *
 
***************************************************************************************************************************
 
-Create tests that ensure serializers don't close output but parsers do close 
input.
\ No newline at end of file
+Create tests that ensure serializers don't close output but parsers do close 
input.
+Injectable beans.
+Add create() methods to serializer and parser classes.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java 
b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java
index 3530e04..80434ca 100644
--- a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java
+++ b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java
@@ -84,6 +84,45 @@ public abstract class Var {
        protected String getName() {
                return name;
        }
+       
+       /**
+        * Returns whether nested variables are supported by this variable.
+        * 
+        * <p>
+        * For example, in <js>"$X{$Y{xxx}}"</js>, $Y is a nested variable that 
will be resolved if this method returns
+        * <jk>true</jk>.
+        * 
+        * <p>
+        * The default implementation of this method always returns 
<jk>true</jk>.  
+        * Subclasses can override this method to override the default behavior.
+        * 
+        * @return <jk>true</jk> if nested variables are supported by this 
variable.
+        */
+       protected boolean allowNested() {
+               return true;
+       }
+       
+       /**
+        * Returns whether variables in the resolved contents of this variable 
should also be resolved.
+        * 
+        * <p>
+        * For example, if <js>"$X{xxx}"</js> resolves to <js>"$Y{xxx}"<js>, 
then the $Y variable will be recursively
+        * resolved if this method returns <jk>true</jk>.
+        * 
+        * <p>
+        * The default implementation of this method always returns 
<jk>true</jk>.  
+        * Subclasses can override this method to override the default behavior.
+        * 
+        * <h6 class='topic'>Important Note</h6>
+        * <p>
+        * As a general rule, variables that resolve user-entered data should 
not be recursively resolved as this may 
+        * cause a security hole.
+        * 
+        * @return <jk>true</jk> if resolved variables should be recursively 
resolved.
+        */
+       protected boolean allowRecurse() {
+               return true;
+       }
 
        /**
         * The method called from {@link VarResolver}.

http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
 
b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
index 65b847b..bbc6ffc 100644
--- 
a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
+++ 
b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
@@ -102,7 +102,7 @@ public class VarResolverSession {
                                        s = v.doResolve(this, val);
                                        if (s == null)
                                                s = "";
-                                       return resolve(s);
+                                       return (v.allowRecurse() ? resolve(s) : 
s);
                                } catch (Exception e) {
                                        return '{' + e.getLocalizedMessage() + 
'}';
                                }
@@ -320,7 +320,6 @@ public class VarResolverSession {
                                                depth--;
                                        } else {
                                                varVal = s.substring(x+1, i);
-                                               varVal = (hasInternalVar ? 
resolve(varVal) : varVal);
                                                Var r = getVar(varType);
                                                if (r == null) {
                                                        if (hasInnerEscapes)
@@ -329,6 +328,7 @@ public class VarResolverSession {
                                                                out.append(s, 
x2, i+1);
                                                        x = i+1;
                                                } else {
+                                                       varVal = 
(hasInternalVar && r.allowNested() ? resolve(varVal) : varVal);
                                                        try {
                                                                if (r.streamed)
                                                                        
r.resolveTo(this, out, varVal);
@@ -337,7 +337,7 @@ public class VarResolverSession {
                                                                        if 
(replacement == null)
                                                                                
replacement = "";
                                                                        // If 
the replacement also contains variables, replace them now.
-                                                                       if 
(replacement.indexOf('$') != -1)
+                                                                       if 
(replacement.indexOf('$') != -1 && r.allowRecurse())
                                                                                
replacement = resolve(replacement);
                                                                        
out.append(replacement);
                                                                }

http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-doc/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-doc/src/main/javadoc/overview.html 
b/juneau-doc/src/main/javadoc/overview.html
index f98ab84..08ec4f2 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -7374,6 +7374,7 @@
        
        <h5 class='toc'>What's new in each release</h5>
        <ul class='toc'>
+               <li><p><a class='doclink' href='#7.0.1'>7.0.1 (TBD)</a></p>
                <li><p><a class='doclink' href='#7.0.0'>7.0.0 (Oct 25, 
2017)</a></p>
                <li><p><a class='doclink' href='#6.4.0'>6.4.0 (Oct 5, 
2017)</a></p>
                <li><p><a class='doclink' href='#6.3.1'>6.3.1 (Aug 1, 
2017)</a></p>
@@ -7445,6 +7446,23 @@
        </ul>
 
        <!-- 
===========================================================================================================
 -->
+       <a id="7.0.1"></a>
+       <h3 class='topic' onclick='toggle(this)'>7.0.1 (TBD)</h3>
+       <div class='topic'>
+       
+               <h6 class='topic'>juneau-svl</h6>
+               <ul class='spaced-list'>
+                       <li>New methods on {@link org.apache.juneau.svl.Var} 
class to restrict when nested and embedded variables
+                       are resolved.
+                               <ul>
+                                       <li>{@link 
org.apache.juneau.svl.Var.allowNested}
+                                       <li>{@link 
org.apache.juneau.svl.Var.allowRecurse}
+                               </ul>
+               </ul>
+
+       </div>
+       
+       <!-- 
===========================================================================================================
 -->
        <a id="7.0.0"></a>
        <h3 class='topic' onclick='toggle(this)'>7.0.0 (Oct 25, 2017)</h3>
        <div class='topic'>

http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
index 96cbfb4..e34b382 100644
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
+++ 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
@@ -28,6 +28,6 @@ public class PropertiesTest extends RestTestcase {
        public void testPropertiesDefinedOnMethod() throws Exception {
                RestClient client = TestMicroservice.DEFAULT_CLIENT;
                String r = client.doGet(URL + 
"/testPropertiesDefinedOnMethod").getResponseAsString();
-               
assertTrue(r.matches("A1=a1,A2=c,B1=b1,B2=c,C=c,R1a=.*/testProperties/testPropertiesDefinedOnMethod,R1b=.*/testProperties,R2=bar,R3=baz,R4=a1,R5=c,R6=c"));
+               
assertTrue(r.matches("A1=a1,A2=c,B1=b1,B2=c,C=c,R1a=.*/testProperties/testPropertiesDefinedOnMethod,R1b=.*/testProperties,R2=bar,R3=,R4=a1,R5=c,R6=c"));
        }
 }

http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
index a90d28d..878bcad 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
@@ -73,6 +73,16 @@ public class RequestVar extends DefaultingVar {
        public RequestVar() {
                super(NAME);
        }
+       
+       @Override /* Var */
+       protected boolean allowNested() {
+               return false;
+       }
+
+       @Override /* Var */
+       protected boolean allowRecurse() {
+               return false;
+       }
 
        @Override /* Parameter */
        public String resolve(VarResolverSession session, String key) {

http://git-wip-us.apache.org/repos/asf/juneau/blob/80da4f69/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
index e7ef586..f124d9c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
@@ -64,4 +64,14 @@ public class SerializedRequestAttrVar extends StreamedVar {
                                s.serialize(w, o);
                }
        }
+       
+       @Override  /* Var */
+       protected boolean allowNested() {
+               return false;
+       }
+
+       @Override  /* Var */
+       protected boolean allowRecurse() {
+               return false;
+       }
 }

Reply via email to