9bfe415f66
Reviewed-by: dholmes, alanb
582 lines
26 KiB
Java
582 lines
26 KiB
Java
/*
|
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/**
|
|
* @test
|
|
* @bug 8277451
|
|
* @run testng NegativeTest
|
|
* @summary Test exception thrown due to bad receiver and bad value on
|
|
* Field with and without setAccessible(true)
|
|
*/
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Modifier;
|
|
|
|
import org.testng.annotations.DataProvider;
|
|
import org.testng.annotations.Test;
|
|
import static org.testng.Assert.*;
|
|
|
|
public class NegativeTest {
|
|
static class Fields {
|
|
public static int si;
|
|
public static char sc;
|
|
public static byte sb;
|
|
public static short ss;
|
|
public static long sl;
|
|
public static double sd;
|
|
public static float sf;
|
|
public static boolean sz;
|
|
public static String so;
|
|
|
|
public static final int sfi = 10;
|
|
public static final char sfc = 'a';
|
|
public static final byte sfb = 1;
|
|
public static final short sfs = 2;
|
|
public static final long sfl = 1000L;
|
|
public static final double sfd = 1.0;
|
|
public static final float sff = 2.0f;
|
|
public static final boolean sfz = true;
|
|
public static final String sfo = "abc";
|
|
|
|
public int i;
|
|
public char c;
|
|
public byte b;
|
|
public short s;
|
|
public long l;
|
|
public double d;
|
|
public float f;
|
|
public boolean z;
|
|
public String o;
|
|
|
|
public final int fi = 10;
|
|
public final char fc = 'a';
|
|
public final byte fb = 1;
|
|
public final short fs = 2;
|
|
public final long fl = 1000L;
|
|
public final double fd = 1.0;
|
|
public final float ff = 2.0f;
|
|
public final boolean fz = true;
|
|
public final String fo = "abc";
|
|
}
|
|
|
|
static final Field i_field = field("i", false);
|
|
static final Field c_field = field("c", false);
|
|
static final Field b_field = field("b", false);
|
|
static final Field s_field = field("s", false);
|
|
static final Field l_field = field("l", false);
|
|
static final Field d_field = field("d", false);
|
|
static final Field f_field = field("f", false);
|
|
static final Field z_field = field("z", false);
|
|
static final Field o_field = field("o", false);
|
|
static final Field fi_field = field("fi", false);
|
|
static final Field fc_field = field("fc", false);
|
|
static final Field fb_field = field("fb", false);
|
|
static final Field fs_field = field("fs", false);
|
|
static final Field fl_field = field("fl", false);
|
|
static final Field fd_field = field("fd", false);
|
|
static final Field ff_field = field("ff", false);
|
|
static final Field fz_field = field("fz", false);
|
|
static final Field fo_field = field("fo", false);
|
|
|
|
static final Field override_i_field = field("i", true);
|
|
static final Field override_c_field = field("c", true);
|
|
static final Field override_b_field = field("b", true);
|
|
static final Field override_s_field = field("s", true);
|
|
static final Field override_l_field = field("l", true);
|
|
static final Field override_d_field = field("d", true);
|
|
static final Field override_f_field = field("f", true);
|
|
static final Field override_z_field = field("z", true);
|
|
static final Field override_o_field = field("o", true);
|
|
static final Field override_fi_field = field("fi", true);
|
|
static final Field override_fc_field = field("fc", true);
|
|
static final Field override_fb_field = field("fb", true);
|
|
static final Field override_fs_field = field("fs", true);
|
|
static final Field override_fl_field = field("fl", true);
|
|
static final Field override_fd_field = field("fd", true);
|
|
static final Field override_ff_field = field("ff", true);
|
|
static final Field override_fz_field = field("fz", true);
|
|
static final Field override_fo_field = field("fo", true);
|
|
|
|
static final Field si_field = field("si", false);
|
|
static final Field sc_field = field("sc", false);
|
|
static final Field sb_field = field("sb", false);
|
|
static final Field ss_field = field("ss", false);
|
|
static final Field sl_field = field("sl", false);
|
|
static final Field sd_field = field("sd", false);
|
|
static final Field sf_field = field("sf", false);
|
|
static final Field sz_field = field("sz", false);
|
|
static final Field so_field = field("so", false);
|
|
static final Field sfi_field = field("sfi", false);
|
|
static final Field sfc_field = field("sfc", false);
|
|
static final Field sfb_field = field("sfb", false);
|
|
static final Field sfs_field = field("sfs", false);
|
|
static final Field sfl_field = field("sfl", false);
|
|
static final Field sfd_field = field("sfd", false);
|
|
static final Field sff_field = field("sff", false);
|
|
static final Field sfz_field = field("sfz", false);
|
|
static final Field sfo_field = field("sfo", false);
|
|
|
|
static final Field override_si_field = field("si", true);
|
|
static final Field override_sc_field = field("sc", true);
|
|
static final Field override_sb_field = field("sb", true);
|
|
static final Field override_ss_field = field("ss", true);
|
|
static final Field override_sl_field = field("sl", true);
|
|
static final Field override_sd_field = field("sd", true);
|
|
static final Field override_sf_field = field("sf", true);
|
|
static final Field override_sz_field = field("sz", true);
|
|
static final Field override_so_field = field("so", true);
|
|
static final Field override_sfi_field = field("sfi", true);
|
|
static final Field override_sfc_field = field("sfc", true);
|
|
static final Field override_sfb_field = field("sfb", true);
|
|
static final Field override_sfs_field = field("sfs", true);
|
|
static final Field override_sfl_field = field("sfl", true);
|
|
static final Field override_sfd_field = field("sfd", true);
|
|
static final Field override_sff_field = field("sff", true);
|
|
static final Field override_sfz_field = field("sfz", true);
|
|
static final Field override_sfo_field = field("sfo", true);
|
|
|
|
private static Field field(String name, boolean suppressAccessCheck) {
|
|
try {
|
|
Field f = Fields.class.getDeclaredField(name);
|
|
if (suppressAccessCheck) {
|
|
f.setAccessible(true);
|
|
}
|
|
return f;
|
|
} catch (ReflectiveOperationException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@DataProvider(name = "instanceFields")
|
|
private Object[][] instanceFields() {
|
|
return new Object[][]{
|
|
new Object[]{i_field},
|
|
new Object[]{c_field},
|
|
new Object[]{b_field},
|
|
new Object[]{s_field},
|
|
new Object[]{l_field},
|
|
new Object[]{d_field},
|
|
new Object[]{f_field},
|
|
new Object[]{z_field},
|
|
new Object[]{o_field},
|
|
new Object[]{override_i_field},
|
|
new Object[]{override_c_field},
|
|
new Object[]{override_b_field},
|
|
new Object[]{override_s_field},
|
|
new Object[]{override_l_field},
|
|
new Object[]{override_d_field},
|
|
new Object[]{override_f_field},
|
|
new Object[]{override_z_field},
|
|
new Object[]{override_o_field},
|
|
// final instance fields
|
|
new Object[]{fi_field},
|
|
new Object[]{fc_field},
|
|
new Object[]{fb_field},
|
|
new Object[]{fs_field},
|
|
new Object[]{fl_field},
|
|
new Object[]{fd_field},
|
|
new Object[]{ff_field},
|
|
new Object[]{fz_field},
|
|
new Object[]{fo_field},
|
|
new Object[]{override_fi_field},
|
|
new Object[]{override_fc_field},
|
|
new Object[]{override_fb_field},
|
|
new Object[]{override_fs_field},
|
|
new Object[]{override_fl_field},
|
|
new Object[]{override_fd_field},
|
|
new Object[]{override_ff_field},
|
|
new Object[]{override_fz_field},
|
|
new Object[]{override_fo_field},
|
|
};
|
|
}
|
|
private static Fields INSTANCE = new Fields();
|
|
|
|
/*
|
|
* Test Field::get on a good receiver, a bad receiver and null.
|
|
*
|
|
* IllegalArgumentException is thrown if the receiver is of
|
|
* a bad type. NullPointerException is thrown if the receiver is null.
|
|
*/
|
|
@Test(dataProvider = "instanceFields")
|
|
public void testReceiver(Field f) throws ReflectiveOperationException {
|
|
f.get(INSTANCE); // good receiver
|
|
|
|
testBadReceiver(f);
|
|
testNullReceiver(f);
|
|
}
|
|
|
|
/*
|
|
* IllegalArgumentException should be thrown for bad receiver type
|
|
*/
|
|
private void testBadReceiver(Field f) throws ReflectiveOperationException {
|
|
assertFalse(Modifier.isStatic(f.getModifiers())); // instance field
|
|
Object badObj = new NegativeTest();
|
|
try {
|
|
f.get(badObj);
|
|
fail("expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException e) {
|
|
// expected
|
|
}
|
|
Class<?> fType = f.getType();
|
|
if (fType.isPrimitive()) {
|
|
try {
|
|
switch (fType.descriptorString()) {
|
|
case "B" -> f.getByte(badObj);
|
|
case "C" -> f.getChar(badObj);
|
|
case "D" -> f.getDouble(badObj);
|
|
case "F" -> f.getFloat(badObj);
|
|
case "I" -> f.getInt(badObj);
|
|
case "J" -> f.getLong(badObj);
|
|
case "S" -> f.getShort(badObj);
|
|
case "Z" -> f.getBoolean(badObj);
|
|
}
|
|
fail("expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException e) {
|
|
// expected
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* NullPointerException should be thrown for null receiver
|
|
*/
|
|
private void testNullReceiver(Field f) throws ReflectiveOperationException {
|
|
assertFalse(Modifier.isStatic(f.getModifiers())); // instance field
|
|
try {
|
|
f.get(null);
|
|
fail("expected NullPointerException");
|
|
} catch (NullPointerException e) {
|
|
// expected
|
|
}
|
|
|
|
Class<?> fType = f.getType();
|
|
if (fType.isPrimitive()) {
|
|
try {
|
|
switch (fType.descriptorString()) {
|
|
case "B" -> f.getByte(null);
|
|
case "C" -> f.getChar(null);
|
|
case "D" -> f.getDouble(null);
|
|
case "F" -> f.getFloat(null);
|
|
case "I" -> f.getInt(null);
|
|
case "J" -> f.getLong(null);
|
|
case "S" -> f.getShort(null);
|
|
case "Z" -> f.getBoolean(null);
|
|
}
|
|
fail("expected NullPointerException");
|
|
} catch (NullPointerException e) {
|
|
// expected
|
|
}
|
|
}
|
|
}
|
|
|
|
@DataProvider(name = "writeableFields")
|
|
private Object[][] writeableFields() {
|
|
Fields obj = new Fields();
|
|
return new Object[][]{
|
|
// instance fields with and without setAccessible(true)
|
|
new Object[]{i_field, obj, Integer.valueOf(10)},
|
|
new Object[]{c_field, obj, Character.valueOf('c')},
|
|
new Object[]{b_field, obj, Byte.valueOf((byte)1)},
|
|
new Object[]{s_field, obj, Short.valueOf((short)2)},
|
|
new Object[]{l_field, obj, Long.valueOf(1000)},
|
|
new Object[]{d_field, obj, Double.valueOf(1.2)},
|
|
new Object[]{f_field, obj, Float.valueOf(2.5f)},
|
|
new Object[]{z_field, obj, Boolean.valueOf(true)},
|
|
new Object[]{o_field, obj, "good-value"},
|
|
new Object[]{override_i_field, obj, Integer.valueOf(10)},
|
|
new Object[]{override_c_field, obj, Character.valueOf('c')},
|
|
new Object[]{override_b_field, obj, Byte.valueOf((byte)1)},
|
|
new Object[]{override_s_field, obj, Short.valueOf((short)2)},
|
|
new Object[]{override_l_field, obj, Long.valueOf(1000)},
|
|
new Object[]{override_d_field, obj, Double.valueOf(1.2)},
|
|
new Object[]{override_f_field, obj, Float.valueOf(2.5f)},
|
|
new Object[]{override_z_field, obj, Boolean.valueOf(true)},
|
|
new Object[]{override_o_field, obj, "good-value"},
|
|
// instance final fields with setAccessible(true)
|
|
new Object[]{override_fi_field, obj, Integer.valueOf(10)},
|
|
new Object[]{override_fc_field, obj, Character.valueOf('c')},
|
|
new Object[]{override_fb_field, obj, Byte.valueOf((byte)1)},
|
|
new Object[]{override_fs_field, obj, Short.valueOf((short)2)},
|
|
new Object[]{override_fl_field, obj, Long.valueOf(1000)},
|
|
new Object[]{override_fd_field, obj, Double.valueOf(1.2)},
|
|
new Object[]{override_ff_field, obj, Float.valueOf(2.5f)},
|
|
new Object[]{override_fz_field, obj, Boolean.valueOf(true)},
|
|
new Object[]{override_fo_field, obj, "good-value"},
|
|
// static fields with and without setAccessible(true)
|
|
new Object[]{si_field, null, Integer.valueOf(10)},
|
|
new Object[]{sc_field, null, Character.valueOf('c')},
|
|
new Object[]{sb_field, null, Byte.valueOf((byte)1)},
|
|
new Object[]{ss_field, null, Short.valueOf((short)2)},
|
|
new Object[]{sl_field, null, Long.valueOf(1000)},
|
|
new Object[]{sd_field, null, Double.valueOf(1.2)},
|
|
new Object[]{sf_field, null, Float.valueOf(2.5f)},
|
|
new Object[]{sz_field, null, Boolean.valueOf(true)},
|
|
new Object[]{so_field, null, "good-value"},
|
|
new Object[]{override_si_field, null, Integer.valueOf(10)},
|
|
new Object[]{override_sc_field, null, Character.valueOf('c')},
|
|
new Object[]{override_sb_field, null, Byte.valueOf((byte)1)},
|
|
new Object[]{override_ss_field, null, Short.valueOf((short)2)},
|
|
new Object[]{override_sl_field, null, Long.valueOf(1000)},
|
|
new Object[]{override_sd_field, null, Double.valueOf(1.2)},
|
|
new Object[]{override_sf_field, null, Float.valueOf(2.5f)},
|
|
new Object[]{override_sz_field, null, Boolean.valueOf(true)},
|
|
new Object[]{override_so_field, null, "good-value"},
|
|
};
|
|
}
|
|
|
|
/*
|
|
* Test Field::set with a good and bad value.
|
|
* Test setting to null if the field type is primitive.
|
|
*
|
|
* IllegalArgumentException is thrown if the value is of a bad type or null.
|
|
* NullPointerException is thrown if the receiver of an instance field is null.
|
|
* The receiver is checked
|
|
*/
|
|
@Test(dataProvider = "writeableFields")
|
|
public void testSetValue(Field f, Object obj, Object value) throws IllegalAccessException {
|
|
f.set(obj, value);
|
|
Class<?> fType = f.getType();
|
|
if (fType.isPrimitive()) {
|
|
switch (fType.descriptorString()) {
|
|
case "B" -> f.setByte(obj, ((Byte) value).byteValue());
|
|
case "C" -> f.setChar(obj, ((Character) value).charValue());
|
|
case "D" -> f.setDouble(obj, ((Double) value).doubleValue());
|
|
case "F" -> f.setFloat(obj, ((Float) value).floatValue());
|
|
case "I" -> f.setInt(obj, ((Integer) value).intValue());
|
|
case "J" -> f.setLong(obj, ((Long) value).longValue());
|
|
case "S" -> f.setShort(obj, ((Short) value).shortValue());
|
|
case "Z" -> f.setBoolean(obj, ((Boolean) value).booleanValue());
|
|
}
|
|
|
|
// test null value only if it's primitive type
|
|
try {
|
|
f.set(obj, null);
|
|
fail("expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException e) {
|
|
// expected
|
|
}
|
|
}
|
|
|
|
Object badValue = new NegativeTest();
|
|
try {
|
|
f.set(obj, badValue);
|
|
fail("expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException e) {
|
|
// expected
|
|
}
|
|
}
|
|
|
|
@DataProvider(name = "readOnlyFinalFields")
|
|
private Object[][] readOnlyFinalFields() {
|
|
Object obj = INSTANCE;
|
|
return new Object[][]{
|
|
// instance final fields
|
|
new Object[]{fi_field, obj, Integer.valueOf(10)},
|
|
new Object[]{fc_field, obj, Character.valueOf('c')},
|
|
new Object[]{fb_field, obj, Byte.valueOf((byte)1)},
|
|
new Object[]{fs_field, obj, Short.valueOf((short)2)},
|
|
new Object[]{fl_field, obj, Long.valueOf(1000)},
|
|
new Object[]{fd_field, obj, Double.valueOf(1.2)},
|
|
new Object[]{ff_field, obj, Float.valueOf(2.5f)},
|
|
new Object[]{fz_field, obj, Boolean.valueOf(true)},
|
|
new Object[]{fo_field, obj, "good-value"},
|
|
// static final fields
|
|
new Object[]{sfi_field, null, Integer.valueOf(10)},
|
|
new Object[]{sfc_field, null, Character.valueOf('c')},
|
|
new Object[]{sfb_field, null, Byte.valueOf((byte)1)},
|
|
new Object[]{sfs_field, null, Short.valueOf((short)2)},
|
|
new Object[]{sfl_field, null, Long.valueOf(1000)},
|
|
new Object[]{sfd_field, null, Double.valueOf(1.2)},
|
|
new Object[]{sff_field, null, Float.valueOf(2.5f)},
|
|
new Object[]{sfz_field, null, Boolean.valueOf(true)},
|
|
new Object[]{sfo_field, null, "good-value"},
|
|
new Object[]{override_sfi_field, null, Integer.valueOf(10)},
|
|
new Object[]{override_sfc_field, null, Character.valueOf('c')},
|
|
new Object[]{override_sfb_field, null, Byte.valueOf((byte)1)},
|
|
new Object[]{override_sfs_field, null, Short.valueOf((short)2)},
|
|
new Object[]{override_sfl_field, null, Long.valueOf(1000)},
|
|
new Object[]{override_sfd_field, null, Double.valueOf(1.2)},
|
|
new Object[]{override_sff_field, null, Float.valueOf(2.5f)},
|
|
new Object[]{override_sfz_field, null, Boolean.valueOf(true)},
|
|
new Object[]{override_sfo_field, null, "good-value"},
|
|
};
|
|
}
|
|
|
|
/*
|
|
* Test Field::set on a read-only final field.
|
|
* IllegalAccessException is thrown regardless of whether the value
|
|
* is of a bad type or not.
|
|
*/
|
|
@Test(dataProvider = "readOnlyFinalFields")
|
|
public void testSetValueOnFinalField(Field f, Object obj, Object value) {
|
|
assertTrue(Modifier.isFinal(f.getModifiers()));
|
|
try {
|
|
f.set(obj, value);
|
|
fail("expected IllegalAccessException");
|
|
} catch (IllegalAccessException e) {
|
|
// expected
|
|
}
|
|
|
|
Class<?> fType = f.getType();
|
|
if (fType.isPrimitive()) {
|
|
try {
|
|
switch (fType.descriptorString()) {
|
|
case "B" -> f.setByte(obj, ((Byte)value).byteValue());
|
|
case "C" -> f.setChar(obj, ((Character)value).charValue());
|
|
case "D" -> f.setDouble(obj, ((Double)value).doubleValue());
|
|
case "F" -> f.setFloat(obj, ((Float)value).floatValue());
|
|
case "I" -> f.setInt(obj, ((Integer)value).intValue());
|
|
case "J" -> f.setLong(obj, ((Long)value).longValue());
|
|
case "S" -> f.setShort(obj, ((Short)value).shortValue());
|
|
case "Z" -> f.setBoolean(obj, ((Boolean)value).booleanValue());
|
|
}
|
|
fail("expected IllegalAccessException");
|
|
} catch (IllegalAccessException e) {
|
|
// expected
|
|
}
|
|
|
|
// test null value only if it's primitive type
|
|
try {
|
|
f.set(obj, null);
|
|
fail("expected IllegalAccessException");
|
|
} catch (IllegalAccessException e) {
|
|
// expected
|
|
}
|
|
}
|
|
|
|
Object badValue = new NegativeTest();
|
|
try {
|
|
f.set(obj, badValue);
|
|
fail("expected IllegalAccessException");
|
|
} catch (IllegalAccessException e) {
|
|
// expected
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@DataProvider(name = "finalInstanceFields")
|
|
private Object[][] finalInstanceFields() {
|
|
return new Object[][]{
|
|
new Object[]{fi_field, Integer.valueOf(10)},
|
|
new Object[]{fc_field, Character.valueOf('c')},
|
|
new Object[]{fb_field, Byte.valueOf((byte) 1)},
|
|
new Object[]{fs_field, Short.valueOf((short) 2)},
|
|
new Object[]{fl_field, Long.valueOf(1000)},
|
|
new Object[]{fd_field, Double.valueOf(1.2)},
|
|
new Object[]{ff_field, Float.valueOf(2.5f)},
|
|
new Object[]{fz_field, Boolean.valueOf(true)},
|
|
new Object[]{fo_field, "good-value"},
|
|
};
|
|
}
|
|
|
|
/*
|
|
* Test Field::set on a final instance field with either a bad receiver
|
|
* or null. IllegalArgumentException is thrown if the receiver is of
|
|
* a bad type. NullPointerException is thrown if the receiver is null.
|
|
* The receiver is checked before the access check is performed and
|
|
* also before the value is checked.
|
|
*/
|
|
@Test(dataProvider = "finalInstanceFields")
|
|
public void testReceiverOnFinalField(Field f, Object value) {
|
|
assertTrue(Modifier.isFinal(f.getModifiers()));
|
|
Object badReceiver = new NegativeTest();
|
|
// set the field with a bad receiver with a good value
|
|
try {
|
|
f.set(badReceiver, value);
|
|
fail("expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException e) {
|
|
// expected
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e);
|
|
}
|
|
|
|
// set the field with a bad receiver with a bad value
|
|
Object badValue = new NegativeTest();
|
|
try {
|
|
f.set(badReceiver, badValue);
|
|
fail("expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException e) {
|
|
// expected
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e);
|
|
}
|
|
|
|
// set the field with a null receiver with a good value
|
|
try {
|
|
f.set(null, value);
|
|
fail("expected NullPointerException");
|
|
} catch (NullPointerException e) {
|
|
// expected
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e);
|
|
}
|
|
// set the field with a null receiver with a bad value
|
|
try {
|
|
f.set(null, badValue);
|
|
fail("expected NullPointerException");
|
|
} catch (NullPointerException e) {
|
|
// expected
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e);
|
|
}
|
|
|
|
Class<?> fType = f.getType();
|
|
if (fType.isPrimitive()) {
|
|
// test bad receiver
|
|
try {
|
|
switch (fType.descriptorString()) {
|
|
case "B" -> f.setByte(badReceiver, ((Byte) value).byteValue());
|
|
case "C" -> f.setChar(badReceiver, ((Character) value).charValue());
|
|
case "D" -> f.setDouble(badReceiver, ((Double) value).doubleValue());
|
|
case "F" -> f.setFloat(badReceiver, ((Float) value).floatValue());
|
|
case "I" -> f.setInt(badReceiver, ((Integer) value).intValue());
|
|
case "J" -> f.setLong(badReceiver, ((Long) value).longValue());
|
|
case "S" -> f.setShort(badReceiver, ((Short) value).shortValue());
|
|
case "Z" -> f.setBoolean(badReceiver, ((Boolean) value).booleanValue());
|
|
}
|
|
} catch (IllegalArgumentException e) {
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e);
|
|
}
|
|
// test null receiver
|
|
try {
|
|
switch (fType.descriptorString()) {
|
|
case "B" -> f.setByte(null, ((Byte) value).byteValue());
|
|
case "C" -> f.setChar(null, ((Character) value).charValue());
|
|
case "D" -> f.setDouble(null, ((Double) value).doubleValue());
|
|
case "F" -> f.setFloat(null, ((Float) value).floatValue());
|
|
case "I" -> f.setInt(null, ((Integer) value).intValue());
|
|
case "J" -> f.setLong(null, ((Long) value).longValue());
|
|
case "S" -> f.setShort(null, ((Short) value).shortValue());
|
|
case "Z" -> f.setBoolean(null, ((Boolean) value).booleanValue());
|
|
}
|
|
} catch (NullPointerException e) {
|
|
// expected
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e);
|
|
}
|
|
}
|
|
}
|
|
}
|