[
https://issues.apache.org/jira/browse/GROOVY-12568?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135443#comment-18135443
]
ASF GitHub Bot commented on GROOVY-12568:
-----------------------------------------
blackdrag commented on code in PR #3097:
URL: https://github.com/apache/groovy/pull/3097#discussion_r4429126084
##########
src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java:
##########
@@ -1307,9 +1307,52 @@ private static String getStaticFieldName(final ClassNode
type) {
/**
* Determines if the given field can be directly accessed by the given
class
* (via {@code GETFIELD}, {@code GETSTATIC}, etc. bytecode instructions).
+ * <p>
+ * A protected or package-private field of a class with the same package
+ * name is accessible only within the same run-time package; see
+ * {@link #isInSameRuntimePackage}. Otherwise it is directly accessible
+ * only through the subclass rule for a protected field.
*/
public static boolean isFieldDirectlyAccessible(final FieldNode field,
final ClassNode accessingClass) {
- return field != null &&
isMemberDirectlyAccessible(field.getModifiers(), field.getDeclaringClass(),
accessingClass);
+ if (field == null || !isMemberDirectlyAccessible(field.getModifiers(),
field.getDeclaringClass(), accessingClass)) return false;
+ ClassNode declaringClass = field.getDeclaringClass();
+ return field.isPublic() || field.isPrivate() ||
isInSameRuntimePackage(declaringClass, accessingClass)
+ || (field.isProtected() &&
accessingClass.isDerivedFrom(declaringClass));
Review Comment:
this overlaps highly with isMemberDirectlyAccessible I don`t think all
conditions make sense. The later condition needs at least some comments on why
they are now legal cases and how they overlap with the illegal cases that have
been excluded
> SC: protected and package-private members of a class defined by another
> GroovyClassLoader compilation fail with IllegalAccessError
> ----------------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12568
> URL: https://issues.apache.org/jira/browse/GROOVY-12568
> Project: Groovy
> Issue Type: Bug
> Components: Static compilation
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> The JVM allows access to a protected or package-private member only within
> the same run-time package, which is the package name and the class loader. A
> {{GroovyClassLoader}} defines each compilation in memory with a class loader
> of its own: a {{GroovyShell}} script, {{parseClass}}, a script run with
> {{groovy}}, JSR-223. So a class of an earlier parse, or a precompiled class
> used by such a script, is in another run-time package even with the same
> package name. Statically compiled code calls such members directly and fails;
> dynamic code goes through the meta-class and works.
> {code:groovy}
> def shell = new GroovyShell()
> shell.evaluate '''package p
> class A {
> @groovy.transform.PackageScope A(String s) { }
> @groovy.transform.PackageScope String name() { 'a' }
> @groovy.transform.PackageScope String tag = 't'
> }
> true
> '''
> shell.evaluate '''package p
> @groovy.transform.CompileStatic
> List make() { def a = new A('x'); [a.name(), a.tag] }
> make()
> ''' // IllegalAccessError; without @CompileStatic: ['a', 't']
> {code}
> The same happens for map-style construction, instance and static methods,
> getters and setters used as properties, method references such as
> {{a::name}}, and field reads and writes including {{.@}}, {{+=}} and {{++}}.
> In dynamic code, {{super.f}}, {{super.@f}} and {{this.@f}} of such a field,
> and {{super.m()}} of such a method, fail the same way, because the {{super$}}
> helper and the field instructions are generated directly.
> Related, in a subclass in another package, under static compilation:
> * {{new A(...)}} of a protected constructor of another package compiles and
> then fails verification. As in Java, only {{super(...)}} and {{new A(...)
> {}}} can call it.
> * a protected method of another package called through a receiver of the
> superclass type ({{a.m()}}, {{a.name}}, {{a::m}}, {{A::m}}) compiles and then
> fails with {{VerifyError}}: the GROOVY-7325 check compared the types the
> wrong way round. {{a.@field = value}} through such a receiver fails
> verification too.
> * with invokedynamic, a dynamic {{new ObjectInputStream()}} in a subclass
> fails with {{GroovyBugError}} ("member is protected") instead of "could not
> access constructor".
> Expected: such members are reached through the meta-class, as in dynamic
> code; code compiled to class files (groovyc, Gradle, Maven, joint
> compilation) keeps direct access, as javac does; the two verification
> failures are compile errors.
> PR: https://github.com/apache/groovy/pull/3097
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)