Created
February 17, 2022 06:27
-
-
Save jocopa3/0f7effc520f7510bbaf5799dcc56a329 to your computer and use it in GitHub Desktop.
Inspired by similar magic tricks to make 2+2=5 through messing with IntegerCache, I present two more devious tricks to make booleans behave in unexpected ways.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sun.misc.Unsafe; | |
import java.lang.reflect.Field; | |
public class BooleanMagic { | |
private static void doImpossibleBool() { | |
boolean impossible = ImpossibleBool.IMPOSSIBLE_BOOL; | |
if (impossible == true) { | |
System.out.println("Value was true"); | |
} else if (impossible == false) { | |
System.out.println("Value was false"); | |
} else if (impossible == impossible) { | |
System.out.println("Value was impossible"); | |
} | |
} | |
private static void doOppositeDay() { | |
makeOppositeDay(); | |
Boolean alwaysTrue = true; | |
if (alwaysTrue) { | |
System.out.println("The world is normal"); | |
} else { | |
System.out.println("Today is opposite day"); | |
} | |
System.out.println("True = " + Boolean.valueOf(true)); | |
System.out.println("False = " + Boolean.valueOf(false)); | |
} | |
public static void main(String[] args) throws Exception { | |
doImpossibleBool(); | |
System.out.println(); | |
doOppositeDay(); | |
} | |
private static void makeOppositeDay() { | |
try { | |
Field theUnsafe = Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe"); | |
theUnsafe.setAccessible(true); | |
Unsafe unsafe = (Unsafe) theUnsafe.get(null); | |
// Overwrite the raw value of "true" to false | |
unsafe.putByte(Boolean.TRUE, unsafe.objectFieldOffset(Boolean.class.getDeclaredField("value")), (byte) 0); | |
// Overwrite the raw value of "false" to true | |
unsafe.putByte(Boolean.FALSE, unsafe.objectFieldOffset(Boolean.class.getDeclaredField("value")), (byte) 1); | |
} catch (Exception ignore) {} | |
} | |
private static class ImpossibleBool { | |
// This cannot be final or passed in a method otherwise it'll become a compile-time constant or lose its modified value | |
public static boolean IMPOSSIBLE_BOOL = true; | |
static { | |
try { | |
Field theUnsafe = Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe"); | |
theUnsafe.setAccessible(true); | |
Unsafe unsafe = (Unsafe) theUnsafe.get(null); | |
// Setting a boolean value to 2 makes any direct comparisons against other booleans (0 or 1) always false | |
// Regular conditonal checks like if (IMPOSSIBLE_BOOL) will behave as if the value is true | |
unsafe.putInt(ImpossibleBool.class, unsafe.staticFieldOffset(ImpossibleBool.class.getDeclaredField("IMPOSSIBLE_BOOL")), 2); | |
} catch (Exception ignore) {} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment