The mauve tests that I committed show that we are overly restrictive in
KeyboardFocusManager wrt to thread security. This patch fixes this. We
should add more Mauve tests to check each method for SecurityExceptions.
2006-07-26 Roman Kennke <[EMAIL PROTECTED]>
* java/awt/KeyboardFocusManager.java
(getGlobalFocusOwner): Explicitly check for thread security.
(getGlobalPermanentFocusOwner): Explicitly check for thread security.
(getGlobalFocusedWindow): Explicitly check for thread security.
(getGlobalActiveWindow): Explicitly check for thread security.
(getGlobalCurrentFocusCycleRoot): Explicitly check for thread security.
(getGlobalObject): Added new argument for specifying if
a security check should be performed or not.
(setGlobalObject): Don't check for thread security when
calling getGlobalObject.
/Roman
Index: java/awt/KeyboardFocusManager.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/KeyboardFocusManager.java,v
retrieving revision 1.19
diff -u -1 -2 -r1.19 KeyboardFocusManager.java
--- java/awt/KeyboardFocusManager.java 26 Jul 2006 19:43:59 -0000 1.19
+++ java/awt/KeyboardFocusManager.java 26 Jul 2006 21:11:08 -0000
@@ -311,25 +311,25 @@
* Retrieve the [EMAIL PROTECTED] Component} that has the keyboard focus,
* regardless of whether or not it was set by a thread in the
* current [EMAIL PROTECTED] java.lang.ThreadGroup}. If there is no temporary
* focus owner in effect then this method will return the same value
* as [EMAIL PROTECTED] #getGlobalPermanentFocusOwner}.
*
* @return the keyboard focus owner
* @throws SecurityException if this is not the keyboard focus
* manager associated with the current [EMAIL PROTECTED] java.lang.ThreadGroup}
*/
protected Component getGlobalFocusOwner ()
{
- return (Component) getGlobalObject(currentFocusOwners);
+ return (Component) getGlobalObject(currentFocusOwners, true);
}
/**
* Set the [EMAIL PROTECTED] Component} that will be returned by [EMAIL PROTECTED]
* #getFocusOwner} (when it is called from the current [EMAIL PROTECTED]
* java.lang.ThreadGroup}) and [EMAIL PROTECTED] #getGlobalFocusOwner}. This
* method does not actually transfer the keyboard focus.
*
* @param owner the Component to return from getFocusOwner and
* getGlobalFocusOwner
*
* @see Component#requestFocus()
@@ -394,25 +394,25 @@
/**
* Retrieve the [EMAIL PROTECTED] Component} that has the permanent keyboard
* focus, regardless of whether or not it was set by a thread in the
* current [EMAIL PROTECTED] java.lang.ThreadGroup}.
*
* @return the keyboard focus owner
* @throws SecurityException if this is not the keyboard focus
* manager associated with the current [EMAIL PROTECTED] java.lang.ThreadGroup}
*/
protected Component getGlobalPermanentFocusOwner ()
{
- return (Component) getGlobalObject (currentPermanentFocusOwners);
+ return (Component) getGlobalObject (currentPermanentFocusOwners, true);
}
/**
* Set the [EMAIL PROTECTED] Component} that will be returned by [EMAIL PROTECTED]
* #getPermanentFocusOwner} (when it is called from the current
* [EMAIL PROTECTED] java.lang.ThreadGroup}) and [EMAIL PROTECTED]
* #getGlobalPermanentFocusOwner}. This method does not actually
* transfer the keyboard focus.
*
* @param focusOwner the Component to return from
* getPermanentFocusOwner and getGlobalPermanentFocusOwner
*
@@ -440,25 +440,25 @@
/**
* Retrieve the [EMAIL PROTECTED] Window} that is or contains the focus owner,
* regardless of whether or not the [EMAIL PROTECTED] Window} was set focused
* by a thread in the current [EMAIL PROTECTED] java.lang.ThreadGroup}.
*
* @return the focused window
* @throws SecurityException if this is not the keyboard focus
* manager associated with the current [EMAIL PROTECTED] java.lang.ThreadGroup}
*/
protected Window getGlobalFocusedWindow ()
{
- return (Window) getGlobalObject (currentFocusedWindows);
+ return (Window) getGlobalObject (currentFocusedWindows, true);
}
/**
* Set the [EMAIL PROTECTED] Window} that will be returned by [EMAIL PROTECTED]
* #getFocusedWindow} (when it is called from the current [EMAIL PROTECTED]
* java.lang.ThreadGroup}) and [EMAIL PROTECTED] #getGlobalFocusedWindow}.
* This method does not actually cause <code>window</code> to become
* the focused [EMAIL PROTECTED] Window}.
*
* @param window the Window to return from getFocusedWindow and
* getGlobalFocusedWindow
*/
@@ -482,25 +482,25 @@
/**
* Retrieve the active [EMAIL PROTECTED] Window}, regardless of whether or not
* the [EMAIL PROTECTED] Window} was made active by a thread in the current
* [EMAIL PROTECTED] java.lang.ThreadGroup}.
*
* @return the active window
* @throws SecurityException if this is not the keyboard focus
* manager associated with the current [EMAIL PROTECTED] java.lang.ThreadGroup}
*/
protected Window getGlobalActiveWindow()
{
- return (Window) getGlobalObject (currentActiveWindows);
+ return (Window) getGlobalObject (currentActiveWindows, true);
}
/**
* Set the [EMAIL PROTECTED] Window} that will be returned by [EMAIL PROTECTED]
* #getActiveWindow} (when it is called from the current [EMAIL PROTECTED]
* java.lang.ThreadGroup}) and [EMAIL PROTECTED] #getGlobalActiveWindow}. This
* method does not actually cause <code>window</code> to be made
* active.
*
* @param window the Window to return from getActiveWindow and
* getGlobalActiveWindow
*/
@@ -648,25 +648,25 @@
/**
* Retrieve the current focus cycle root, regardless of whether or
* not it was made set by a thread in the current [EMAIL PROTECTED]
* java.lang.ThreadGroup}.
*
* @return the current focus cycle root
* @throws SecurityException if this is not the keyboard focus
* manager associated with the current [EMAIL PROTECTED] java.lang.ThreadGroup}
*/
protected Container getGlobalCurrentFocusCycleRoot ()
{
- return (Container) getGlobalObject (currentFocusCycleRoots);
+ return (Container) getGlobalObject (currentFocusCycleRoots, true);
}
/**
* Set the [EMAIL PROTECTED] Container} that will be returned by [EMAIL PROTECTED]
* #getCurrentFocusCycleRoot} (when it is called from the current
* [EMAIL PROTECTED] java.lang.ThreadGroup}) and [EMAIL PROTECTED]
* #getGlobalCurrentFocusCycleRoot}. This method does not actually
* make <code>cycleRoot</code> the current focus cycle root.
*
* @param cycleRoot the focus cycle root to return from
* getCurrentFocusCycleRoot and getGlobalCurrentFocusCycleRoot
*/
@@ -1338,35 +1338,37 @@
*
* @return a global object set by the current ThreadGroup, or null
*
* @throws SecurityException if this is not the keyboard focus
* manager associated with the current [EMAIL PROTECTED] java.lang.ThreadGroup}
*
* @see #getGlobalFocusOwner()
* @see #getGlobalPermanentFocusOwner()
* @see #getGlobalFocusedWindow()
* @see #getGlobalActiveWindow()
* @see #getGlobalCurrentFocusCycleRoot()
*/
- private Object getGlobalObject (Map globalMap)
+ private Object getGlobalObject (Map globalMap, boolean checkThread)
{
- ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
- KeyboardFocusManager managerForCallingThread
- = (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
-
- if (this != managerForCallingThread)
- throw new SecurityException ("Attempted to retrieve an object from a "
- + "keyboard focus manager that isn't "
- + "associated with the current thread group.");
+ if (checkThread)
+ {
+ ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+ KeyboardFocusManager managerForCallingThread =
+ (KeyboardFocusManager) currentKeyboardFocusManagers.get(currentGroup);
+ if (this != managerForCallingThread)
+ throw new SecurityException ("Attempted to retrieve an object from a "
+ + "keyboard focus manager that isn't "
+ + "associated with the current thread group.");
+ }
synchronized (globalMap)
{
Collection globalObjects = globalMap.values ();
Iterator i = globalObjects.iterator ();
Component globalObject;
while (i.hasNext ())
{
globalObject = (Component) i.next ();
if (globalObject != null)
return globalObject;
}
@@ -1389,25 +1391,25 @@
* @see #setGlobalPermanentFocusOwner(Component)
* @see #setGlobalFocusedWindow(Window)
* @see #setGlobalActiveWindow(Window)
* @see #setGlobalCurrentFocusCycleRoot(Container)
*/
private void setGlobalObject (Map globalMap,
Object newObject,
String property)
{
synchronized (globalMap)
{
// Save old object.
- Object oldObject = getGlobalObject (globalMap);
+ Object oldObject = getGlobalObject(globalMap, false);
// Nullify old object.
Collection threadGroups = globalMap.keySet ();
Iterator i = threadGroups.iterator ();
while (i.hasNext ())
{
ThreadGroup oldThreadGroup = (ThreadGroup) i.next ();
if (globalMap.get (oldThreadGroup) != null)
{
globalMap.put (oldThreadGroup, null);
// There should only be one object set at a time, so
// we can short circuit.