1 //
2 // Copyright (C) 2007, 2008, 2009, 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
22 #ifdef HAVE_DEJAGNU_H
23
24 //#include <netinet/in.h>
25 #include <string>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <iostream>
33 #include <string>
34
35 #include "as_object.h"
36 #include "dejagnu.h"
37 #include "log.h"
38 #include "amf.h"
39 #include "buffer.h"
40 #include "network.h"
41 #include "element.h"
42 #include "sol.h"
43 #include "arg_parser.h"
44 #include "gmemory.h"
45
46 using namespace cygnal;
47 using namespace gnash;
48 using namespace std;
49
50 static void usage (void);
51
52 // Enable the display of memory allocation and timing data
53 static bool memdebug = false;
54
55 // We use the Memory profiling class to check the malloc buffers
56 // in the kernel to make sure the allocations and frees happen
57 // the way we expect them too. There is no real other way to tell.
58 #if defined(HAVE_MALLINFO) && defined(USE_STATS_MEMORY)
59 Memory *mem = 0;
60 #endif
61
62 static TestState runtest;
63
64 static void test_read(std::string &filespec);
65 //static void test_write(std::string &filespec);
66 bool test_sol(std::string &filespec);
67
68 LogFile& dbglogfile = LogFile::getDefaultInstance();
69
70 int
main(int argc,char * argv[])71 main(int argc, char *argv[])
72 {
73 const Arg_parser::Option opts[] =
74 {
75 { 'h', "help", Arg_parser::no },
76 { 'v', "verbose", Arg_parser::no },
77 { 'w', "write", Arg_parser::no },
78 // Unless you have support for memory debugging turned on, and
79 // you have support for the Linux mallinfo() system call,
80 // this option is totally useless. This doesn't really matter
81 // as the memory testing is primarily used only during
82 // debugging or development.
83 { 'm', "memstats", Arg_parser::no },
84 { 'd', "dump", Arg_parser::no },
85 };
86
87 Arg_parser parser(argc, argv, opts);
88 if( ! parser.error().empty() ) {
89 cout << parser.error() << endl;
90 exit(EXIT_FAILURE);
91 }
92
93 for( int i = 0; i < parser.arguments(); ++i ) {
94 const int code = parser.code(i);
95 try {
96 switch( code ) {
97 case 'h':
98 usage ();
99 exit(EXIT_SUCCESS);
100 case 'v':
101 dbglogfile.setVerbosity();
102 log_debug(_("Verbose output turned on"));
103 break;
104 case 'm':
105 log_debug(_("Enabling memory statistics"));
106 memdebug = true;
107 break;
108 }
109 }
110
111 catch (Arg_parser::ArgParserException &e) {
112 cerr << _("Error parsing command line options: ") << e.what() << endl;
113 cerr << _("This is a Gnash bug.") << endl;
114 }
115 }
116
117 #if defined(HAVE_MALLINFO) && defined(USE_STATS_MEMORY)
118 if (memdebug) {
119 mem = new Memory;
120 mem->startStats();
121 }
122 #endif
123
124 // Read a premade .sol file
125 string filespec = SRCDIR;
126 filespec += "/settings.sol";
127 test_read(filespec);
128
129 filespec = SRCDIR;
130 filespec += "/testout.sol";
131 // Write a .sol file
132
133 // test_write(filespec);
134
135 // test_sol();
136 }
137
138 void
test_read(std::string & filespec)139 test_read(std::string &filespec)
140 {
141 GNASH_REPORT_FUNCTION;
142 struct stat st;
143
144 std::shared_ptr<Buffer> hex1(new Buffer("00 bf 00 00 01 28 54 43 53 4f 00 04 00 00 00 00 00 08 73 65 74 74 69 6e 67 73 00 00 00 00 00 04 67 61 69 6e 00 40 49 00 00 00 00 00 00 00 00 0f 65 63 68 6f 73 75 70 70 72 65 73 73 69 6f 6e 01 00 00 00 11 64 65 66 61 75 6c 74 6d 69 63 72 6f 70 68 6f 6e 65 02 00 0e 2f 64 65 76 2f 69 6e 70 75 74 2f 6d 69 63 00 00 0d 64 65 66 61 75 6c 74 63 61 6d 65 72 61 02 00 00 00 00 0d 64 65 66 61 75 6c 74 6b 6c 69 6d 69 74 00 40 59 00 00 00 00 00 00 00 00 0d 64 65 66 61 75 6c 74 61 6c 77 61 79 73 01 00 00 00 10 63 72 6f 73 73 64 6f 6d 61 69 6e 41 6c 6c 6f 77 01 01 00 00 11 63 72 6f 73 73 64 6f 6d 61 69 6e 41 6c 77 61 79 73 01 01 00 00 18 61 6c 6c 6f 77 54 68 69 72 64 50 61 72 74 79 4c 53 4f 41 63 63 65 73 73 01 01 00 00 0c 74 72 75 73 74 65 64 50 61 74 68 73 03 00 00 09 00 00 0c 6c 6f 63 61 6c 53 65 63 50 61 74 68 02 00 00 00 00 10 6c 6f 63 61 6c 53 65 63 50 61 74 68 54 69 6d 65 00 42 71 6d 14 10 22 e0 00 00"));
145
146 if (stat(filespec.c_str(), &st) == 0) {
147 SOL sol;
148 sol.readFile(filespec);
149 vector<std::shared_ptr<cygnal::Element> > els = sol.getElements();
150
151 if (els.size() > 1) {
152 string str = els[2]->to_string();
153
154 // Make sure multiple elements of varying datatypes are checked for.
155 if ((strcmp(els[0]->getName(), "gain") == 0) &&
156 (strcmp(els[2]->getName(), "defaultmicrophone") == 0) &&
157 (str == "/dev/input/mic") &&
158 (strcmp(els[5]->getName(), "defaultalways") == 0) &&
159 (strcmp(els[9]->getName(), "trustedPaths") == 0)) {
160 runtest.pass("Read SOL File");
161 } else {
162 runtest.fail("Read SOL file");
163 }
164 } else {
165 runtest.fail("Read SOL file");
166 }
167 // sol.dump();
168 }
169 }
170
171 #if 0
172 void
173 test_write(std::string &filespec)
174 {
175 GNASH_REPORT_FUNCTION;
176
177 SOL sol;
178 AMF amf_obj;
179
180 // char *data = const_cast<char *>("/dev/input/mic");
181 // el.getData() = reinterpret_cast<uint8_t *>(data);
182 amf::Element newel;
183
184 double dub = 50.0;
185
186 // amf::Element *el = new amf::Element("gain", dub);
187 amf::Element *el = new amf::Element("gain", dub);
188 // amf_obj.createElement(&el, "gain", dub);
189 sol.addObj(el);
190
191 if ((strcmp(el->getName(), "gain") == 0) &&
192 (el->getType() == Element::NUMBER_AMF0) &&
193 (el->to_number() == dub) &&
194 (el->getLength() == AMF0_NUMBER_SIZE)) {
195 runtest.pass("gain set");
196 } else {
197 runtest.fail("gain set");
198 }
199
200 el = new amf::Element("echosuppression", false);
201 sol.addObj(el);
202 if ((strcmp(el->getName(), "echosuppression") == 0) &&
203 (el->getType() == Element::BOOLEAN_AMF0) &&
204 (*el->getData() == 0) &&
205 (el->getLength() == 1)) {
206 runtest.pass("echosupression set");
207 } else {
208 runtest.fail("echosupression set");
209 }
210
211 string name = "defaultmicrophone";
212 string data = "/dev/input/mic";
213 el = new amf::Element("defaultmicrophone", data);
214 sol.addObj(el);
215 if ((el->getName() == name) &&
216 (el->getType() == Element::STRING_AMF0) &&
217 (memcmp(el->getData(), data.c_str(), el->getLength()) == 0) &&
218 (el->getLength() == data.size())) {
219 runtest.pass("defaultmicrophone set");
220 } else {
221 runtest.fail("defaultmicrophone set");
222 }
223
224 data = "";
225 el = new amf::Element("defaultcamera", data);
226 sol.addObj(el);
227 if ((strcmp(el->getName(), "defaultcamera") == 0) &&
228 (el->getType() == Element::STRING_AMF0) &&
229 (el->getLength() == 0)) {
230 runtest.pass("defaultcamera set");
231 } else {
232 runtest.fail("defaultcamera set");
233 }
234
235 dub = 100.0;
236 el = new amf::Element("defaultklimit", dub);
237 // el = new amf::Element("defaultklimit", dub);
238 sol.addObj(el);
239 if ((strcmp(el->getName(), "defaultklimit") == 0) &&
240 (el->getType() == Element::NUMBER_AMF0) &&
241 (el->to_number() == dub) &&
242 (el->getLength() == AMF0_NUMBER_SIZE)) {
243 runtest.pass("defaultklimit set");
244 } else {
245 runtest.fail("defaultklimit set");
246 }
247
248 el = new amf::Element("defaultalways", false);
249 sol.addObj(el);
250 if ((strcmp(el->getName(), "defaultalways") == 0) &&
251 (el->getType() == Element::BOOLEAN_AMF0) &&
252 (el->to_bool() == false) &&
253 (el->getLength() == 1)) {
254 runtest.pass("defaultalways set");
255 } else {
256 runtest.fail("defaultalways set");
257 }
258
259 el = new amf::Element("crossdomainAllow", true);
260 sol.addObj(el);
261 if ((strcmp(el->getName(), "crossdomainAllow") == 0) &&
262 (el->getType() == Element::BOOLEAN_AMF0) &&
263 (el->to_bool() == true) &&
264 (el->getLength() == 1)) {
265 runtest.pass("crossdomainAllow set");
266 } else {
267 runtest.fail("crossdomainAllow set");
268 }
269
270 el = new amf::Element("crossdomainAlways", true);
271 sol.addObj(el);
272 if ((strcmp(el->getName(), "crossdomainAlways") == 0) &&
273 (el->getType() == Element::BOOLEAN_AMF0) &&
274 (*el->getData() == 1) &&
275 (el->getLength() == 1)) {
276 runtest.pass("crossdomainAlways set");
277 } else {
278 runtest.fail("crossdomainAlways set");
279 }
280
281 el = new amf::Element("allowThirdPartyLSOAccess", true);
282 sol.addObj(el);
283 if ((strcmp(el->getName(), "allowThirdPartyLSOAccess") ==0) &&
284 (el->getType() == Element::BOOLEAN_AMF0) &&
285 (*el->getData() == 1) &&
286 (el->getLength() == 1)) {
287 runtest.pass("allowThirdPartyLSOAccess set");
288 } else {
289 runtest.fail("allowThirdPartyLSOAccess set");
290 }
291
292 el = new amf::Element("localSecPath", data);
293 sol.addObj(el);
294 if ((strcmp(el->getName(), "localSecPath") == 0) &&
295 (el->getType() == Element::STRING_AMF0) &&
296 (el->getLength() == 0)) {
297 runtest.pass("localSecPath set");
298 } else {
299 runtest.fail("localSecPath set");
300 }
301
302 // Grabbed from GDB when reading this huge value
303 dub = 1.8379389592608646e-304;
304 swapBytes(&dub, 8);
305
306 el = new amf::Element("localSecPathTime", dub);
307 sol.addObj(el);
308 if ((strcmp(el->getName(), "localSecPathTime") ==0) &&
309 (el->getType() == Element::NUMBER_AMF0) &&
310 (memcmp(el->getData(), &dub, AMF0_NUMBER_SIZE) == 0) &&
311 (*((double *)el->getData()) == dub) &&
312 (el->getLength() == AMF0_NUMBER_SIZE)) {
313 runtest.pass("localSecPathTime set");
314 } else {
315 runtest.fail("localSecPathTime set");
316 }
317 sol.dump();
318 // now write the data to disk
319 sol.writeFile(filespec, "settings");
320 }
321 #endif
322
323 static void
usage(void)324 usage (void)
325 {
326 cerr << "This program tests SOL support in the AMF library." << endl;
327 cerr << "Usage: test_sol [hv]" << endl;
328 cerr << "-h\tHelp" << endl;
329 cerr << "-v\tVerbose" << endl;
330 exit (-1);
331 }
332
333 #else
334
335 int
main(int,char)336 main(int /*argc*/, char /* *argv[]*/)
337 {
338 // nop
339 return 0;
340 }
341
342 #endif
343
344 // amf::SOL::formatHeader(std::string const&)
345 // amf::SOL::formatHeader(std::string const&, int)
346 // amf::SOL::formatHeader(std::vector<unsigned char, std::allocator<unsigned char> > const&)
347 // amf::SOL::extractHeader(std::string const&)
348 // amf::SOL::extractHeader(std::vector<unsigned char, std::allocator<unsigned char> > const&)
349 // amf::SOL::dump()
350 // amf::SOL::addObj(amf::Element*)
351 // amf::SOL::readFile(std::string&)
352 // amf::SOL::writeFile(std::string const&, std::string const&)
353 // amf::SOL::SOL()
354 // amf::SOL::SOL()
355 // amf::SOL::~SOL()
356 // amf::SOL::~SOL()
357