Skip to content

Commit

Permalink
[FIXED JENKINS-29541] Methods with a GString receiver need to be trea…
Browse files Browse the repository at this point in the history
…ted as a String receiver as a fallback.
  • Loading branch information
jglick committed Aug 4, 2015
1 parent 45f6ad3 commit 3142de1
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 8 deletions.
Expand Up @@ -89,14 +89,13 @@ private static boolean matches(@Nonnull Class<?>[] parameterTypes, @Nonnull Obje
*/
public static @CheckForNull Method method(@Nonnull Object receiver, @Nonnull String method, @Nonnull Object[] args) {
for (Class<?> c : types(receiver)) {
Method candidate = null;
for (Method m : c.getDeclaredMethods()) {
if (m.getName().equals(method) && matches(m.getParameterTypes(), args)) {
if (candidate == null || isMoreSpecific(m, candidate)) {
candidate = m;
}
}
Method candidate = findMatchingMethod(c, method, args);
if (candidate != null) {
return candidate;
}
}
if (receiver instanceof GString) { // cf. GString.invokeMethod
Method candidate = findMatchingMethod(String.class, method, args);
if (candidate != null) {
return candidate;
}
Expand All @@ -115,6 +114,10 @@ private static boolean matches(@Nonnull Class<?>[] parameterTypes, @Nonnull Obje

public static @CheckForNull Method staticMethod(@Nonnull Class<?> receiver, @Nonnull String method, @Nonnull Object[] args) {
// TODO should we check for inherited static calls?
return findMatchingMethod(receiver, method, args);
}

private static Method findMatchingMethod(Class<?> receiver, String method, Object[] args) {
Method candidate = null;
for (Method m : receiver.getDeclaredMethods()) {
if (m.getName().equals(method) && matches(m.getParameterTypes(), args)) {
Expand Down
Expand Up @@ -25,11 +25,14 @@
package org.jenkinsci.plugins.scriptsecurity.sandbox.groovy;

import com.google.common.io.NullOutputStream;
import groovy.lang.GString;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import org.codehaus.groovy.runtime.GStringImpl;
import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.EnumeratingWhitelistTest;
import static org.junit.Assert.*;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;

public class GroovyCallSiteSelectorTest {

Expand All @@ -47,4 +50,12 @@ public class GroovyCallSiteSelectorTest {
assertEquals(PrintWriter.class.getMethod("print", int.class), GroovyCallSiteSelector.method(receiver, "print", new Object[] {42}));
}

@Issue("JENKINS-29541")
@Test public void methodsOnGString() throws Exception {
GStringImpl gString = new GStringImpl(new Object[0], new String[] {"x"});
assertEquals(String.class.getMethod("substring", int.class), GroovyCallSiteSelector.method(gString, "substring", new Object[] {99}));
assertEquals(GString.class.getMethod("getValues"), GroovyCallSiteSelector.method(gString, "getValues", new Object[0]));
assertEquals(GString.class.getMethod("getStrings"), GroovyCallSiteSelector.method(gString, "getStrings", new Object[0]));
}

}
Expand Up @@ -88,7 +88,6 @@ public class SandboxInterceptorTest {
assertEvaluate(new StaticWhitelist("new " + clazz, "method " + clazz + " specialize java.lang.Object", "method " + clazz + " quote java.lang.Object"), expected, script);
}

@Ignore("TODO second line fails with: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (org.codehaus.groovy.runtime.GStringImpl substring java.lang.Integer java.lang.Integer)")
@Issue("JENKINS-29541")
@Test public void substringGString() throws Exception {
assertEvaluate(new GenericWhitelist(), "hell", "'hello world'.substring(0, 4)");
Expand Down

0 comments on commit 3142de1

Please sign in to comment.