From 7d4710db682ce7d7da9f57f54f229c8a09a904e8 Mon Sep 17 00:00:00 2001 From: sabinahofmann Date: Tue, 12 Sep 2017 18:41:27 +0200 Subject: [PATCH 1/3] XPath queries escape according to ISO9075 rules --- .../sinicum/server/jcr/NodeQueryManager.java | 50 +++++-- .../server/jcr/NodeQueryManagerTest.java | 51 ++++++- .../src/test/resources/fixtures/templates.xml | 138 ++++++++++++++++++ 3 files changed, 224 insertions(+), 15 deletions(-) diff --git a/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java b/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java index 37bf7a7..96ba51a 100644 --- a/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java +++ b/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java @@ -1,7 +1,9 @@ package com.dievision.sinicum.server.jcr; -import java.util.ArrayList; -import java.util.List; +import com.dievision.sinicum.server.mgnlAdapters.MgnlContextAdapter; +import org.apache.jackrabbit.util.ISO9075; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.jcr.Node; import javax.jcr.NodeIterator; @@ -9,11 +11,10 @@ import javax.jcr.Session; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.dievision.sinicum.server.mgnlAdapters.MgnlContextAdapter; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class NodeQueryManager { private final String workspace; @@ -34,7 +35,7 @@ public NodeQueryManager(String workspace, String query, String language, long li public NodeQueryManager(String workspace, String query, String language, long limit, long offset) { this.workspace = workspace; - this.query = query; + this.query = encodeQuery(query, language); this.language = convertQueryLanguage(language); this.limit = limit; this.offset = offset; @@ -44,7 +45,6 @@ public List executeQuery() throws RepositoryException { Session session = MgnlContextAdapter.getJcrSession(workspace); QueryManager queryManager = session.getWorkspace().getQueryManager(); Query qry = queryManager.createQuery(query, language); - if (limit > 0) { qry.setLimit(limit); } @@ -65,6 +65,13 @@ protected String getLanguage() { return language; } + private String encodeQuery(String query, String queryLanguage) { + if (Query.XPATH.equalsIgnoreCase(queryLanguage)) { + query = encodeXPathQuery(query); + } + return query; + } + private String convertQueryLanguage(String queryLanguage) { if (Query.XPATH.equalsIgnoreCase(queryLanguage)) { return Query.XPATH; @@ -78,4 +85,29 @@ private String convertQueryLanguage(String queryLanguage) { return queryLanguage; } } + + private String encodeXPathQuery(String query) { + String [] toEncodeNodes = query.split("\\[(.?)\\]|\\[(.*)\\]"); + String [] encodedNodes = new String[toEncodeNodes.length]; + for (int i = 0; i < toEncodeNodes.length; i++ ) { + String replaceNode = toEncodeNodes[i]; + Matcher matchNode = Pattern.compile("[0-9]+").matcher(toEncodeNodes[i]); + while (matchNode.find()) { + replaceNode = + replaceNode.replace(matchNode.group(0), ISO9075.encode(matchNode.group(0))); + encodedNodes[i] = replaceNode; + } + } + if (encodedNodes[0] != null) { + for (int i = 0; i < toEncodeNodes.length; i++) { + String toEncodeNode = toEncodeNodes[i]; + String encodedNode = encodedNodes[i]; + int startIndex, endIndex = 0; + startIndex = query.indexOf(toEncodeNode); + endIndex = startIndex + toEncodeNode.length(); + query = query.substring(0, startIndex) + encodedNode + query.substring(endIndex); + } + } + return query; + } } diff --git a/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java b/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java index df39b0f..76e9380 100644 --- a/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java +++ b/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java @@ -1,22 +1,22 @@ package com.dievision.sinicum.server.jcr; -import java.util.List; - -import javax.jcr.RepositoryException; -import javax.jcr.query.Query; - +import com.dievision.sinicum.server.JackrabbitTest45; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.dievision.sinicum.server.JackrabbitTest45; +import javax.jcr.RepositoryException; +import javax.jcr.query.Query; +import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; public class NodeQueryManagerTest extends JackrabbitTest45 { private static final String QUERY = "/jcr:root//*[@jcr:primaryType = 'mgnl:contentNode'] " + "order by @jcr:path"; + private static final Logger logger = LoggerFactory.getLogger(NodeQueryManagerTest.class); @Before @@ -32,6 +32,45 @@ public void testExecuteQuery() throws RepositoryException { } */ + @Test + public void testNodeAsANumberXpath() throws RepositoryException { + String [] queries = { + "/jcr:root/333[1]/1111[1]/11111//element(123,mix:title)" + + "[jcr:contains(.,'123,132:break')]", + "//element(*, mgnl:user)[@email = 'eric@example.com']", + "//*[@mgnl:template = 'stkTeaser']", + "/jcr:root/demo-project//element(*, mgnl:metaData)" + + "[@mgnl:template = 'standard-templating-kit:pages/stkArticle']/.." + + "[@categories = 'ab9437db-ab2c-4df5-bb41-87e55409e8e1'] order by @date", + "//element(89878node, mgnl:content)[jcr:like(@title, '%News%')]"}; + + for (String query : queries) { + try { + if (isVersion2()) { + NodeQueryManager nodeQueryManager = + new NodeQueryManager("config", query, Query.XPATH, 0, 0); + List result = nodeQueryManager.executeQuery(); + assertEquals(0, result.size()); + } + } catch (Exception e){ + assertNull(e); + } + } + + String query = "/jcr:root/templates/components/1234_test_sections/*"; + try{ + if (isVersion2()) { + NodeQueryManager nodeQueryManager = + new NodeQueryManager("config", query, Query.XPATH, 0, 0); + List result = nodeQueryManager.executeQuery(); + assertEquals(3, result.size()); + } + } catch (Exception e){ + assertNull(e); + } + + } + @Test public void testLimit() throws RepositoryException { if (isVersion2()) { diff --git a/sinicum-server/src/test/resources/fixtures/templates.xml b/sinicum-server/src/test/resources/fixtures/templates.xml index e717df3..34a6a6c 100644 --- a/sinicum-server/src/test/resources/fixtures/templates.xml +++ b/sinicum-server/src/test/resources/fixtures/templates.xml @@ -9070,5 +9070,143 @@ + + + mgnl:content + + + mix:lockable + + + cf3ceb5c-fef7-4dce-bda8-51fbadb92e50 + + + admin + + + + mgnl:metaData + + + admin + + + true + + + superuser + + + dievision + + + 2009-11-09T11:13:09.692+01:00 + + + 2010-09-30T22:00:49.265+08:00 + + + 2009-11-09T11:13:14.352+01:00 + + + + + mgnl:contentNode + + + mix:lockable + + + 676dc7cd-4e23-4de4-8999-27ba2b99056b + + + Displays the data of a contact person + + + shure:sections/contact_dialog + + + admin + + + Contact box + + + + mgnl:metaData + + + admin + + + true + + + superuser + + + dievision + + + 2009-10-02T14:17:00.000+02:00 + + + 2010-09-30T22:00:49.266+08:00 + + + 2009-11-09T11:15:04.634+01:00 + + + + + + mgnl:contentNode + + + mix:lockable + + + b49e7bfb-d910-4db3-cc99-b674b4b6fc4c + + + Simple text field + + + shure:sections/single_text_dialog + + + admin + + + Single text + + + + mgnl:metaData + + + admin + + + true + + + superuser + + + dievision + + + 2009-10-02T14:17:00.000+02:00 + + + 2010-09-30T22:00:49.266+08:00 + + + 2009-12-15T20:26:11.562+01:00 + + + + From 9a12fd30d579b623916154001df23f6962ebdd60 Mon Sep 17 00:00:00 2001 From: sabinahofmann Date: Tue, 12 Sep 2017 18:50:42 +0200 Subject: [PATCH 2/3] checkstyles --- .../sinicum/server/jcr/NodeQueryManager.java | 2 +- .../sinicum/server/jcr/NodeQueryManagerTest.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java b/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java index 96ba51a..80d7d69 100644 --- a/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java +++ b/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java @@ -89,7 +89,7 @@ private String convertQueryLanguage(String queryLanguage) { private String encodeXPathQuery(String query) { String [] toEncodeNodes = query.split("\\[(.?)\\]|\\[(.*)\\]"); String [] encodedNodes = new String[toEncodeNodes.length]; - for (int i = 0; i < toEncodeNodes.length; i++ ) { + for (int i = 0; i < toEncodeNodes.length; i++) { String replaceNode = toEncodeNodes[i]; Matcher matchNode = Pattern.compile("[0-9]+").matcher(toEncodeNodes[i]); while (matchNode.find()) { diff --git a/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java b/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java index 76e9380..77de806 100644 --- a/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java +++ b/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java @@ -39,9 +39,9 @@ public void testNodeAsANumberXpath() throws RepositoryException { + "[jcr:contains(.,'123,132:break')]", "//element(*, mgnl:user)[@email = 'eric@example.com']", "//*[@mgnl:template = 'stkTeaser']", - "/jcr:root/demo-project//element(*, mgnl:metaData)" + - "[@mgnl:template = 'standard-templating-kit:pages/stkArticle']/.." + - "[@categories = 'ab9437db-ab2c-4df5-bb41-87e55409e8e1'] order by @date", + "/jcr:root/demo-project//element(*, mgnl:metaData)" + + "[@mgnl:template = 'standard-templating-kit:pages/stkArticle']/.." + + "[@categories = 'ab9437db-ab2c-4df5-bb41-87e55409e8e1'] order by @date", "//element(89878node, mgnl:content)[jcr:like(@title, '%News%')]"}; for (String query : queries) { @@ -52,20 +52,20 @@ public void testNodeAsANumberXpath() throws RepositoryException { List result = nodeQueryManager.executeQuery(); assertEquals(0, result.size()); } - } catch (Exception e){ + } catch (Exception e) { assertNull(e); } } String query = "/jcr:root/templates/components/1234_test_sections/*"; - try{ + try { if (isVersion2()) { NodeQueryManager nodeQueryManager = new NodeQueryManager("config", query, Query.XPATH, 0, 0); List result = nodeQueryManager.executeQuery(); assertEquals(3, result.size()); } - } catch (Exception e){ + } catch (Exception e) { assertNull(e); } From 73b20a36fe699d7ced9c4b959af634a9ec757ccc Mon Sep 17 00:00:00 2001 From: sabinahofmann Date: Thu, 21 Sep 2017 13:44:07 +0200 Subject: [PATCH 3/3] Naming of variables --- .../sinicum/server/jcr/NodeQueryManager.java | 19 +++++++++++-------- .../server/jcr/NodeQueryManagerTest.java | 1 - 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java b/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java index 80d7d69..0259698 100644 --- a/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java +++ b/sinicum-server/src/main/java/com/dievision/sinicum/server/jcr/NodeQueryManager.java @@ -87,11 +87,13 @@ private String convertQueryLanguage(String queryLanguage) { } private String encodeXPathQuery(String query) { - String [] toEncodeNodes = query.split("\\[(.?)\\]|\\[(.*)\\]"); - String [] encodedNodes = new String[toEncodeNodes.length]; - for (int i = 0; i < toEncodeNodes.length; i++) { - String replaceNode = toEncodeNodes[i]; - Matcher matchNode = Pattern.compile("[0-9]+").matcher(toEncodeNodes[i]); + String [] queryPartToEncode = query.split("\\[(.?)\\]|\\[(.*)\\]"); + String [] encodedNodes = new String[queryPartToEncode.length]; + String replaceNode = null; + Matcher matchNode = null; + for (int i = 0; i < queryPartToEncode.length; i++) { + replaceNode = queryPartToEncode[i]; + matchNode = Pattern.compile("[0-9]+").matcher(queryPartToEncode[i]); while (matchNode.find()) { replaceNode = replaceNode.replace(matchNode.group(0), ISO9075.encode(matchNode.group(0))); @@ -99,9 +101,10 @@ private String encodeXPathQuery(String query) { } } if (encodedNodes[0] != null) { - for (int i = 0; i < toEncodeNodes.length; i++) { - String toEncodeNode = toEncodeNodes[i]; - String encodedNode = encodedNodes[i]; + String toEncodeNode, encodedNode = null; + for (int i = 0; i < queryPartToEncode.length; i++) { + toEncodeNode = queryPartToEncode[i]; + encodedNode = encodedNodes[i]; int startIndex, endIndex = 0; startIndex = query.indexOf(toEncodeNode); endIndex = startIndex + toEncodeNode.length(); diff --git a/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java b/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java index 77de806..238699b 100644 --- a/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java +++ b/sinicum-server/src/test/java/com/dievision/sinicum/server/jcr/NodeQueryManagerTest.java @@ -68,7 +68,6 @@ public void testNodeAsANumberXpath() throws RepositoryException { } catch (Exception e) { assertNull(e); } - } @Test