You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2015/04/09 16:03:55 UTC

svn commit: r1672357 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/query/ main/java/org/apache/jackrabbit/oak/query/xpath/ test/java/org/apache/jackrabbit/oak/query/

Author: thomasm
Date: Thu Apr  9 14:03:55 2015
New Revision: 1672357

URL: http://svn.apache.org/r1672357
Log:
OAK-2738 Possible StackOverflowException with many "or" conditions

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java?rev=1672357&r1=1672356&r2=1672357&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java Thu Apr  9 14:03:55 2015
@@ -1364,7 +1364,10 @@ public class SQL2Parser {
     }
 
     public static String escapeStringLiteral(String value) {
-        return '\'' + value.replace("'", "''") + '\'';
+        if (value.indexOf('\'') >= 0) {
+            value = value.replace("'", "''");
+        }
+        return '\'' + value + '\'';
     }
 
     /**

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java?rev=1672357&r1=1672356&r2=1672357&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java Thu Apr  9 14:03:55 2015
@@ -321,12 +321,17 @@ abstract class Expression {
                 return this;
             }
             // "@x = 1 or @x = 2" is converted to "@x in (1, 2)"
+            if (left instanceof InCondition) {
+                InCondition in = (InCondition) left;
+                in.list.addAll(right.getRight());
+                return in;
+            }
             ArrayList<Expression> list = new ArrayList<Expression>();
             list.addAll(left.getRight());
             list.addAll(right.getRight());
             Expression le = left.getLeft();
             InCondition in = new InCondition(le, list);
-            return in.optimize();
+            return in;
         }
         
         @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java?rev=1672357&r1=1672356&r2=1672357&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java Thu Apr  9 14:03:55 2015
@@ -421,10 +421,14 @@ public class XPathToSQL2Converter {
 
     private Expression parseConstraint() throws ParseException {
         Expression a = parseAnd();
+        int i = 0;
         while (readIf("or")) {
             a = new Expression.OrCondition(a, parseAnd());
+            if (++i % 100 == 0) {
+                a = a.optimize();
+            }
         }
-        return a;
+        return a.optimize();
     }
 
     private Expression parseAnd() throws ParseException {

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java?rev=1672357&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java Thu Apr  9 14:03:55 2015
@@ -0,0 +1,49 @@
+/*
+ * 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.jackrabbit.oak.query;
+
+import static org.junit.Assert.assertEquals;
+
+import java.text.ParseException;
+
+import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
+import org.junit.Test;
+
+public class LargeQueryTest {
+
+    @Test
+    public void test() throws ParseException {
+        StringBuilder buff = new StringBuilder("//*[");
+        StringBuilder buff2 = new StringBuilder(
+                "select [jcr:path], [jcr:score], * from [nt:base] as a where [x] in(");
+        for (int i = 0; i < 100000; i++) {
+            if (i > 0) {
+                buff.append(" or ");
+                buff2.append(", ");
+            }
+            buff.append("@x=").append(i);
+            buff2.append(i);
+        }
+        buff.append("]");
+        buff2.append(")");
+        String xpath = buff.toString();
+        XPathToSQL2Converter conv = new XPathToSQL2Converter();
+        String sql2 = conv.convert(xpath);
+        buff2.append(" /* xpath: ").append(xpath).append(" */");
+        assertEquals(buff2.toString(), sql2);
+    }
+}