This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit acab343f73b939bb3b28a13f9142cba4f799104a
Author: greg-dove <greg.d...@gmail.com>
AuthorDate: Wed Apr 6 13:41:58 2022 +1200

    Avoid the possibility of infinite loops (in JS only, SWF untested) with xml 
watchers. This can happen if changes are made in watcher functions.
---
 .../src/main/royale/mx/utils/XMLNotifier.as        | 71 ++++++++++++++++++----
 1 file changed, 59 insertions(+), 12 deletions(-)

diff --git 
a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/XMLNotifier.as 
b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/XMLNotifier.as
index 5bc8a13fa1..c4d033b476 100644
--- a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/XMLNotifier.as
+++ b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/XMLNotifier.as
@@ -20,10 +20,14 @@
 package mx.utils
 {
 
-import org.apache.royale.utils.ObjectMap;
+//import org.apache.royale.utils.ObjectMap;
 import mx.core.mx_internal;
 import mx.utils.IXMLNotifiable;
 
+COMPILE::SWF{
+    import flash.utils.Dictionary;
+}
+
 use namespace mx_internal;
 
 /**
@@ -98,13 +102,32 @@ public class XMLNotifier
             {
                 callee = notificationFunction;
             }
-            var xmlWatchers:ObjectMap = callee["watched"];
-            if (xmlWatchers != null)
-            {
-                xmlWatchers.forEach( 
function(truevalue:Object,notifiable:Object,map:Object):void {
+            //var xmlWatchers:ObjectMap = callee["watched"];
+
+            COMPILE::SWF{
+                var xmlWatchers:Dictionary = callee["watched"];
+                for (var notifiable:Object in xmlWatchers) {
                     IXMLNotifiable(notifiable).xmlNotification(currentTarget, 
ty, tar, value, detail);
-                } );
+                }
             }
+
+            COMPILE::JS{
+                var xmlWatchers:Map = callee["watched"];
+                if (xmlWatchers != null)
+                {
+                    var collected:Array = [];
+                    //note, if we don't collect these first and try to iterate 
directly, then there can be the case that iterating is infinite if the function 
caLL also somehow affects the xmlWatchers Map:
+                    xmlWatchers.forEach( 
function(truevalue:Object,notifiable:Object,map:Object):void {
+                        collected.push(notifiable);
+                    } );
+
+                    while(collected.length){
+                        
IXMLNotifiable(collected.shift()).xmlNotification(currentTarget, ty, tar, 
value, detail);
+                    }
+                }
+            }
+
+
         }
 
         return notificationFunction;
@@ -181,13 +204,25 @@ public class XMLNotifier
             }
 
             // Watch lists are maintained on the notification function.
-            var xmlWatchers:ObjectMap;
-            if (watcherFunction["watched"] == undefined)
-                watcherFunction["watched"] = xmlWatchers = new 
ObjectMap(true,true);
+            if (watcherFunction["watched"] == undefined) {
+               // watcherFunction["watched"] = xmlWatchers = new 
ObjectMap(true,true);
+                COMPILE::SWF{
+                    var xmlWatchers:Dictionary = watcherFunction["watched"] = 
new Dictionary();
+                }
+
+                COMPILE::JS{
+                    var xmlWatchers:Map= watcherFunction["watched"] = new 
Map();
+                }
+            }
             else
                 xmlWatchers = watcherFunction["watched"];
 
-            xmlWatchers.set(notifiable, true);
+            COMPILE::SWF{
+                xmlWatchers[notifiable]=true;
+            }
+            COMPILE::JS{
+                xmlWatchers.set(notifiable, true);
+            }
         }
     }
 
@@ -223,12 +258,24 @@ public class XMLNotifier
             if (!(watcherFunction is Function))
                 return;
 
-            var xmlWatchers:ObjectMap;
+            COMPILE::SWF{
+                var xmlWatchers:Dictionary;
+            }
+
+            COMPILE::JS{
+                var xmlWatchers:Map;
+            }
 
             if (watcherFunction["watched"] != undefined)
             {
                 xmlWatchers = watcherFunction["watched"];
-                xmlWatchers.delete(notifiable);
+                COMPILE::SWF{
+                    delete xmlWatchers[notifiable];
+                }
+                COMPILE::JS{
+                    xmlWatchers.delete(notifiable);
+                }
+
             }           
         }
     }

Reply via email to