Author: rr
Date: Fri May  7 17:15:56 2010
New Revision: 942153

URL: http://svn.apache.org/viewvc?rev=942153&view=rev
Log:
ODE-807: Infinite Loop when locating unresolved functions in XPath expression 
(fix), thanks to David Carver

Added:
    
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/
    
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java
   (with props)
Modified:
    
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java

Modified: 
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java
URL: 
http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java?rev=942153&r1=942152&r2=942153&view=diff
==============================================================================
--- 
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java
 (original)
+++ 
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java
 Fri May  7 17:15:56 2010
@@ -20,9 +20,12 @@
 package org.apache.ode.bpel.elang.xpath20.compiler;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.xml.namespace.QName;
 import javax.xml.transform.TransformerFactory;
@@ -251,60 +254,19 @@ public class XPath20ExpressionCompilerIm
      * @return list of function expressions that may not have been resolved 
properly
      */
     private List<String> extractFunctionExprs(String xpathStr) {       
-               ArrayList<String> functionExprs = new ArrayList<String>();
+               ArrayList<String> functionExprs = new ArrayList<String>(); 
+               // Match the prefix : function name ( all contents except the ) 
and the closing )'s that may occur
+               final String FUNCTION_REGEX = "\\w+:\\w+\\([.[^\\)]]*\\)*";
                int firstFunction = xpathStr.indexOf("("), 
                        lastFunction = xpathStr.lastIndexOf("("); 
-               StringBuffer functionExpr = new StringBuffer();
-               if ((firstFunction > 0 && // the xpath contains a function
-                               firstFunction < lastFunction)) { // the xpath 
references multiple variables 
-                       // most likely, the variable reference has not been 
resolved, so make that happen
-                       boolean quoted = false, doubleQuoted = false, function 
= false, arguments = false;
-                       Name11Checker nameChecker = Name11Checker.getInstance();
-                       for (int index = firstFunction; index < 
xpathStr.length(); index++) {
-                               if (!function) {
-                                       int colonIndex = xpathStr.indexOf(':', 
index);
-                                       if (colonIndex == -1) {
-                                               break;
-                                       }
-                                       while (colonIndex >= 0 && 
nameChecker.isNCNameChar(xpathStr.charAt(--colonIndex)));
-                                       if (xpathStr.charAt(colonIndex) == '$') 
{
-                                               index = xpathStr.indexOf(':', 
index) + 1;
-                                               continue;
-                                       }
-                                       function = true;
-                                       arguments = false;
-                                       functionExpr.setLength(0);
-                                       index = colonIndex;
-                                       continue;
-                               }
-                               char ch = xpathStr.charAt(index);
-                               if (function) {
-                                       functionExpr.append(ch);
-                                       // in the name is qualified, don't 
check if its a qname when we're at the ":" character
-                                       if (ch == ':') {
-                                               continue;
-                                       } else if (ch == '(') {
-                                               if 
(nameChecker.isQName(functionExpr.substring(0, functionExpr.length() - 1))) {
-                                                       arguments = true;
-                                               } else {
-                                                       function = false;
-                                                       continue;
-                                               }
-                                       } else if (ch == ')') {
-                                               if (arguments) {
-                                                       function = false;
-                                                       
functionExprs.add(functionExpr.toString());
-                                                       
functionExpr.setLength(0);                                                      
-                                               }
-                                       } else {
-                                               if (!arguments) {
-                                                       if 
(!nameChecker.isQName(functionExpr.substring(0, functionExpr.length()))) {
-                                                               function = 
false;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
+               if ((firstFunction > 0 && firstFunction < lastFunction)) {
+               Pattern regex = Pattern.compile(FUNCTION_REGEX);
+               Matcher matcher = regex.matcher(xpathStr);
+               
+               while (matcher.find()) {
+                   String function = matcher.group();
+                   functionExprs.add(function);
+               }
                }
                return functionExprs;
        }

Added: 
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java
URL: 
http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java?rev=942153&view=auto
==============================================================================
--- 
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java
 (added)
+++ 
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java
 Fri May  7 17:15:56 2010
@@ -0,0 +1,86 @@
+/*
+ * 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.ode.bpel.elang.xpath20.compiler;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.*;
+
+
+public class XPath20ExpressionCompilerImplTest {
+    
+    private static final String TEST_NAMESPACE = "http://www.example.com/";;
+    private static final String EXTRACT_FUNCTION_EXPRS = 
"extractFunctionExprs";
+
+    @Test
+    public void testresolvedFunctionsExpr() throws Exception {
+        XPath20ExpressionCompilerImpl xp20Exp = new 
XPath20ExpressionCompilerImpl(TEST_NAMESPACE);
+        final Method[] methods =
+            xp20Exp.getClass().getDeclaredMethods();
+        for (int i = 0; i < methods.length; ++i) {
+            if (methods[i].getName().equals(EXTRACT_FUNCTION_EXPRS)) {
+                final Object params[] = { "count(count(1))" };
+                methods[i].setAccessible(true);
+                Object ret = methods[i].invoke(xp20Exp, params);
+                List<?> values = (List<?>) ret;
+                Assert.assertEquals(0, values.size());
+            }
+        }
+    }
+    
+    @Test
+    public void testTimeStampInFunction() throws Exception {
+        XPath20ExpressionCompilerImpl xp20Exp = new 
XPath20ExpressionCompilerImpl(TEST_NAMESPACE);
+        final Method[] methods =
+            xp20Exp.getClass().getDeclaredMethods();
+        for (int i = 0; i < methods.length; ++i) {
+            if (methods[i].getName().equals(EXTRACT_FUNCTION_EXPRS)) {
+                final Object params[] = { "concat(xs:concat(\"P\", 
\"08:30:00.000+08:00\"))" };
+                methods[i].setAccessible(true);
+                Object ret = methods[i].invoke(xp20Exp, params);
+                List<?> values = (List<?>) ret;
+                Assert.assertEquals(1, values.size());
+            }
+        }
+
+    }
+    
+    @Test
+    public void testresolvedFunctionsTimeStamp() throws Exception {
+        XPath20ExpressionCompilerImpl xp20Exp = new 
XPath20ExpressionCompilerImpl(TEST_NAMESPACE);
+        final Method[] methods =
+            xp20Exp.getClass().getDeclaredMethods();
+        for (int i = 0; i < methods.length; ++i) {
+            if (methods[i].getName().equals(EXTRACT_FUNCTION_EXPRS)) {
+                final Object params[] = { "concat(current-date() + 
xs:dayTimeDuration(concat(\"P\", $DAYS_TO_NEXT_REMINDER, \"D\")), \"T\", 
\"08:30:00.000+08:00\")" };
+                methods[i].setAccessible(true);
+                Object ret = methods[i].invoke(xp20Exp, params);
+                List<?> values = (List<?>) ret;
+                Assert.assertEquals(1, values.size());
+                Assert.assertEquals("Unexpected Function value", 
"xs:dayTimeDuration(concat(\"P\", $DAYS_TO_NEXT_REMINDER, \"D\"))", 
(String)values.get(0));
+            }
+        }
+    }
+    
+    
+    
+
+}

Propchange: 
ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to