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; + } }
