classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug fix in java.lang.Boolean


From: Eric Blake
Subject: Bug fix in java.lang.Boolean
Date: Fri, 13 Jul 2001 10:22:09 +0100

Consider this program:

import java.lang.reflect.*;
class Foo
{
    static void print()
    {
        System.out.println("true == " + Boolean.TRUE);
        System.out.println("false == " + Boolean.FALSE);
    }
    public static void main(String[] args)
    {
        print();
        try
        {
            Field value = Boolean.class.getDeclaredField("value");
            value.setAccessible(true);
            value.setBoolean(Boolean.TRUE, false);
            value.setBoolean(Boolean.FALSE, true);
        catch (SecurityException se)
        {
            System.out.println("This requires generous reflection
permissions, " +
                                 "such as the default ones provided by the JDK 
" +
                               "for single-user use.");
        }
        catch (Exception e)
        {
            System.out.println("Caught: " + e);
        }
        print();
    }
}

Unless java.lang.Boolean.value is final, reflection is free to modify the
field given sufficient permission.  On the other hand, if it is final,
reflection will fail with an IllegalAccessException: field is final.  This
is not a problem for applets, which do not have permissions to change
reflection accessibility, but is for default permissions granted to
single-user use.  Immutable objects must be immutable!  Classpath ought to
have better security than Sun, so here is the patch for Boolean.  Since I
don't have direct CVS access, the diff is against a version downloaded from
WebCVS.

I imagine that several other parts of the classpath library suffer from this
malady (in particular, we need to make sure that reflection cannot be used
to change how reflection will behave - with enough reflection hacking on
Sun's library, I was able to make Foo.class.newInstance() create an instance
of an unrelated class Bar, by changing the fields in the appropriate
java.lang.reflect.Constructor object).  I would work more on this issue, but
I have not signed the paperwork to contribute anything larger.

My other patches were just quickie optimizations.  equalsIgnoreCase already
does the required null check, without throwing a NullPointerException.
--
Eric Blake, Elixent, Castlemead, Lwr Castle St., Bristol BS1 3AG, UK
address@hidden   tel:+44(0)117 917 5611


2001-07-13  Eric Blake  <address@hidden>

        * java/lang/Boolean.java (value): Make final.
        (Boolean String): Optimize string comparison.
        (getBoolean String): idem

--- classpath/java/lang/Boolean.java.orig       Fri Jul 13 09:46:53 2001
+++ classpath/java/lang/Boolean.java    Fri Jul 13 09:50:58 2001
@@ -62,7 +62,11 @@
      */
     public static final Class TYPE =
VMClassLoader.getPrimitiveClass("boolean");

-    private boolean value;
+    /**
+     * The value of this wrapper object. It is final, so that reflection
+     * cannot change it.
+     */
+    private final boolean value;

     /**
      * Create a <code>Boolean</code> object representing the value of the
@@ -88,7 +92,7 @@
      *   or false
      */
     public Boolean(String s) {
-       value = (s != null && s.equalsIgnoreCase("true"));
+       value = "true".equalsIgnoreCase(s);
     }

     /**
@@ -149,7 +153,7 @@
      */
     public static boolean getBoolean(String name) {
        String val = System.getProperty(name);
-       return (val != null && val.equalsIgnoreCase("true"));
+       return "true".equalsIgnoreCase(val);
     }

     /**




reply via email to

[Prev in Thread] Current Thread [Next in Thread]