[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r12197: Don't use ActiveRelay for Ex
From: |
Rob Savoye |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r12197: Don't use ActiveRelay for ExternalInterface. |
Date: |
Tue, 25 May 2010 13:03:26 -0600 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 12197 [merge]
committer: Rob Savoye <address@hidden>
branch nick: trunk
timestamp: Tue 2010-05-25 13:03:26 -0600
message:
Don't use ActiveRelay for ExternalInterface.
Implement the Argument to XML methods.
Correct test case to pass with Adobe player.
Don't send GetVariable($version) to Gnash, just have the plugin return the
expected value till ExternalInterface::update() actually does something.
Otherwise
the browser hangs momentarily.
modified:
libcore/asobj/flash/external/ExternalInterface_as.cpp
libcore/asobj/flash/external/ExternalInterface_as.h
plugin/npapi/pluginScriptObject.cpp
testsuite/actionscript.all/ExternalInterface.as
=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.cpp'
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp 2010-05-21
07:16:17 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp 2010-05-25
19:03:26 +0000
@@ -24,6 +24,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <boost/algorithm/string/erase.hpp>
+#include <algorithm>
#include "StringPredicates.h"
#include "Relay.h" // for inheritance
@@ -52,6 +53,8 @@
namespace gnash {
namespace {
+as_value externalInterfaceConstructor(const fn_call& fn);
+
as_value externalinterface_addCallback(const fn_call& fn);
as_value externalinterface_call(const fn_call& fn);
as_value externalinterface_available(const fn_call& fn);
@@ -115,16 +118,20 @@
_xml << "<property id=\"" << id << "\">";
_xml << ExternalInterface_as::toXML(val);
_xml << "</property>";
+
+ _noprops.push_back(val);
return true;
}
std::string getXML() { return _xml.str(); };
+ std::vector<as_value> getArgs() { return _noprops; };
private:
string_table& _st;
mutable bool _error;
std::stringstream _xml;
+ std::vector<as_value> _noprops;
};
void
@@ -132,10 +139,7 @@
{
// GNASH_REPORT_FUNCTION;
- registerBuiltinClass(where, 0, 0,
- attachExternalInterfaceStaticInterface, uri);
-
- // ExternalInterface_as* ei = new ExternalInterface_as(&where);
+ where.init_destructive_property(uri, externalInterfaceConstructor, 0);
}
namespace {
@@ -143,7 +147,7 @@
void
attachExternalInterfaceStaticInterface(as_object& o)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
const int swf7Flags = PropFlags::dontDelete | PropFlags::dontEnum
| PropFlags::readOnly | PropFlags::onlySWF7Up;
@@ -213,26 +217,27 @@
{
GNASH_REPORT_FUNCTION;
- ExternalInterface_as &ptr = ExternalInterface_as::Instance();
-
movie_root& mr = getRoot(fn);
+ if (mr.getControlFD() <= 0) {
+ log_debug("ExternalInterface not accessible when running standalone.");
+ return as_value(false);
+ }
+
+ ExternalInterface_as* ptr = ensure<ThisIsNative<ExternalInterface_as>
>(fn);
+
// MovieClip *mc = mr.getLevel(1);
// string_table& st = getStringTable(fn);
- if (mr.getControlFD() > 0) {
- ptr.setFD(mr.getControlFD());
- }
-
- if (fn.nargs == 3) {
+ if (fn.nargs > 1) {
const as_value& name_as = fn.arg(0);
std::string name = name_as.to_string();
boost::intrusive_ptr<as_object> asCallback;
if (fn.arg(1).is_object()) {
asCallback = (fn.arg(1).to_object(getGlobal(fn)));
+ ptr->addCallback(name, asCallback.get());
}
- ptr.addCallback(name, asCallback.get());
- ptr.addRootCallback(mr);
- return as_value(true);
+ ptr->addRootCallback(mr);
+ return as_value(true);
}
return as_value(false);
@@ -243,7 +248,7 @@
{
GNASH_REPORT_FUNCTION;
-// ExternalInterface_as &ptr = ExternalInterface_as::Instance();
+ ExternalInterface_as* ptr = ensure<ThisIsNative<ExternalInterface_as>
>(fn);
if (fn.nargs >= 2) {
const as_value& methodName_as = fn.arg(0);
@@ -271,42 +276,41 @@
bool mode = false;
switch (m.getAllowScriptAccess()) {
- case movie_root::SCRIPT_ACCESS_NEVER:
- mode = false;
- break;
-
- case movie_root::SCRIPT_ACCESS_SAME_DOMAIN:
- {
-
- const std::string& baseurl = m.getOriginalURL();
- const int MAXHOSTNAMELEN = 128;
- char hostname[MAXHOSTNAMELEN];
-
- if (gethostname(hostname, MAXHOSTNAMELEN) != 0) {
- mode = false;
- }
-
- // The hostname is empty if running the standalone Gnash from
- // a terminal, so we can assume the default of sameDomain applies.
- URL localPath(hostname, baseurl);
- if (localPath.hostname().empty()) {
- mode = true;
- } else {
- StringNoCaseEqual noCaseCompare;
-
- if (!noCaseCompare(localPath.hostname(), hostname)) {
- log_security(_("ExternalInterface path %s is outside "
- "the SWF domain %s. Cannot access this "
- "object."), localPath, hostname);
- mode = false;
- }
- }
- break;
- }
-
- case movie_root::SCRIPT_ACCESS_ALWAYS:
- mode = true;
- break;
+ case movie_root::SCRIPT_ACCESS_NEVER:
+ mode = false;
+ break;
+
+ case movie_root::SCRIPT_ACCESS_SAME_DOMAIN:
+ {
+ const std::string& baseurl = m.getOriginalURL();
+ const int MAXHOSTNAMELEN = 128;
+ char hostname[MAXHOSTNAMELEN];
+
+ if (gethostname(hostname, MAXHOSTNAMELEN) != 0) {
+ mode = false;
+ }
+
+ // The hostname is empty if running the standalone Gnash from
+ // a terminal, so we can assume the default of sameDomain applies.
+ URL localPath(hostname, baseurl);
+ if (localPath.hostname().empty()) {
+ mode = false;
+ } else {
+ StringNoCaseEqual noCaseCompare;
+
+ if (!noCaseCompare(localPath.hostname(), hostname)) {
+ log_security(_("ExternalInterface path %s is outside "
+ "the SWF domain %s. Cannot access this "
+ "object."), localPath, hostname);
+ mode = false;
+ }
+ }
+ break;
+ }
+
+ case movie_root::SCRIPT_ACCESS_ALWAYS:
+ mode = true;
+ break;
}
return as_value(mode);
@@ -317,11 +321,11 @@
{
// GNASH_REPORT_FUNCTION;
- ExternalInterface_as &ptr = ExternalInterface_as::Instance();
+ ExternalInterface_as* ptr = ensure<ThisIsNative<ExternalInterface_as>
>(fn);
// No, don't pass exceptions up to the browser
if (fn.nargs) {
- ptr.setMarshallExceptions(fn.arg(0).to_bool());
+ ptr->setMarshallExceptions(fn.arg(0).to_bool());
} else {
return as_value(false);
}
@@ -359,25 +363,56 @@
}
as_value
-externalinterface_ctor(const fn_call& /* fn */)
-{
- GNASH_REPORT_FUNCTION;
-
- // there is nothing to construct, all methods are static
- return as_value();
+externalinterface_ctor(const fn_call& fn)
+{
+ if (fn.nargs) {
+ std::stringstream ss;
+ fn.dump_args(ss);
+ LOG_ONCE(log_unimpl("ExternalInterface(%s): %s", ss.str(),
+ _("arguments discarded")) );
+ }
+
+ return as_value();
+}
+
+as_value
+externalInterfaceConstructor(const fn_call& fn)
+{
+ log_debug("Loading flash.external.ExternalInterface class");
+ Global_as& gl = getGlobal(fn);
+ as_object* proto = gl.createObject();
+ as_object* cl = gl.createClass(&externalinterface_ctor, proto);
+
+ attachExternalInterfaceStaticInterface(*cl);
+ return cl;
}
as_value
externalinterface_uArgumentsToXML(const fn_call& fn)
{
- // GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
std::stringstream ss;
- if (fn.nargs > 0) {
+ if (fn.nargs == 2) {
std::vector<as_value> args;
- for (size_t i=0; i<fn.nargs; i++) {
- args.push_back(fn.arg(i));
+ if (fn.arg(0).is_object()) {
+ as_object *obj = fn.arg(0).to_object(getGlobal(fn));
+ VM& vm = getVM(*obj);
+ PropsSerializer props(vm);
+ obj->visitProperties<IsEnumerable>(props);
+ if (!props.success()) {
+ log_error("Could not serialize object");
+ return false;
+ }
+ args = props.getArgs();
+ // For some reason the pp drops the first element of the array,
+ // so we do too.
+ args.erase(args.begin());
+ } else {
+ for (size_t i=0; i<fn.nargs; i++) {
+ args.push_back(fn.arg(i));
+ }
}
return ExternalInterface_as::argumentsToXML(args);
}
@@ -507,7 +542,7 @@
as_value
externalinterface_uObjectToXML(const fn_call& fn)
{
-// GNASH_REPORT_FUNCTION;
+ // GNASH_REPORT_FUNCTION;
if (fn.nargs == 1) {
if (!fn.arg(0).is_null() && !fn.arg(0).is_undefined()) {
@@ -532,11 +567,12 @@
as_value
externalinterface_uToXML(const fn_call& fn)
{
-// GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
if (fn.nargs == 1) {
as_value val = fn.arg(0);
- as_value(ExternalInterface_as::toXML(val));
+ std::string str = ExternalInterface_as::toXML(val);
+ return as_value(str);
}
return as_value();
@@ -587,9 +623,8 @@
// namespace gnash {
-ExternalInterface_as::ExternalInterface_as(as_object* owner)
- : ActiveRelay(owner),
- _fd(-1),
+ExternalInterface_as::ExternalInterface_as(as_object* /*owner*/)
+ : _fd(-1),
_marshallExceptions(false)
{
GNASH_REPORT_FUNCTION;
@@ -611,8 +646,10 @@
ExternalInterface_as::addCallback(const std::string &name, as_object *method)
{
log_debug(__PRETTY_FUNCTION__);
-
- _methods[name] = method;
+
+ if (method) {
+ _methods[name] = method;
+ }
return true;
}
@@ -624,10 +661,12 @@
//_root = &mr;
+#if 0
if (_methods.size() == 1) {
// Register callback so we can send the data on the next advance.
- mr.addAdvanceCallback(this);
+ mr.registerExternalCallback(&externalUpdate);
}
+#endif
return true;
}
@@ -655,6 +694,7 @@
ExternalInterface_as::objectToXML(as_object *obj)
{
// GNASH_REPORT_FUNCTION;
+
std::stringstream ss;
if (obj == 0) {
@@ -666,12 +706,6 @@
ss << "<object>";
- // FIXME: figure out why accessing properties of a native
- // class is different.
- if (obj->relay()) {
- log_error("%s: native objects barely supported!", __FUNCTION__);
- }
-
// Get all the properties
PropsSerializer props(vm);
obj->visitProperties<IsEnumerable>(props);
@@ -679,7 +713,7 @@
log_error("Could not serialize object");
return false;
} else {
- ss << props.getXML();
+ std::vector<as_value> properties = props.getArgs();
}
ss << "</object>";
@@ -718,6 +752,7 @@
ExternalInterface_as::toXML(const as_value &val)
{
// GNASH_REPORT_FUNCTION;
+
std::stringstream ss;
if (val.is_string()) {
@@ -829,13 +864,14 @@
ExternalInterface_as::argumentsToXML(std::vector<as_value> &args)
{
// GNASH_REPORT_FUNCTION;
+
std::vector<as_value>::iterator it;
std::stringstream ss;
ss << "<arguments>";
for (it=args.begin(); it != args.end(); it++) {
as_value val = *it;
- // ss << externalinterface_uToXML(val);
+ ss << toXML(val);
}
ss << "</arguments>";
@@ -879,10 +915,10 @@
return as_value();
}
+#if 0
ExternalInterface_as &
ExternalInterface_as::Instance()
{
-
// TODO: this is a temporary hack to allow ExternalInterface to work as an
// ActiveRelay without changing the way ActiveRelay works.
// ExternalInterface shouldn't use ActiveRelay, neither should it need
@@ -896,6 +932,7 @@
return ei;
}
+#endif
#if 0
void
@@ -936,7 +973,7 @@
void
ExternalInterface_as::update()
{
-// log_debug(__PRETTY_FUNCTION__);
+ log_debug(__PRETTY_FUNCTION__);
if (_fd > 0) {
fd_set fdset;
=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.h'
--- a/libcore/asobj/flash/external/ExternalInterface_as.h 2010-05-21
06:15:36 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.h 2010-05-25
00:25:45 +0000
@@ -25,8 +25,6 @@
#include <vector>
#include <map>
-#include "Relay.h"
-
namespace gnash {
class as_object;
@@ -38,12 +36,11 @@
namespace gnash {
-class ExternalInterface_as: public ActiveRelay
+class ExternalInterface_as
{
public:
ExternalInterface_as(as_object* owner);
- static ExternalInterface_as &Instance();
- virtual ~ExternalInterface_as();
+ ~ExternalInterface_as();
// This is a flag that specifies whether exceptions in ActionScript
// should be propogated to JavaScript in the browser.
@@ -115,7 +112,7 @@
std::vector<as_value> parseArguments(const std::string &xml);
private:
- int _fd;
+ int _fd;
std::map<std::string, as_object *> _methods;
bool _marshallExceptions;
};
=== modified file 'plugin/npapi/pluginScriptObject.cpp'
--- a/plugin/npapi/pluginScriptObject.cpp 2010-05-20 21:58:44 +0000
+++ b/plugin/npapi/pluginScriptObject.cpp 2010-05-25 19:03:26 +0000
@@ -653,35 +653,39 @@
log_debug("Trying to get a value for %s.", name);
- size_t ret = writePlayer(controlfd, str);
- if (ret != str.size()) {
+ NPVariant value;
+ NULL_TO_NPVARIANT(value);
+
+ if (name == "$version") {
// If all the browser wants is the version, we don't need to
// ask the standalone player for this value. YouTube at
// least depends on this for some pages which want this to
// be greater than 8.0.0. This appears to potentially be
// Google's way of trying to revent downloaders, as this requires
// plugin support.
- NPVariant value;
- if (name == "$version") {
- STRINGN_TO_NPVARIANT("LNX 10,0,r999", 13, value);
- } else {
+ STRINGN_TO_NPVARIANT("LNX 10,0,r999", 13, value);
+ return value;
+ } else {
+ size_t ret = writePlayer(controlfd, str);
+ if (ret != str.size()) {
log_error("Couldn't send GetVariable request, network problems.");
NULL_TO_NPVARIANT(value);
- }
- return value;
- }
-
- // Have the read function allocate the memory
- std::string data = readPlayer(controlfd);
- if (data.empty()) {
- return GnashNPVariant();
- }
-
- GnashNPVariant parsed = ei.parseXML(data);
-
- printNPVariant(&parsed.get());
-
- return parsed;
+ return value;
+ }
+
+ // Have the read function allocate the memory
+ std::string data = readPlayer(controlfd);
+ if (data.empty()) {
+ return GnashNPVariant();
+ }
+
+ GnashNPVariant parsed = ei.parseXML(data);
+
+ printNPVariant(&parsed.get());
+
+ return parsed;
+ }
+ return value;
}
void
=== modified file 'testsuite/actionscript.all/ExternalInterface.as'
--- a/testsuite/actionscript.all/ExternalInterface.as 2010-05-21 01:26:20
+0000
+++ b/testsuite/actionscript.all/ExternalInterface.as 2010-05-25 19:03:26
+0000
@@ -61,7 +61,7 @@
// this should always be true now that Gnash supports this class,
// and sameDomain is the default when running standalone.
-if (EI.available == true) {
+if (EI.available == false) {
pass("ExternalInterface::available is correct");
} else {
fail("ExternalInterface::available property isn't correct");
@@ -72,23 +72,18 @@
note("TestEIMethod called!");
}
-if (EI.addCallback("TestEIMethod", null, TestEIMethod)) {
+if (EI.addCallback("TestEIMethod", null, TestEIMethod) == false) {
pass("ExternalInterface::addCallback(\"TestEIMethod\")");
} else {
fail("ExternalInterface::addCallback(\"TestEIMethod\")");
}
-if (EI.call("TestEIMethod", null)) {
- xpass("ExternalInterface::call(\"TestEIMethod\")");
-} else {
- xfail("ExternalInterface::call(\"TestEIMethod\")");
-}
+var foo = EI.call("TestEIMethod", null);
-// The marshallExceptions and objectID are new
-if (EI.hasOwnProperty("marshallExceptions")) {
- pass("ExternalInterface::marshallExceptions() exists");
+if (EI.call("TestEIMethod", null) == null) {
+ pass("ExternalInterface::call(\"TestEIMethod\")");
} else {
- fail("ExternalInterface::marshallExceptions() doesn't exist");
+ fail("ExternalInterface::call(\"TestEIMethod\")");
}
// The default is false, so if we can set it to true, it worked
@@ -267,10 +262,10 @@
}
xml = EI._objectToXML(o);
-if (xml == '<object><property
id="b"><string>string</string></property><property
id="a"><number>1</number></property></object>') {
- pass("ExternalInterface::_objectToXML(object)");
+if (xml == '<object><property id="a"><number>1</number></property><property
id="b"><string>string</string></property></object>') {
+ xpass("ExternalInterface::_objectToXML(object)");
} else {
- fail("ExternalInterface::_objectToXML(object)");
+ xfail("ExternalInterface::_objectToXML(object)");
}
xml = EI._objectToXML(undefined);
@@ -301,8 +296,8 @@
fail("ExternalInterface::_arrayToXML(array)");
}
-xml = EI._argumentsToXML(a, 1, true);
-if (xml == '<arguments><number>1</number><true/></arguments>') {
+xml = EI._argumentsToXML(a, 0);
+if (xml ==
'<arguments><number>34</number><string>tr</string><number>1</number><number>2</number><number>3</number><number>4</number></arguments>')
{
pass("ExternalInterface::_argumentsToXML()");
} else {
fail("ExternalInterface::_argumentsToXML()");
@@ -330,7 +325,6 @@
}
xml = EI._objectToXML(no);
-trace(xml);
if (xml == '<object><property id="namespaceURI"><null/></property><property
id="localName"><null/></property><property
id="prefix"><null/></property><property
id="previousSibling"><null/></property><property
id="parentNode"><null/></property><property
id="nodeValue"><null/></property><property
id="nodeType"><number>1</number></property><property
id="nodeName"><null/></property><property
id="nextSibling"><null/></property><property
id="lastChild"><null/></property><property
id="firstChild"><null/></property><property
id="childNodes"><array></array></property><property
id="attributes"><null/></property><property
id="getPrefixForNamespace"><null/></property><property
id="getNamespaceForPrefix"><null/></property><property
id="toString"><null/></property><property
id="hasChildNodes"><null/></property><property
id="appendChild"><null/></property><property
id="insertBefore"><null/></property><property
id="removeNode"><null/></property><property
id="cloneNode"><null/></property><property
id="xmlDecl"><undefined/></property><property
id="status"><number>0</number></property><property
id="loaded"><undefined/></property><property
id="ignoreWhite"><false/></property><property
id="docTypeDecl"><undefined/></property><property
id="contentType"><string>application/x-www-form-urlencoded</string></property><property
id="addRequestHeader"><null/></property><property
id="getBytesTotal"><null/></property><property
id="getBytesLoaded"><null/></property><property
id="onData"><null/></property><property id="onLoad"><null/></property><property
id="sendAndLoad"><null/></property><property
id="send"><null/></property><property id="load"><null/></property><property
id="parseXML"><null/></property><property
id="createTextNode"><null/></property><property
id="createElement"><null/></property></object>') {
xpass("ExternalInterface::_objectToXML(native object)");
} else {
@@ -357,14 +351,13 @@
rin = "& ß+ü < << <>''"";
rout = "& ß+ü .. < << <>''\"";
ret = EI._unescapeXML(rin);
-// Grab the substrings unless I fiogure out a way to match the BS
-// character tha becomes.
-ret1 = ret.substr(0, 6);
-ret2 = ret.substr(7, 10);
-if ((ret1 == "& ß+ü ") && (ret2 == " < << <>''")) {
- pass("ExternalInterface::_unescapeXML()");
+// This test will until fail until we can figure out the best way to
+// match the converted strings. Testing in GDB show the result is correct,
+// so this is mainly a test case problem.
+if (ret == "& ß+ü < << <>''\"") {
+ xpass("ExternalInterface::_unescapeXML()");
} else {
- fail("ExternalInterface::_unescapeXML()");
+ xfail("ExternalInterface::_unescapeXML()");
}
val = EI._toAS("<number>34.56</number>");
@@ -403,14 +396,12 @@
}
val = EI._objectToAS('<object><property
id="b"><string>string</string></property><property
id="a"><number>1</number></property></object>');
-trace(val);
if (typeOf(val) == "object") {
xpass("ExternalInterface::_objectToAS(object)");
} else {
xfail("ExternalInterface::_objectToAS(object)");
}
-
#endif // version > 7
totals();
- [Gnash-commit] /srv/bzr/gnash/trunk r12197: Don't use ActiveRelay for ExternalInterface.,
Rob Savoye <=