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.

Reply via email to