PageRenderTime 25ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/plugin/npapi/test.cpp

#
C++ | 498 lines | 389 code | 59 blank | 50 comment | 94 complexity | 88d2542b6ca6df9a928a712f30f0f721 MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, BSD-3-Clause
  1. //
  2. // Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. #ifdef HAVE_CONFIG_H
  19. #include "gnashconfig.h"
  20. #endif
  21. #include <iostream>
  22. #include <string>
  23. #include <cstdlib>
  24. #include <vector>
  25. #include <map>
  26. #include <cassert>
  27. #include <memory>
  28. #if NPAPI_VERSION == 190
  29. #include "npupp.h"
  30. #else
  31. #include "npapi.h"
  32. #include "npruntime.h"
  33. #include "npfunctions.h"
  34. #endif
  35. #include "pluginbase.h"
  36. #include "dejagnu.h"
  37. #include "../../testsuite/check.h"
  38. #include <regex.h>
  39. #include "external.h"
  40. #include "GnashNPVariant.h"
  41. TestState& runtest = _runtest;
  42. std::map<NPIdentifier, NPVariant *> _properties;
  43. std::map<NPIdentifier, NPInvokeFunctionPtr> _methods;
  44. int
  45. main(int , char **)
  46. {
  47. using namespace gnash;
  48. NPVariant *value = (NPVariant *)NPN_MemAlloc(sizeof(NPVariant));
  49. BOOLEAN_TO_NPVARIANT(true, *value);
  50. std::string str = plugin::ExternalInterface::convertNPVariant(value);
  51. if (str == "<true/>") {
  52. runtest.pass("convertNPVariant(true)");
  53. } else {
  54. runtest.fail("convertNPVariant(true)");
  55. }
  56. BOOLEAN_TO_NPVARIANT(false, *value);
  57. str = plugin::ExternalInterface::convertNPVariant(value);
  58. if (str == "<false/>") {
  59. runtest.pass("convertNPVariant(false)");
  60. } else {
  61. runtest.fail("convertNPVariant(false)");
  62. }
  63. NULL_TO_NPVARIANT(*value);
  64. str = plugin::ExternalInterface::convertNPVariant(value);
  65. if (str == "<null/>") {
  66. runtest.pass("convertNPVariant(null)");
  67. } else {
  68. runtest.fail("convertNPVariant(null)");
  69. }
  70. VOID_TO_NPVARIANT(*value);
  71. str = plugin::ExternalInterface::convertNPVariant(value);
  72. if (str == "<void/>") {
  73. runtest.pass("convertNPVariant(void)");
  74. } else {
  75. runtest.fail("convertNPVariant(void)");
  76. }
  77. DOUBLE_TO_NPVARIANT(123.456, *value);
  78. str = plugin::ExternalInterface::convertNPVariant(value);
  79. if (str == "<number>123.456</number>") {
  80. runtest.pass("convertNPVariant(double)");
  81. } else {
  82. runtest.fail("convertNPVariant(double)");
  83. }
  84. INT32_TO_NPVARIANT(78, *value);
  85. str = plugin::ExternalInterface::convertNPVariant(value);
  86. if (str == "<number>78</number>") {
  87. runtest.pass("convertNPVariant(int32)");
  88. } else {
  89. runtest.fail("convertNPVariant(int32)");
  90. }
  91. STRINGZ_TO_NPVARIANT("Hello World!", *value);
  92. str = plugin::ExternalInterface::convertNPVariant(value);
  93. if (str == "<string>Hello World!</string>") {
  94. runtest.pass("convertNPVariant(string)");
  95. } else {
  96. runtest.fail("convertNPVariant(string)");
  97. }
  98. str = plugin::ExternalInterface::makeProperty("hi", "Hello World!");
  99. if (str == "<property id=\"hi\">Hello World!</property>") {
  100. runtest.pass("plugin::ExternalInterface::makeProperty()");
  101. } else {
  102. runtest.fail("plugin::ExternalInterface::makeProperty()");
  103. }
  104. #if 0
  105. ARRAY_TO_NPVARIANT(*value);
  106. str = plugin::ExternalInterface::convertNPVariant(value);
  107. if (str == "<array></array>") {
  108. runtest.pass("convertNPVariant(array)");
  109. } else {
  110. runtest.fail("convertNPVariant(array)");
  111. }
  112. #endif
  113. std::string prop1 = plugin::ExternalInterface::makeString("foobar");
  114. std::string prop2 = plugin::ExternalInterface::makeNumber(12.34);
  115. std::string prop3 = plugin::ExternalInterface::makeNumber(56);
  116. std::vector<std::string> aargs;
  117. aargs.push_back(prop1);
  118. aargs.push_back(prop2);
  119. aargs.push_back(prop3);
  120. regex_t regex_pat;
  121. regcomp (&regex_pat, "<array><property id=\"0\"><string>foobar</string></property><property id=\"1\"><number>12.34</number></property><property id=\"2\"><number>56</number></property></array>", REG_NOSUB|REG_NEWLINE);
  122. str = plugin::ExternalInterface::makeArray(aargs);
  123. if (regexec (&regex_pat, reinterpret_cast<const char*>(str.c_str()), 0, (regmatch_t *)0, 0)) {
  124. runtest.fail("plugin::ExternalInterface::makeArray()");
  125. } else {
  126. runtest.pass("plugin::ExternalInterface::makeArray()");
  127. }
  128. std::map<std::string, std::string> margs;
  129. margs["test1"] = prop1;
  130. margs["test2"] = prop2;
  131. margs["test3"] = prop3;
  132. str = plugin::ExternalInterface::makeObject(margs);
  133. std::string xml = "<object><property id=\"test1\"><string>foobar</string></property><property id=\"test2\"><number>12.34</number></property><property id=\"test3\"><number>56</number></property></object>";
  134. regfree (&regex_pat);
  135. regcomp (&regex_pat, xml.c_str(), REG_NOSUB|REG_NEWLINE);
  136. // std::cout << str << std::endl;
  137. if (regexec (&regex_pat, reinterpret_cast<const char*>(str.c_str()), 0, (regmatch_t *)0, 0)) {
  138. runtest.fail("plugin::ExternalInterface::makeObject()");
  139. } else {
  140. runtest.pass("plugin::ExternalInterface::makeObject()");
  141. }
  142. //
  143. // Parsing tests
  144. //
  145. xml = "<string>Hello World!</string>";
  146. GnashNPVariant np = plugin::ExternalInterface::parseXML(xml);
  147. std::string data = NPStringToString(NPVARIANT_TO_STRING(np.get()));
  148. if (NPVARIANT_IS_STRING(np.get()) &&
  149. (data == "Hello World!")) {
  150. runtest.pass("plugin::ExternalInterface::parseXML(string)");
  151. } else {
  152. runtest.fail("plugin::ExternalInterface::parseXML(string)");
  153. }
  154. xml = "<number>123.456</number>";
  155. np = plugin::ExternalInterface::parseXML(xml);
  156. double num = NPVARIANT_TO_DOUBLE(np.get());
  157. if (NPVARIANT_IS_DOUBLE(np.get()) &&
  158. (num == 123.456)) {
  159. runtest.pass("plugin::ExternalInterface::parseXML(double)");
  160. } else {
  161. runtest.fail("plugin::ExternalInterface::parseXML(double)");
  162. }
  163. xml = "<number>78</number>";
  164. np = plugin::ExternalInterface::parseXML(xml);
  165. int inum = NPVARIANT_TO_INT32(np.get());
  166. if (NPVARIANT_IS_INT32(np.get()) &&
  167. (inum == 78)) {
  168. runtest.pass("plugin::ExternalInterface::parseXML(int32)");
  169. } else {
  170. runtest.fail("plugin::ExternalInterface::parseXML(int32)");
  171. }
  172. xml = "<true/>";
  173. np = plugin::ExternalInterface::parseXML(xml);
  174. bool flag = NPVARIANT_TO_BOOLEAN(np.get());
  175. if (NPVARIANT_IS_BOOLEAN(np.get()) &&
  176. (flag == true)) {
  177. runtest.pass("plugin::ExternalInterface::parseXML(true)");
  178. } else {
  179. runtest.fail("plugin::ExternalInterface::parseXML(true)");
  180. }
  181. xml = "<false/>";
  182. np = plugin::ExternalInterface::parseXML(xml);
  183. flag = NPVARIANT_TO_BOOLEAN(np.get());
  184. if (NPVARIANT_IS_BOOLEAN(np.get()) &&
  185. (flag == false)) {
  186. runtest.pass("plugin::ExternalInterface::parseXML(false)");
  187. } else {
  188. runtest.fail("plugin::ExternalInterface::parseXML(false)");
  189. }
  190. xml = "<null/>";
  191. np = plugin::ExternalInterface::parseXML(xml);
  192. if (NPVARIANT_IS_NULL(np.get())) {
  193. runtest.pass("plugin::ExternalInterface::parseXML(null)");
  194. } else {
  195. runtest.fail("plugin::ExternalInterface::parseXML(null)");
  196. }
  197. xml = "<void/>";
  198. np = plugin::ExternalInterface::parseXML(xml);
  199. if (NPVARIANT_IS_VOID(np.get())) {
  200. runtest.pass("plugin::ExternalInterface::parseXML(void)");
  201. } else {
  202. runtest.fail("plugin::ExternalInterface::parseXML(void)");
  203. }
  204. xml = "<property id=\"0\"><string>foobar</string></property><property id=\"1\"><number>12.34</number></property><property id=\"2\"><number>56</number></property>";
  205. std::map<std::string, GnashNPVariant> props = plugin::ExternalInterface::parseProperties(xml);
  206. np = props["0"];
  207. data = NPStringToString(NPVARIANT_TO_STRING(np.get()));
  208. if ((props.size() == 3) && (data == "foobar")) {
  209. runtest.pass("plugin::ExternalInterface::parseProperties()");
  210. } else {
  211. runtest.fail("plugin::ExternalInterface::parseProperties()");
  212. }
  213. xml = "<object><property id=\"test1\"><string>foobar</string></property><property id=\"test2\"><number>12.34</number></property><property id=\"test3\"><number>56</number></property></object>";
  214. np = plugin::ExternalInterface::parseXML(xml);
  215. if (NPVARIANT_IS_OBJECT(np.get())) {
  216. runtest.pass("plugin::ExternalInterface::parseXML(object)");
  217. } else {
  218. runtest.fail("plugin::ExternalInterface::parseXML(object)");
  219. }
  220. std::vector<std::string> iargs;
  221. str = plugin::ExternalInterface::makeString("barfoo");
  222. iargs.push_back(str);
  223. str = plugin::ExternalInterface::makeNumber(135.78);
  224. iargs.push_back(str);
  225. str = plugin::ExternalInterface::makeInvoke("barbyfoo", iargs);
  226. xml = "<invoke name=\"barbyfoo\" returntype=\"xml\"><arguments><string>barfoo</string><number>135.78</number></arguments></invoke>";
  227. // std::cout << str << std::endl;
  228. regfree (&regex_pat);
  229. regcomp (&regex_pat, xml.c_str(), REG_NOSUB|REG_NEWLINE);
  230. if (regexec (&regex_pat, reinterpret_cast<const char*>(str.c_str()), 0, (regmatch_t *)0, 0) == 0) {
  231. runtest.pass("plugin::ExternalInterface::makeInvoke()");
  232. } else {
  233. runtest.fail("plugin::ExternalInterface::makeInvoke()");
  234. }
  235. xml = "<arguments><string>barfoo</string><number>135.78</number><number>89</number></arguments>";
  236. std::vector<GnashNPVariant> arguments = plugin::ExternalInterface::parseArguments(xml);
  237. np = arguments[0];
  238. str = NPStringToString(NPVARIANT_TO_STRING(np.get()));
  239. double dub = NPVARIANT_TO_DOUBLE(arguments[1].get());
  240. int val = NPVARIANT_TO_INT32(arguments[2].get());
  241. if ((arguments.size() == 3) && (str == "barfoo")
  242. && (dub == 135.78) && (val == 89)) {
  243. runtest.pass("plugin::ExternalInterface::parseArguments()");
  244. } else {
  245. runtest.fail("plugin::ExternalInterface::parseArguments()");
  246. }
  247. // Parse an invoke message
  248. xml = "<invoke name=\"barbyfoo\" returntype=\"xml\"><arguments><string>barfoo</string><number>135.78</number></arguments></invoke>";
  249. std::shared_ptr<plugin::ExternalInterface::invoke_t> invoke ( plugin::ExternalInterface::parseInvoke(xml) );
  250. str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[0].get()));
  251. if ((invoke->name == "barbyfoo") && (invoke->type == "xml")
  252. && (NPVARIANT_IS_STRING(invoke->args[0].get()))
  253. && (str == "barfoo")
  254. && (NPVARIANT_IS_DOUBLE(invoke->args[1].get()))
  255. && (NPVARIANT_TO_DOUBLE(invoke->args[1].get()) == 135.78)
  256. ) {
  257. runtest.pass("plugin::ExternalInterface::parseInvoke()");
  258. } else {
  259. runtest.fail("plugin::ExternalInterface::parseInvoke()");
  260. }
  261. // Test for bug #31766
  262. xml = "<invoke name=\"reportFlashTiming\" returntype=\"xml\"><arguments><string>reportFlashTiming</string><object><property id=\"5\"><number>1297286708921</number></property><property id=\"4\"><string>vr</string></p";
  263. invoke = plugin::ExternalInterface::parseInvoke(xml);
  264. if ((invoke->name == "reportFlashTiming") && (invoke->type == "xml")
  265. && invoke->args.empty())
  266. {
  267. runtest.pass("plugin::ExternalInterface::parseInvoke() with missing closing invoke tag");
  268. } else {
  269. runtest.fail("plugin::ExternalInterface::parseInvoke() with missing closing invoke tag");
  270. }
  271. xml = "<invoke name=\"reportFlashTiming\" returntype=\"xml\"><arguments><string>reportFlashTiming</string><object><property id=\"5\"><number>1297326407594</number></property><property id=\"4\"><string>vr</string></property><property id=\"3\"><number>1297326407147</number></property><property id=\"2\"><string>gv</string></property><property id=\"1\"><number>1297326406281</number></property><property id=\"0\"><string>fs</string></property></object><string>34</string><number>2</number><string>AASb6VeOkQtvnu_8</string><string>0</string><string>LNX%2010%2C1%2C999%2C0</string><string>Gnash%20GNU%2FLinux</string></arguments></invoke>";
  272. invoke = plugin::ExternalInterface::parseInvoke(xml);
  273. check_equals (invoke->name, "reportFlashTiming");
  274. check_equals (invoke->type, "xml");
  275. xcheck_equals (invoke->args.size(), 8);
  276. //
  277. check(NPVARIANT_IS_STRING(invoke->args[0].get()));
  278. str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[0].get()));
  279. check_equals(str, "reportFlashTiming");
  280. //
  281. xcheck(NPVARIANT_IS_OBJECT(invoke->args[1].get()));
  282. // TODO: check object contents
  283. //
  284. xcheck(NPVARIANT_IS_STRING(invoke->args[2].get()));
  285. // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[2].get()));
  286. // check_equals(str, "34");
  287. //
  288. xcheck(NPVARIANT_IS_DOUBLE(invoke->args[3].get()));
  289. // check_equals(NPVARIANT_TO_DOUBLE(invoke->args[3].get()), 2);
  290. //
  291. check(NPVARIANT_IS_STRING(invoke->args[4].get()));
  292. str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[4].get()));
  293. xcheck_equals(str, "AASb6VeOkQtvnu_8");
  294. //
  295. xcheck(NPVARIANT_IS_STRING(invoke->args[5].get()));
  296. // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[5].get()));
  297. // check_equals(str, "0");
  298. //
  299. xcheck(NPVARIANT_IS_STRING(invoke->args[6].get()));
  300. // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[6].get()));
  301. // check_equals(str, "LNX%2010%2C1%2C999%2C0");
  302. //
  303. xcheck(NPVARIANT_IS_STRING(invoke->args[7].get()));
  304. // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[7].get()));
  305. // check_equals(str, "Gnash%20GNU%2FLinux");
  306. {
  307. xml = "<object><property id=\"5\">";
  308. GnashNPVariant v = plugin::ExternalInterface::parseXML(xml);
  309. check(NPVARIANT_IS_NULL(v.get()));
  310. }
  311. {
  312. NPVariant val;
  313. NULL_TO_NPVARIANT(val);
  314. check(NPVARIANT_IS_NULL(val));
  315. GnashNPVariant v = val;
  316. check(NPVARIANT_IS_NULL(v.get()));
  317. }
  318. regfree (&regex_pat);
  319. NPN_MemFree(value);
  320. }
  321. // We have to implement these two memory allocation functions as
  322. // they're used in the code we're testing.
  323. void *
  324. NPN_MemAlloc(uint32_t size)
  325. {
  326. void * rv = NULL;
  327. rv = malloc(size);
  328. return rv;
  329. }
  330. void
  331. NPN_MemFree(void* ptr)
  332. {
  333. assert(ptr);
  334. free(ptr);
  335. }
  336. // These are just stubs to get the test case to link standalone.
  337. NPIdentifier
  338. NPN_GetStringIdentifier(const NPUTF8 *)
  339. {
  340. return 0;
  341. }
  342. nsPluginInstanceBase *
  343. NS_NewPluginInstance(nsPluginCreateData *)
  344. {
  345. return NULL;
  346. }
  347. NPError
  348. NS_PluginGetValue(NPPVariable, void *)
  349. {
  350. return NPERR_INVALID_INSTANCE_ERROR;
  351. }
  352. NPError
  353. NS_PluginInitialize()
  354. {
  355. return NPERR_INVALID_INSTANCE_ERROR;
  356. }
  357. void
  358. NS_PluginShutdown()
  359. {
  360. }
  361. #ifdef NPAPI_CONST
  362. const
  363. #endif
  364. char*
  365. NPP_GetMIMEDescription(void)
  366. {
  367. char *x = 0;
  368. return x;
  369. }
  370. void
  371. NS_DestroyPluginInstance(nsPluginInstanceBase *)
  372. {
  373. }
  374. // Implement minimal properties handling
  375. bool
  376. NPN_SetProperty(NPP, NPObject*, NPIdentifier name,
  377. const NPVariant *value)
  378. {
  379. _properties[name] = const_cast<NPVariant *>(value);
  380. return true;
  381. }
  382. bool
  383. NPN_GetProperty(NPP, NPObject* , NPIdentifier name,
  384. NPVariant *value)
  385. {
  386. std::map<NPIdentifier, NPVariant *>::iterator it;
  387. it = _properties.find(name);
  388. if (it == _properties.end()) return false;
  389. *value = *(it->second);
  390. return true;
  391. }
  392. bool
  393. NPN_HasProperty(NPP , NPObject* , NPIdentifier name)
  394. {
  395. std::map<NPIdentifier, NPVariant *>::iterator it;
  396. it = _properties.find(name);
  397. if (it != _properties.end()) {
  398. return true;
  399. }
  400. return false;
  401. }
  402. void
  403. NPN_ReleaseVariantValue(NPVariant *variant)
  404. {
  405. switch(variant->type) {
  406. case NPVariantType_String:
  407. {
  408. NPN_MemFree(const_cast<NPUTF8*>(gnash::GetNPStringChars(NPVARIANT_TO_STRING(*variant))));
  409. break;
  410. }
  411. case NPVariantType_Object:
  412. {
  413. NPObject* obj = NPVARIANT_TO_OBJECT(*variant);
  414. if (obj) {
  415. NPN_ReleaseObject(obj);
  416. }
  417. break;
  418. }
  419. default:
  420. {}
  421. }
  422. NULL_TO_NPVARIANT(*variant);
  423. }
  424. NPObject*
  425. NPN_RetainObject(NPObject *obj)
  426. { assert(obj); ++obj->referenceCount; return obj; }
  427. void
  428. NPN_ReleaseObject(NPObject *npobj)
  429. {
  430. assert(npobj);
  431. --npobj->referenceCount;
  432. if (npobj->referenceCount == 0) {
  433. NPN_MemFree(npobj);
  434. }
  435. }
  436. // Local Variables:
  437. // mode: C++
  438. // indent-tabs-mode: nil
  439. // End: