Scott Murphy Heiberg created GROOVY-12680:
---------------------------------------------
Summary: A closure's metaclass reads and overwrites private fields
of groovy.lang.Closure
Key: GROOVY-12680
URL: https://issues.apache.org/jira/browse/GROOVY-12680
Project: Groovy
Issue Type: Bug
Affects Versions: 5.0.8, 4.0.33, 6.0.0, 7.0.0-alpha-1
Reporter: Scott Murphy Heiberg
{code:groovy}
def c = { -> 1 }
assert c.metaClass.getProperty(c, 'bcw') == null
assert c.metaClass.getProperty(c, 'serialVersionUID') == 4368710879820278874L
assert c.metaClass.getMetaProperty('thisType') != null
c.metaClass.setProperty(c, 'thisType', String) // overwrites Closure's
private field
class C {
private secret = 'C'
def read() {
Closure c = { -> secret }
c.metaClass.setProperty(c, 'thisType', Object)
c()
}
}
class D extends C {}
new D().read()
{code}
*Actual:* getProperty returns the values of the private fields bcw,
serialVersionUID, thisType, mopPerturbed and PROPERTY_GETTERS of Closure, also
under capitalised names such as ThisType. getMetaProperty and hasProperty
return them. setProperty overwrites thisType and mopPerturbed. After thisType
is overwritten, the last line fails with "No such property: secret for class:
D". With the TO_SELF resolve strategy, plain {{c.thisType = String}} does the
same.
*Expected:* MissingPropertyException from getProperty and setProperty, and null
from getMetaProperty and hasProperty, as the metaclass of any other subclass
gives for its superclass's private fields.
ClosureMetaClass delegates property access to a MetaClassImpl of Closure
itself, which indexes Closure's own private members. A generated closure class
does not inherit them. Related: GROOVY-12675 (the same members in
getProperties).
Verified: 5.0.8, 6.0.0 and master (including the setProperty overwrite of
thisType); 4.0.33 read side only (bcw and serialVersionUID).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)