jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [05/19] jena git commit: ARQ:Query:ParameterizedSparqlString - "validateValuesSafeToInject" method now performed when applying the values. The variables which will be used in the substitution are identified then each variable is checked against the relev
Date Sun, 05 Aug 2018 15:33:30 GMT
ARQ:Query:ParameterizedSparqlString - "validateValuesSafeToInject" method now performed when
applying the values. The variables which will be used in the substitution are identified then
each variable is checked against the relevant item.

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

Branch: refs/heads/master
Commit: a5f18c3d468a703954de464887b699e4ca95822a
Parents: 93c6780
Author: Greg Albiston <greg_albiston@hotmail.com>
Authored: Mon Jul 30 15:48:42 2018 +0100
Committer: Greg Albiston <greg_albiston@hotmail.com>
Committed: Mon Jul 30 15:48:42 2018 +0100

----------------------------------------------------------------------
 .../jena/query/ParameterizedSparqlString.java   | 57 ++++++++++++++++++--
 .../query/TestParameterizedSparqlString.java    | 39 ++++++++++++++
 2 files changed, 93 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/a5f18c3d/jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java b/jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java
index ab3bfcc..cba1e6d 100644
--- a/jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java
+++ b/jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java
@@ -1850,6 +1850,24 @@ public class ParameterizedSparqlString implements PrefixMapping {
         return command;
     }
 
+    private static final String VALUES_KEYWORD = "values";
+
+    protected static String[] extractTargetVars(String command, String varName) {
+        String[] targetVars;
+
+        int varIndex = command.indexOf(varName);
+        if (varIndex > -1) {
+            String subCmd = command.substring(0, varIndex).toLowerCase(); //Truncate the
command at the varName. Lowercase to search both types of values.
+            int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+            int bracesIndex = subCmd.lastIndexOf("{");
+            String vars = command.substring(valuesIndex + VALUES_KEYWORD.length(), bracesIndex);
+            targetVars = vars.replaceAll("[(?)]", "").trim().split(" ");
+        } else {
+            targetVars = new String[]{};
+        }
+        return targetVars;
+    }
+
     /**
      * Performs replacement of VALUES in query string.
      *
@@ -1884,10 +1902,11 @@ public class ParameterizedSparqlString implements PrefixMapping {
                 return command;
             }
 
-            String target = createTarget(varName);
+            validateValuesSafeToInject(command);
 
-            StringBuilder replacement;
+            String target = createTarget();
 
+            StringBuilder replacement;
             if (isGrouped) {
                 replacement = groupedApply();
             } else {
@@ -1943,7 +1962,7 @@ public class ParameterizedSparqlString implements PrefixMapping {
          * @param varName
          * @return
          */
-        private String createTarget(String varName) {
+        private String createTarget() {
             String target;
 
             if (varName.startsWith("?") || varName.startsWith("$")) {
@@ -1954,6 +1973,38 @@ public class ParameterizedSparqlString implements PrefixMapping {
             return target;
         }
 
+        protected void validateValuesSafeToInject(String command) {
+
+            String[] targetVars = extractTargetVars(command, varName);
+
+            for (int i = 0; i < targetVars.length; i++) {
+                String targetVar = targetVars[i];
+                if (isGrouped) {
+                    //Iterate through each group according to the position of var and item.
+                    for (List<? extends RDFNode> group : groupedItems) {
+                        RDFNode item = group.get(i);
+                        validateSafeToInject(command, targetVar, item.asNode());
+                    }
+                } else {
+                    if (targetVars.length > 1) {
+                        if (items instanceof List) {
+                            //Multiple vars with items in an ordered list. Each var is checked
against the item.
+                            List<? extends RDFNode> listItems = (List<? extends
RDFNode>) items;
+                            RDFNode item = listItems.get(i);
+                            validateSafeToInject(command, targetVar, item.asNode());
+                        } else {
+                            //Multiple vars with items not in an ordered list. This is parsing
error.
+                            throw new ARQException("Multiple VALUES variables (" + String.join(",
", targetVars) + ") being used without an ordered list of items: " + items.toString());
+                        }
+                    } else {
+                        //Single var with one or more items so all are checked.
+                        for (RDFNode item : items) {
+                            validateSafeToInject(command, targetVar, item.asNode());
+                        }
+                    }
+                }
+            }
+        }
     }
     
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/a5f18c3d/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
b/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
index 69c50bf..90e5385 100644
--- a/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
+++ b/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
@@ -2070,4 +2070,43 @@ public class TestParameterizedSparqlString {
         Assert.fail("Attempt to do SPARQL injection should result in an exception");
     }
 
+    @Test
+    public void test_extract_target_vars() {
+        // Identifies the vars in the VALUES clause according to the substituting varName.
+        String cmd = "SELECT * WHERE { VALUES ?o {?objs} ?s ?p ?o }";
+        String varName = "objs";
+        String[] res = ParameterizedSparqlString.extractTargetVars(cmd, varName);
+        String[] exp = new String[]{"o"};
+
+        //System.out.println("Exp: " + exp);
+        //System.out.println("Res: " + res);
+        Assert.assertArrayEquals(exp, res);
+    }
+
+    @Test
+    public void test_extract_two_target_vars() {
+        // Identifies the vars in the VALUES clause according to the substituting varName.
+        String cmd = "SELECT * WHERE { VALUES(?p ?o){?vars} ?s ?p ?o }";
+        String varName = "vars";
+        String[] res = ParameterizedSparqlString.extractTargetVars(cmd, varName);
+        String[] exp = new String[]{"p", "o"};
+
+        //System.out.println("Exp: " + exp);
+        //System.out.println("Res: " + res);
+        Assert.assertArrayEquals(exp, res);
+    }
+
+    @Test
+    public void test_extract_multiple_target_vars() {
+        // Identifies the vars in the VALUES clause according to the substituting varName.
+        String cmd = "SELECT * WHERE { VALUES ?p {?props} VALUES ?o {?objs} ?s ?p ?o }";
+        String varName = "objs";
+        String[] res = ParameterizedSparqlString.extractTargetVars(cmd, varName);
+        String[] exp = new String[]{"o"};
+
+        //System.out.println("Exp: " + exp);
+        //System.out.println("Res: " + res);
+        Assert.assertArrayEquals(exp, res);
+    }
+
 }


Mime
View raw message