jenkinsci / groovy-sandbox

(Deprecated) Compile-time transformer to run Groovy code in a restrictive sandbox
MIT License
122 stars 60 forks source link

StackOverflowError on a class method call #64

Open mariuszpala opened 4 years ago

mariuszpala commented 4 years ago

I have a groovy script below which fails with the StackOverflowError

User user = new User();

user.setLoginName("abdc"); // This is ok.
user.getLoginName(); // This line throw error

class User {

private String loginName;
private String userName;
private String description;
private String password;
private String email;
private String locale;
private List groupList;

public List getGroupList(){
return groupList;
}

public void setGroupList(List groupList){
this.groupList = groupList;
}

public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getLocale() {
return locale;
}
public void setLocale(String locale) {
this.locale = locale;
}

}

It fails with the following error:

java.lang.StackOverflowError
    at org.codehaus.groovy.runtime.memoize.UnlimitedConcurrentCache.get(UnlimitedConcurrentCache.java:182)
    at groovy.lang.GroovyClassLoader.getClassCacheEntry(GroovyClassLoader.java:760)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:860)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:979)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:967)
    at groovy.lang.GroovyClassLoader$InnerLoader.loadClass(GroovyClassLoader.java:607)
    at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1918)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3828)
    at groovy.lang.GroovyObject.getProperty(GroovyObject.java:50)
    at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:192)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:468)
    at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:355)
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
    at org.kohsuke.groovy.sandbox.GroovyValueFilter.onGetProperty(GroovyValueFilter.java:73)
    at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:353)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:357)
    at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty$0.callStatic(Unknown Source)
    at User.getLoginName(Script1.groovy:25)
    at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1918)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3828)
    at groovy.lang.GroovyObject.getProperty(GroovyObject.java:50)
    at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:192)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:468)
    at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:355)
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
    at org.kohsuke.groovy.sandbox.GroovyValueFilter.onGetProperty(GroovyValueFilter.java:73)
    at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:353)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:357)
    at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty$0.callStatic(Unknown Source)
    at User.getLoginName(Script1.groovy:25)
    at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1918)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3828)
    at groovy.lang.GroovyObject.getProperty(GroovyObject.java:50)
    at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:192)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:468)
    at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:355)
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
    at org.kohsuke.groovy.sandbox.GroovyValueFilter.onGetProperty(GroovyValueFilter.java:73)
    at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:353)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:357)
    at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty$0.callStatic(Unknown Source)
    at User.getLoginName(Script1.groovy:25)
    at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1918)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3828)
    at groovy.lang.GroovyObject.getProperty(GroovyObject.java:50)
    at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:192)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:468)
    at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:355)
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
    at org.kohsuke.groovy.sandbox.GroovyValueFilter.onGetProperty(GroovyValueFilter.java:73)
dwnusbaum commented 4 years ago

I think the problem is the definition of getLoginName:

public String getLoginName() {
  return loginName; // Replace with `return this.@loginName` as a workaround.
}

A workaround is to use this.@loginName instead of loginName in the method.

The problem is that the sandbox does not track the class that is accessing the property, which Groovy uses to decide when property access should go through the getter method or directly to the field.

This might be the underlying issue causing JENKINS-31484, or there might be two issues, one here and one in groovy-cps.

aazahran commented 1 year ago

Download action repository 'tj-actions/json2file@v1.4.2' (SHA:46d3707a327c0049b276be5977a89354b9310003)