Github user rvesse commented on a diff in the pull request:
https://github.com/apache/jena/pull/449#discussion_r207148170
--- Diff:
jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
---
@@ -1925,4 +1926,190 @@ public void test_param_string_bug_04() {
pss.toString();
}
+
+ @Test
+ public void test_set_values_item() {
+ // Tests a single value being added.
+ String str = "SELECT * WHERE { VALUES ?o {?objs} ?s ?p ?o }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+ pss.setValues("objs", ResourceFactory.createPlainLiteral("test"));
+
+ String exp = "SELECT * WHERE { VALUES ?o {\"test\"} ?s ?p ?o }";
+ String res = pss.toString();
+ //System.out.println("Exp: " + exp);
+ //System.out.println("Res: " + res);
+ Assert.assertEquals(exp, res);
+ }
+
+ @Test
+ public void test_set_values_items() {
+ // Tests two values for same variable.
+ String str = "SELECT * WHERE { VALUES ?o {?objs} ?s ?p ?o }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+ List<RDFNode> objs = new ArrayList<>();
+ objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+ objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+ pss.setValues("objs", objs);
+
+ String exp = "SELECT * WHERE { VALUES ?o {\"obj_A\" \"obj_B\"} ?s
?p ?o }";
+ String res = pss.toString();
+ //System.out.println("Exp: " + exp);
+ //System.out.println("Res: " + res);
+ Assert.assertEquals(exp, res);
+ }
+
+ @Test
+ public void test_set_values_items_parenthesis() {
+ // Tests two values for same variable.
+ String str = "SELECT * WHERE { VALUES (?o) {?objs} ?s ?p ?o }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+ List<RDFNode> objs = new ArrayList<>();
+ objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+ objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+ pss.setValues("objs", objs);
+
+ String exp = "SELECT * WHERE { VALUES (?o) {(\"obj_A\")
(\"obj_B\")} ?s ?p ?o }";
+ String res = pss.toString();
+ //System.out.println("Exp: " + exp);
+ //System.out.println("Res: " + res);
+ Assert.assertEquals(exp, res);
+ }
+
+ @Test
+ public void test_set_values_multiple_variables_parenthesis() {
+ // Tests two values for same variable.
+ String str = "SELECT * WHERE { VALUES (?p ?o) {?vars} ?s ?p ?o }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+ List<RDFNode> vars = new ArrayList<>();
+
vars.add(ResourceFactory.createProperty("http://example.org/prop_A"));
+ vars.add(ResourceFactory.createPlainLiteral("obj_A"));
+ pss.setValues("vars", vars);
+
+ String exp = "SELECT * WHERE { VALUES (?p ?o)
{(<http://example.org/prop_A> \"obj_A\")} ?s ?p ?o }";
+ String res = pss.toString();
+ System.out.println("Exp: " + exp);
+ System.out.println("Res: " + res);
+ Assert.assertEquals(exp, res);
+ }
+
+ @Test
+ public void test_set_values_multi_var() {
+ // Tests two variables.
+ String str = "SELECT * WHERE { VALUES ?p {?props} VALUES ?o
{?objs} ?s ?p ?o }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+ List<RDFNode> objs = new ArrayList<>();
+ objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+ objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+ pss.setValues("objs", objs);
+
+ List<RDFNode> props = new ArrayList<>();
+
props.add(ResourceFactory.createProperty("http://example.org/prop_A"));
+
props.add(ResourceFactory.createProperty("http://example.org/prop_B"));
+ pss.setValues("props", props);
+
+ String exp = "SELECT * WHERE { VALUES ?p
{<http://example.org/prop_A> <http://example.org/prop_B>} VALUES ?o {\"obj_A\"
\"obj_B\"} ?s ?p ?o }";
+ String res = pss.toString();
+ //System.out.println("Exp: " + exp);
+ //System.out.println("Res: " + res);
+ Assert.assertEquals(exp, res);
+ }
+
+ @Test
+ public void test_set_values_multi_var_parenthesis() {
+ // Tests two variables with parenthesis for one.
+ String str = "SELECT * WHERE { VALUES (?p) {?props} VALUES ?o
{?objs} ?s ?p ?o }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+ List<RDFNode> objs = new ArrayList<>();
+ objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+ objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+ pss.setValues("objs", objs);
+
+ List<RDFNode> props = new ArrayList<>();
+
props.add(ResourceFactory.createProperty("http://example.org/prop_A"));
+
props.add(ResourceFactory.createProperty("http://example.org/prop_B"));
+ pss.setValues("props", props);
+
+ String exp = "SELECT * WHERE { VALUES (?p)
{(<http://example.org/prop_A>) (<http://example.org/prop_B>)} VALUES ?o
{\"obj_A\" \"obj_B\"} ?s ?p ?o }";
+ String res = pss.toString();
+ //System.out.println("Exp: " + exp);
+ //System.out.println("Res: " + res);
+ Assert.assertEquals(exp, res);
+ }
+
+ @Test
+ public void test_set_values_grouped_var() {
+ // Tests two variables with parenthesis for one.
+ String str = "SELECT * WHERE { VALUES (?p ?o) {?vars} ?s ?p ?o }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+
+ List<List<? extends RDFNode>> vars = new ArrayList<>();
+ List<RDFNode> objsA = new ArrayList<>();
+
objsA.add(ResourceFactory.createProperty("http://example.org/prop_A"));
+ objsA.add(ResourceFactory.createPlainLiteral("obj_A"));
+ vars.add(objsA);
+
+ List<RDFNode> objsB = new ArrayList<>();
+
objsB.add(ResourceFactory.createProperty("http://example.org/prop_B"));
+ objsB.add(ResourceFactory.createPlainLiteral("obj_B"));
+ vars.add(objsB);
+
+ pss.setGroupedValues("vars", vars);
+
+ String exp = "SELECT * WHERE { VALUES (?p ?o)
{(<http://example.org/prop_A> \"obj_A\") (<http://example.org/prop_B>
\"obj_B\")} ?s ?p ?o }";
+ String res = pss.toString();
+ //System.out.println("Exp: " + exp);
+ //System.out.println("Res: " + res);
+ Assert.assertEquals(exp, res);
+ }
+
+ @Test(expected = ARQException.class)
+ public void test_set_values_uri_injection() {
+ // This injection is prevented by forbidding the > character in
URIs
+ String str = "PREFIX : <http://example/>\nSELECT * WHERE { VALUES
?obj {?objVar} <s> <p> ?obj . }";
+ ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+ pss.setValues(str,
ResourceFactory.createResource("<http://example.org/obj_A>"));
+
+ pss.asQuery();
+ 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);
+ }
+
--- End diff --
It would be nice to have some negative test cases where the SPARQL string
to be substituted into does not correspond correctly to the number of
values/variables the user is attempting to set.
In particular it isn't clear that the code will do anything sensible if the
user calls `setValues()` with a query that never contains the `VALUES` keyword.
---