8224532: Better Path supports
authorjoehw
Fri, 31 May 2019 10:58:10 -0700
changeset 58627 92a18902b92c
parent 58626 a9ed3d93cca3
child 58628 874e94940351
8224532: Better Path supports Reviewed-by: rriggs, lancea, dfuchs, mschoene
src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java
src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java
src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java
src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Compiler.java
src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java	Fri May 31 18:16:57 2019 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java	Fri May 31 10:58:10 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,7 +40,7 @@
  * The XPath class wraps an expression object and provides general services
  * for execution of that expression.
  * @xsl.usage advanced
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
  */
 public class XPath implements Serializable, ExpressionOwner
 {
@@ -179,10 +179,12 @@
     else if (MATCH == type)
       parser.initMatchPattern(compiler, exprString, prefixResolver);
     else
-      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, new Object[]{Integer.toString(type)})); //"Can not deal with XPath type: " + type);
+      throw new RuntimeException(XSLMessages.createXPATHMessage(
+              XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE,
+              new Object[]{Integer.toString(type)}));
 
     // System.out.println("----------------");
-    Expression expr = compiler.compile(0);
+    Expression expr = compiler.compileExpression(0);
 
     // System.out.println("expr: "+expr);
     this.setExpression(expr);
@@ -234,7 +236,7 @@
             //"Can not deal with XPath type: " + type);
 
     // System.out.println("----------------");
-    Expression expr = compiler.compile(0);
+    Expression expr = compiler.compileExpression(0);
 
     // System.out.println("expr: "+expr);
     this.setExpression(expr);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java	Fri May 31 18:16:57 2019 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java	Fri May 31 10:58:10 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -37,7 +37,7 @@
  * Walker for the OP_VARIABLE, or OP_EXTFUNCTION, or OP_FUNCTION, or OP_GROUP,
  * op codes.
  * @see <a href="http://www.w3.org/TR/xpath#NT-FilterExpr">XPath FilterExpr descriptions</a>
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
  */
 public class FilterExprWalker extends AxesWalker
 {
@@ -77,7 +77,7 @@
         m_mustHardReset = true;
     case OpCodes.OP_GROUP :
     case OpCodes.OP_VARIABLE :
-      m_expr = compiler.compile(opPos);
+      m_expr = compiler.compileExpression(opPos);
       m_expr.exprSetParent(this);
       //if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof com.sun.org.apache.xalan.internal.templates.FuncKey))
       if(m_expr instanceof com.sun.org.apache.xpath.internal.operations.Variable)
@@ -87,7 +87,7 @@
       }
       break;
     default :
-      m_expr = compiler.compile(opPos + 2);
+      m_expr = compiler.compileExpression(opPos + 2);
       m_expr.exprSetParent(this);
     }
 //    if(m_expr instanceof WalkingIterator)
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java	Fri May 31 18:16:57 2019 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java	Fri May 31 10:58:10 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -41,7 +41,7 @@
  * which are built from the opcode map output, and an analysis engine
  * for the location path expressions in order to provide optimization hints.
  *
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
  */
 public class WalkerFactory
 {
@@ -1008,10 +1008,10 @@
       case OpCodes.OP_EXTFUNCTION :
       case OpCodes.OP_FUNCTION :
       case OpCodes.OP_GROUP :
-        expr = compiler.compile(opPos);
+        expr = compiler.compileExpression(opPos);
         break;
       default :
-        expr = compiler.compile(opPos + 2);
+        expr = compiler.compileExpression(opPos + 2);
       }
 
       axis = Axis.FILTEREDLIST;
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Compiler.java	Fri May 31 18:16:57 2019 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Compiler.java	Fri May 31 10:58:10 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -70,9 +69,12 @@
  * of operation codes (op map) and then builds from that into an Expression
  * tree.
  * @xsl.usage advanced
+ * @LastModified: May 2019
  */
 public class Compiler extends OpMap
 {
+  // count the number of operations or calls to compileOperation
+  int countOp;
 
   /**
    * Construct a Compiler object with a specific ErrorListener and
@@ -106,15 +108,40 @@
 
   /**
    * Execute the XPath object from a given opcode position.
+   *
+   * Note that this method is added so that when StackOverflowError is caught
+   * the address space can be freed to this point allowing further activities
+   * such as reporting the error.
+   *
    * @param opPos The current position in the xpath.m_opMap array.
    * @return The result of the XPath.
    *
    * @throws TransformerException if there is a syntax or other error.
    * @xsl.usage advanced
    */
-  public Expression compile(int opPos) throws TransformerException
+   public Expression compileExpression(int opPos) throws TransformerException
+   {
+       try {
+           countOp = 0;
+           return compile(opPos);
+       } catch (StackOverflowError sof) {
+           error(XPATHErrorResources.ER_COMPILATION_TOO_MANY_OPERATION, new Object[]{countOp});
+       }
+       return null;
+   }
+
+  /**
+   * This method handles the actual compilation process. It is called from the
+   * compileExpression method as well as the subsequent processes. See the note
+   * for compileExpression.
+   *
+   * @param opPos The current position in the xpath.m_opMap array.
+   * @return The result of the XPath.
+   *
+   * @throws TransformerException if there is a syntax or other error.
+   */
+  private Expression compile(int opPos) throws TransformerException
   {
-
     int op = getOp(opPos);
 
     Expression expr = null;
@@ -210,6 +237,7 @@
   private Expression compileOperation(Operation operation, int opPos)
           throws TransformerException
   {
+    ++countOp;
 
     int leftPos = getFirstChildPos(opPos);
     int rightPos = getNextOpPos(leftPos);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java	Fri May 31 18:16:57 2019 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java	Fri May 31 10:58:10 2019 -0700
@@ -152,6 +152,8 @@
          "ER_PREDICATE_ILLEGAL_SYNTAX";
   public static final String ER_PREDICATE_TOO_MANY_OPEN =
          "ER_PREDICATE_TOO_MANY_OPEN";
+  public static final String ER_COMPILATION_TOO_MANY_OPERATION =
+         "ER_COMPILATION_TOO_MANY_OPERATION";
   public static final String ER_ILLEGAL_AXIS_NAME = "ER_ILLEGAL_AXIS_NAME";
   public static final String ER_UNKNOWN_NODETYPE = "ER_UNKNOWN_NODETYPE";
   public static final String ER_PATTERN_LITERAL_NEEDS_BE_QUOTED =
@@ -467,7 +469,10 @@
       "'..[predicate]' or '.[predicate]' is illegal syntax.  Use 'self::node()[predicate]' instead."},
 
   { ER_PREDICATE_TOO_MANY_OPEN,
-      "Stack overflow while parsing {0} at {1}. Too many open predicates {2}."},
+      "Stack overflow while parsing {0} at {1}. Too many open predicates({2})."},
+
+  { ER_COMPILATION_TOO_MANY_OPERATION,
+      "Stack overflow while compiling the expression. Too many operations({0})."},
 
   { ER_ILLEGAL_AXIS_NAME,
      "illegal axis name: {0}"},