You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/03/25 17:46:12 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-9906: check index
before comparing parameters
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new ec1cdcd GROOVY-9906: check index before comparing parameters
ec1cdcd is described below
commit ec1cdcd922b85587bdcfe1258a30d0c1251f4e6a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jan 25 11:52:16 2021 -0600
GROOVY-9906: check index before comparing parameters
Conflicts:
src/main/java/org/codehaus/groovy/ast/ClassNode.java
---
.../java/org/codehaus/groovy/ast/ClassNode.java | 42 +++++++++++-----------
src/test/groovy/bugs/Groovy9906.groovy | 42 ++++++++++++++++++++++
2 files changed, 63 insertions(+), 21 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 4369c45..3935634 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -1268,14 +1268,14 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
// TODO: this won't strictly be true when using list expansion in argument calls
TupleExpression args = (TupleExpression) arguments;
- int count = args.getExpressions().size();
- MethodNode res = null;
+ int nArgs = args.getExpressions().size();
+ MethodNode method = null;
for (ClassNode cn = this; cn != null; cn = cn.getSuperClass()) {
for (MethodNode mn : cn.getDeclaredMethods(name)) {
- if (hasCompatibleNumberOfArgs(mn, count)) {
+ if (hasCompatibleNumberOfArgs(mn, nArgs)) {
boolean match = true;
- for (int i = 0; i < count; i += 1) {
+ for (int i = 0; i < nArgs; i += 1) {
if (!hasCompatibleType(args, mn, i)) {
match = false;
break;
@@ -1283,18 +1283,18 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
}
if (match) {
- if (res == null) {
- res = mn;
+ if (method == null) {
+ method = mn;
} else {
- if (res.getParameters().length != count)
+ if (method.getParameters().length != nArgs)
return null;
if (cn.equals(this))
return null;
match = true;
- for (int i = 0; i != count; ++i)
+ for (int i = 0; i != nArgs; ++i)
// prefer super method if it matches better
- if (!hasExactMatchingCompatibleType(res, mn, i)) {
+ if (!hasExactMatchingCompatibleType(method, mn, i)) {
match = false;
break;
}
@@ -1306,28 +1306,28 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
}
}
- return res;
+ return method;
}
- private boolean hasExactMatchingCompatibleType(MethodNode current, MethodNode newCandidate, int i) {
- int lastParamIndex = newCandidate.getParameters().length - 1;
- return current.getParameters()[i].getType().equals(newCandidate.getParameters()[i].getType())
- || (isPotentialVarArg(newCandidate, lastParamIndex) && i >= lastParamIndex && current.getParameters()[i].getType().equals(newCandidate.getParameters()[lastParamIndex].getType().componentType));
+ private static boolean hasExactMatchingCompatibleType(final MethodNode match, final MethodNode maybe, final int i) {
+ int lastParamIndex = maybe.getParameters().length - 1;
+ return (i <= lastParamIndex && match.getParameters()[i].getType().equals(maybe.getParameters()[i].getType()))
+ || (i >= lastParamIndex && isPotentialVarArg(maybe, lastParamIndex) && match.getParameters()[i].getType().equals(maybe.getParameters()[lastParamIndex].getType().getComponentType()));
}
- private boolean hasCompatibleType(TupleExpression args, MethodNode method, int i) {
+ private static boolean hasCompatibleType(final TupleExpression args, final MethodNode method, final int i) {
int lastParamIndex = method.getParameters().length - 1;
return (i <= lastParamIndex && args.getExpression(i).getType().isDerivedFrom(method.getParameters()[i].getType()))
- || (isPotentialVarArg(method, lastParamIndex) && i >= lastParamIndex && args.getExpression(i).getType().isDerivedFrom(method.getParameters()[lastParamIndex].getType().componentType));
+ || (i >= lastParamIndex && isPotentialVarArg(method, lastParamIndex) && args.getExpression(i).getType().isDerivedFrom(method.getParameters()[lastParamIndex].getType().getComponentType()));
}
- private boolean hasCompatibleNumberOfArgs(MethodNode method, int count) {
+ private static boolean hasCompatibleNumberOfArgs(final MethodNode method, final int nArgs) {
int lastParamIndex = method.getParameters().length - 1;
- return method.getParameters().length == count || (isPotentialVarArg(method, lastParamIndex) && count >= lastParamIndex);
+ return nArgs == method.getParameters().length || (nArgs >= lastParamIndex && isPotentialVarArg(method, lastParamIndex));
}
- private boolean isPotentialVarArg(MethodNode newCandidate, int lastParamIndex) {
- return lastParamIndex >= 0 && newCandidate.getParameters()[lastParamIndex].getType().isArray();
+ private static boolean isPotentialVarArg(final MethodNode method, final int lastParamIndex) {
+ return lastParamIndex >= 0 && method.getParameters()[lastParamIndex].getType().isArray();
}
/**
@@ -1337,7 +1337,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
* @param arguments the arguments to match against
* @return true if a matching method was found
*/
- public boolean hasPossibleStaticMethod(String name, Expression arguments) {
+ public boolean hasPossibleStaticMethod(final String name, final Expression arguments) {
return ClassNodeUtils.hasPossibleStaticMethod(this, name, arguments, false);
}
diff --git a/src/test/groovy/bugs/Groovy9906.groovy b/src/test/groovy/bugs/Groovy9906.groovy
new file mode 100644
index 0000000..12e433d
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9906.groovy
@@ -0,0 +1,42 @@
+/*
+ * 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 groovy.bugs
+
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy9906 {
+
+ @Test
+ void testSuperClassOverloads() {
+ assertScript '''
+ abstract class A {
+ void m(String a, String b, String c) {}
+ void m(String a, String... zeroPlus) {}
+ }
+ class C extends A {
+ void test() {
+ m('x', 'y', 'z') // ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
+ }
+ }
+ new C().test()
+ '''
+ }
+}