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 2024/05/09 17:10:53 UTC
(groovy) branch master updated: GROOVY-11373: SC: cross-package direct target of package-private method
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 131992c98e GROOVY-11373: SC: cross-package direct target of package-private method
131992c98e is described below
commit 131992c98e9de226aeac50917b37c4bfff31b21e
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu May 9 11:43:32 2024 -0500
GROOVY-11373: SC: cross-package direct target of package-private method
---
.../classgen/asm/sc/StaticInvocationWriter.java | 43 ++++++++++++----------
.../sc/FieldsAndPropertiesStaticCompileTest.groovy | 9 ++---
.../classgen/asm/sc/bugs/Groovy7325Bug.groovy | 12 +++---
3 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index 0aa0e28738..4e81f7b08b 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -73,6 +73,7 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.formatTypeName;
import static org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName;
import static org.apache.groovy.ast.tools.ExpressionUtils.isNullConstant;
import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
@@ -347,16 +348,17 @@ public class StaticInvocationWriter extends InvocationWriter {
return true;
}
- Expression fixedReceiver = receiver;
- boolean fixedImplicitThis = implicitThis;
- if (target.isProtected()) {
- ClassNode node = receiver == null ? ClassHelper.OBJECT_TYPE : controller.getTypeChooser().resolveType(receiver, controller.getClassNode());
+ Expression fixedReceiver = receiver;
+ boolean fixedImplicitThis = implicitThis;
+ if (target.isPackageScope()) { // GROOVY-11373
+ if (!samePackageName(target.getDeclaringClass(), classNode)) {
+ writeMethodAccessError(target, receiver != null ? receiver : args);
+ }
+ } else if (target.isProtected()) {
+ ClassNode node = receiver == null ? ClassHelper.OBJECT_TYPE : controller.getTypeChooser().resolveType(receiver, classNode);
if (!implicitThis && !isThisOrSuper(receiver) && !samePackageName(node, classNode)
- && StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(node,target.getDeclaringClass())) {
- controller.getSourceUnit().addError(new SyntaxException(
- "Method " + target.getName() + " is protected in " + target.getDeclaringClass().toString(false),
- receiver != null ? receiver : args
- ));
+ && StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(node, target.getDeclaringClass())) {
+ writeMethodAccessError(target, receiver != null ? receiver : args);
} else if (!node.isDerivedFrom(target.getDeclaringClass()) && tryBridgeMethod(target, receiver, implicitThis, args, classNode)) {
return true;
}
@@ -389,6 +391,16 @@ public class StaticInvocationWriter extends InvocationWriter {
return super.writeDirectMethodCall(target, implicitThis, receiver, args);
}
+ private void writeMethodAccessError(final MethodNode target, final Expression origin) {
+ var descriptor = new java.util.StringJoiner(", ", target.getName() + "(", ")");
+ for (Parameter parameter : target.getParameters()) {
+ descriptor.add(formatTypeName(parameter.getOriginType()));
+ }
+ String message = "Cannot access method: " + descriptor + " of class: " + formatTypeName(target.getDeclaringClass());
+
+ controller.getSourceUnit().addError(new SyntaxException(message, origin));
+ }
+
private boolean isClassWithSuper(Expression receiver) {
if (receiver instanceof PropertyExpression) {
PropertyExpression pexp = (PropertyExpression) receiver;
@@ -404,21 +416,12 @@ public class StaticInvocationWriter extends InvocationWriter {
&& !declaringClass.equals(classNode)) {
if (tryBridgeMethod(target, receiver, implicitThis, args, classNode)) {
return true;
- } else {
- checkAndAddCannotCallPrivateMethodError(target, receiver, classNode, declaringClass);
}
}
- checkAndAddCannotCallPrivateMethodError(target, receiver, classNode, declaringClass);
- return false;
- }
-
- private void checkAndAddCannotCallPrivateMethodError(final MethodNode target, final Expression receiver, final ClassNode classNode, final ClassNode declaringClass) {
if (declaringClass != classNode) {
- controller.getSourceUnit().addError(new SyntaxException(
- "Cannot call private method " + (target.isStatic() ? "static " : "") + declaringClass.toString(false) + "#" + target.getName() + " from class " + classNode.toString(false),
- receiver
- ));
+ writeMethodAccessError(target, receiver);
}
+ return false;
}
protected static boolean isPrivateBridgeMethodsCallAllowed(final ClassNode receiver, final ClassNode caller) {
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
index 5081b0f990..506db212fb 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -940,7 +940,7 @@ final class FieldsAndPropertiesStaticCompileTest extends FieldsAndPropertiesSTCT
'''
}
- // GROOVY-11223
+ // GROOVY-11223, GROOVY-11373
@Override
void testMapPropertyAccess10() {
assertScript """
@@ -954,13 +954,12 @@ final class FieldsAndPropertiesStaticCompileTest extends FieldsAndPropertiesSTCT
def map = new ${MapType.name}()
map.bar = 22 // protected setter
""",
- "Method setBar is protected in ${MapType.name}"
- /*
+ "Cannot access method: setBar(java.lang.Object) of class: ${MapType.name}"
+
shouldFailWithMessages """
def map = new ${MapType.name}()
map.baz = 33 // package-private setter
""",
- "Method setBaz is package-private in ${MapType.name}"
- */
+ "Cannot access method: setBaz(java.lang.Object) of class: ${MapType.name}"
}
}
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7325Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7325Bug.groovy
index d12cdd665a..49ab84ac65 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7325Bug.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7325Bug.groovy
@@ -41,17 +41,15 @@ final class Groovy7325Bug extends StaticTypeCheckingTestCase implements StaticCo
void testShouldNotThrowIllegalAccessToProtectedData() {
shouldFailWithMessages '''
- class Test {
- final Set<String> HISTORY = [] as HashSet
-
+ class C {
+ private final Set<String> history = []
Set<String> getHistory() {
- return HISTORY.clone() as HashSet<String>
+ (Set<String>) history.clone()
}
}
- Test test = new Test()
- println test.history
+ def set = new C().history
''',
- 'Method clone is protected in java.lang.Object'
+ 'Cannot access method: clone() of class: java.lang.Object'
}
}