changeset 5227:67b0664167d6

RT-33103: Children may change, iterate over a copy. Reviewed by paru
author David Grieve<david.grieve@oracle.com>
date Wed, 02 Oct 2013 14:53:01 -0400
parents 6204306cde59
children 31c7ced6e2e6
files modules/graphics/src/main/java/javafx/scene/Parent.java
diffstat 1 files changed, 21 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/javafx/scene/Parent.java	Wed Oct 02 10:56:51 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Parent.java	Wed Oct 02 14:53:01 2013 -0400
@@ -1216,9 +1216,28 @@
         // Let the super implementation handle CSS for this node
         super.impl_processCSS();
 
+        // avoid the following call to children.toArray if there are no children
+        if (children.isEmpty()) return;
+
+        //
+        // RT-33103
+        //
+        // It is possible for a child to be removed from children in the middle of
+        // the following loop. Iterating over the children may result in an IndexOutOfBoundsException.
+        // So a copy is made and the copy is iterated over.
+        //
+        // Note that we don't want the fail-fast feature of an iterator, not to mention the general iterator overhead.
+        //
+        final Node[] childArray = children.toArray(new Node[children.size()]);
+
         // For each child, process CSS
-        for (int i=0, max=children.size(); i<max; i++) {
-            final Node child = children.get(i);
+        for (int i=0; i<childArray.length; i++) {
+
+            final Node child = childArray[i];
+
+            //  If a child no longer has this as its parent, then it is skipped.
+            final Parent childParent = child.getParent();
+            if (childParent == null || childParent != this) continue;
 
             // If the parent styles are being updated, recalculated or
             // reapplied, then make sure the children get the same treatment.