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