Over the weekend I looked a bit at ResourceBundle usage in Calendar etc again.

The problem:

Various classes, such as Calendar, need to load Locale information from ResourceBundles. The ResourceBundle.getBundle() calls are frequent enough, eg every time a Calendar instance is created, and sometimes every time certain calls are made, that the calling-classloader check performed by getBundle can be a significant performance issue. To avoid this check, we use the 3-argument form of getBundle(), which includes an explicit ClassLoader argument.

However, getting the classloader argument for getBundle() can be a problem. Currently we use the system classloader as returned by getSystemClassLoader() (using something like Calendar.class.getClassLoader() unfortunately doesn't work because that may return "null" for the system classloader, and null is not a valid argument for getBundle() ). But, getSystemClassLoader is a privileged call and requires an AccessController.doPrivileged() to call safely in a secure environment.

Rather than having to add an AccessController.doPrivilaged() to every getBundle() call in every class that uses Locale data, I wondered if we can use a "LocaleHelper" class to cache the system classloader and simplify locale bundle lookups from the classes that need access to them.

My question is - could the LocaleHelper class be a security problem? As far as I can tell it isn't - the worst that can happen is that untrusted code could load a ResourceBundle using the system classloader, but since getBundle() itself is not a privileged call, and getBundle() is not called with elevated privileges anyway, I don't see any problems there. The code could do the same thing by calling getBundle() directly. Have I missed anything?

Bryce


/* LocaleHelper.java
   Copyright (C) 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.locale;

import java.security.AccessController;
import java.security.PrivilegedAction;
import gnu.java.security.action.GetSystemClassLoaderAction;

/**
 * This class provides a convienient interface to access Locale information.
 */
public class LocaleHelper
{
  /** The system classloader is used to load Locale resource bundles. Passing
   *  this to ResourceBundle.getBundle() explicitly avoids a potentially
   *  expensive calling-classloader check. */
  private static ClassLoader systemClassLoader;
  
  static
  {
    PrivilegedAction action = new GetSystemClassLoaderAction();
    systemClassLoader = (ClassLoader) AccessController.doPrivileged(action);
  }
  
  /** Retrieve LocaleInformation ResourceBundle for the given locale.  */
  public static ResourceBundle getLocaleInformation(Locale locale)
  {
    return ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", 
				    locale, systemClassLoader);
  }

  /** Retrieve Calendar ResourceBundle for the given locale.  */
  public static ResourceBundle getCalendar(Locale locale)
  {
    return ResourceBundle.getBundle("gnu.java.locale.Calendar", 
				    locale, systemClassLoader);
  }
}
_______________________________________________
Classpath mailing list
[EMAIL PROTECTED]
http://lists.gnu.org/mailman/listinfo/classpath

Reply via email to