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