Skip to content

Commit

Permalink
[JENKINS-64390] make FieldUtils behave as it used to (#5105)
Browse files Browse the repository at this point in the history
Co-authored-by: Jesse Glick <jglick@cloudbees.com>
  • Loading branch information
jtnord and jglick committed Dec 13, 2020
1 parent bdb5dce commit f7884d3
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 2 deletions.
12 changes: 10 additions & 2 deletions core/src/main/java/org/acegisecurity/util/FieldUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

package org.acegisecurity.util;

import java.lang.reflect.Field;

/**
* @deprecated use {@link org.apache.commons.lang.reflect.FieldUtils}
*/
Expand All @@ -40,8 +42,14 @@ public static Object getProtectedFieldValue(String protectedField, Object object

public static void setProtectedFieldValue(String protectedField, Object object, Object newValue) {
try {
org.apache.commons.lang.reflect.FieldUtils.writeField(object, protectedField, newValue, true);
} catch (IllegalAccessException x) {
// acgegi would silently fail to write to final fields
// FieldUtils.writeField(Object, field, true) only sets accessible on *non* public fields
// and then fails with IllegalAccessException (even if you make the field accessible in the interim!
// for backwards compatability we need to use a few steps
Field field = org.apache.commons.lang.reflect.FieldUtils.getField(object.getClass(), protectedField, true);
field.setAccessible(true);
field.set(object, newValue);
} catch (Exception x) {
throw new RuntimeException(x);
}
}
Expand Down
60 changes: 60 additions & 0 deletions core/src/test/java/org/acegisecurity/util/FieldUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.acegisecurity.util;

import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

@SuppressWarnings("deprecation")
public class FieldUtilsTest {

@Issue("JENKINS-64390")
@Test
public void setProtectedFieldValue_Should_fail_silently_to_set_public_final_fields_in_InnerClass() throws Exception {
InnerClassWithPublicFinalField sut = new InnerClassWithPublicFinalField();
FieldUtils.setProtectedFieldValue("myField", sut, "test");
assertEquals(sut.getMyField(), "original");
}

@Test
@Issue("JENKINS-64390")
public void setProtectedFieldValue_Should_fail_silently_to_set_public_final_fields_in_OuterClass() throws Exception {
OuterClassWithPublicFinalField sut = new OuterClassWithPublicFinalField();
FieldUtils.setProtectedFieldValue("myField", sut, "test");
assertEquals(sut.getMyField(), "original");
}

@Test
public void setProtectedFieldValue_Should_Succeed() throws Exception {
InnerClassWithProtectedField sut = new InnerClassWithProtectedField();
FieldUtils.setProtectedFieldValue("myProtectedField", sut, "test");
assertEquals(sut.getMyNonFinalField(), "test");
}

@Test
public void setNonExistingField_Should_Fail() throws Exception {
InnerClassWithProtectedField sut = new InnerClassWithProtectedField();
assertThrows(Exception.class, () -> FieldUtils.setProtectedFieldValue("bogus", sut, "whatever"));
}

class InnerClassWithPublicFinalField {

public final String myField = "original";

public String getMyField() {
return myField;
}

}

public class InnerClassWithProtectedField {

protected String myProtectedField = "original";

public String getMyNonFinalField() {
return myProtectedField;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.acegisecurity.util;

public class OuterClassWithPublicFinalField {

public final String myField = "original";

public String getMyField() {
return myField;
}
}

0 comments on commit f7884d3

Please sign in to comment.