gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-


From: Sandro Santilli
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-2189-g554c463
Date: Sun, 16 Aug 2015 07:43:17 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  554c4638cc3a11dda8f54ba638de7a0445d345ad (commit)
      from  6b269f9f3d518ca5372aa12876ca09be0743bac9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=554c4638cc3a11dda8f54ba638de7a0445d345ad


commit 554c4638cc3a11dda8f54ba638de7a0445d345ad
Author: Nutchanon Wetchasit <address@hidden>
Date:   Sun Aug 16 09:38:42 2015 +0200

    Fix callback registration in ExternalInterface (bug #37223)
    
    Signed-off-by: Sandro Santilli <address@hidden>

diff --git a/NEWS b/NEWS
index 1ae2c00..5168635 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Caveats:
 
 Improvements since 0.8.10 release are:
 
+ * Fix callback registration issue in ExternalInterface (#37223)
  * Fix possible out-of-bound read in parser (#43865)
  * Fix opening of external URL with Gnash Standalone (#31833)
  * Stability fixes in image handling, (CVE-2012-1175, #39388, #37629).
diff --git a/libcore/asobj/flash/external/ExternalInterface_as.cpp 
b/libcore/asobj/flash/external/ExternalInterface_as.cpp
index a72fd4a..db21e1b 100644
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp
@@ -251,18 +251,26 @@ externalinterface_addCallback(const fn_call& fn)
         return as_value(false);
     }
 
-    if (fn.nargs > 1) {
+    if (fn.nargs >= 3) {
         const as_value& name_as = fn.arg(0);
+        const as_value& method_as = fn.arg(2);
         std::string name = name_as.to_string();
-        if (fn.arg(1).is_object()) {
-            log_debug("adding callback %s", name);
-            as_object* asCallback = toObject(fn.arg(1), getVM(fn));
-            mr.addExternalCallback(name, asCallback);
+
+        if (method_as.is_undefined() || method_as.is_null()) {
+            // Adding callback without function specified is not allowed
+            return as_value(false);
         }
+
+        log_debug("adding callback %s", name);
+        as_object* asCallback = toObject(method_as, getVM(fn));
+        mr.addExternalCallback(name, asCallback);
+    } else {
+        // Invalid addCallback call
+        return as_value(false);
     }
 
-    // Returns true unless unavailable (which we checked above)
-    return as_value(true);    
+    // Returns true unless unavailable or invalid (which we checked above)
+    return as_value(true);
 }
 
 // This calls a Javascript function in the browser.
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index 952e063..e370b36 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -1823,12 +1823,19 @@ movie_root::findDropTarget(std::int32_t x, std::int32_t 
y,
 }
 
 /// This should store a callback object in movie_root.
-//
-/// TODO: currently it doesn't.
 void
 movie_root::addExternalCallback(const std::string& name, as_object* callback)
 {
-    UNUSED(callback);
+    // Store registered callback for later use by callExternalCallback()
+    if(_externalCallbackMethods.count(name)>0) {
+        _externalCallbackMethods.erase(name);
+    }
+    _externalCallbackMethods.insert(
+        std::pair<std::string, as_object*>(name,callback)
+    );
+
+    // Set callback as reachable (avoid garbage collection)
+    if (callback!=NULL) callback->setReachable();
 
     // When an external callback is added, we have to notify the plugin
     // that this method is available.
@@ -1889,29 +1896,31 @@ std::string
 movie_root::callExternalCallback(const std::string &name, 
                  const std::vector<as_value> &fnargs)
 {
+    ExternalCallbackMethods::iterator method_iterator;
     MovieClip *mc = getLevel(0);
-    as_object *obj = getObject(mc);
-
-    const ObjectURI& key = getURI(getVM(), name);
-    // FIXME: there has got to be a better way of handling the variable
-    // length arg list
+    as_object *method;
+    as_object *instance = getObject(mc);
+    fn_call::Args args;
     as_value val;
-    switch (fnargs.size()) {
-      case 0:
-          val = callMethod(obj, key);
-          break;
-      case 1:
-          val = callMethod(obj, key, fnargs[0]);
-          break;
-      case 2:
-          val = callMethod(obj, key, fnargs[0], fnargs[1]);
-          break;
-      case 3:
-          val = callMethod(obj, key, fnargs[0], fnargs[1], fnargs[2]);
-          break;
-      default:
-          val = callMethod(obj, key);
-          break;
+
+    // Look up for ActionScript function registered as callback
+    method_iterator = _externalCallbackMethods.find(name);
+    if (method_iterator == _externalCallbackMethods.end()) {
+        val.set_undefined();
+    } else {
+        method = method_iterator->second;
+
+        // Populate function call arguments
+        for (std::vector<as_value>::const_iterator args_iterator
+                 = fnargs.begin();
+             args_iterator != fnargs.end();
+             args_iterator ++)
+        {
+            args += *args_iterator;
+        }
+
+        // Call the registered callback
+        val=invoke(as_value(method), as_environment(getVM()), instance, args);
     }
 
     std::string result;
diff --git a/libcore/movie_root.h b/libcore/movie_root.h
index 743bfeb..970c313 100644
--- a/libcore/movie_root.h
+++ b/libcore/movie_root.h
@@ -785,7 +785,14 @@ public:
 
     const RunResources& runResources() const { return _runResources; }
 
+    typedef std::map<std::string, as_object*> ExternalCallbackMethods;
+    ExternalCallbackMethods _externalCallbackMethods;
+
     /// Add an ExternalInterface callback object with an associated name.
+    //
+    /// @param name     Callback name, exposed to host container.
+    /// @param callback ActionScript function to be invoked if the callback
+    ///                 is called.
     void addExternalCallback(const std::string& name, as_object* callback);
 
     bool processInvoke(ExternalInterface::invoke_t *);

-----------------------------------------------------------------------

Summary of changes:
 NEWS                                               |    1 +
 .../asobj/flash/external/ExternalInterface_as.cpp  |   22 +++++---
 libcore/movie_root.cpp                             |   57 +++++++++++--------
 libcore/movie_root.h                               |    7 +++
 4 files changed, 56 insertions(+), 31 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

[Prev in Thread] Current Thread [Next in Thread]