bdbd98a207afb5a502341d98ff1d52ccee273668
[platform/upstream/libxml++.git] / tests / saxparser_parse_double_free / main.cc
1 /* Copyright (C) 2015  The libxml++ development team
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17
18 #include <libxml++/libxml++.h>
19
20 #include <cstdlib>
21 #include <glibmm.h>
22 #include <stdexcept>
23
24 class OnCdataBlockTestParser : public xmlpp::SaxParser
25 {
26 protected:
27   void on_cdata_block(const Glib::ustring& text) override
28   {
29     g_assert_cmpstr(text.c_str(), ==, "some CDATA");
30     throw std::runtime_error("on_cdata_block runtime exception");
31   }
32 };
33
34 void test_on_cdata_block()
35 {
36   OnCdataBlockTestParser parser;
37   bool exceptionThrown = false;
38   try
39   {
40     parser.parse_memory("<root><![CDATA[some CDATA]]></root>");
41   }
42 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
43   catch(const std::runtime_error& e)
44 #else
45   catch(const xmlpp::exception& e)
46 #endif
47   {
48     exceptionThrown = true;
49     g_assert_cmpstr(e.what(), ==, "on_cdata_block runtime exception");
50   }
51   g_assert_true(exceptionThrown);
52 }
53
54
55 class OnCharactersTestParser : public xmlpp::SaxParser
56 {
57 protected:
58   void on_characters(const Glib::ustring& characters) override
59   {
60     g_assert_cmpstr(characters.c_str(), ==, "abc");
61     throw std::runtime_error("on_characters runtime exception");
62   }
63 };
64
65 void test_on_characters()
66 {
67   OnCharactersTestParser parser;
68   bool exceptionThrown = false;
69   try
70   {
71     parser.parse_memory("<root>abc</root>");
72   }
73 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
74   catch(const std::runtime_error& e)
75 #else
76   catch(const xmlpp::exception& e)
77 #endif
78   {
79     exceptionThrown = true;
80     g_assert_cmpstr(e.what(), ==, "on_characters runtime exception");
81   }
82   g_assert_true(exceptionThrown);
83 }
84
85
86 class OnCommentTestParser : public xmlpp::SaxParser
87 {
88 protected:
89   void on_comment(const Glib::ustring& text) override
90   {
91     g_assert_cmpstr(text.c_str(), ==, "a comment");
92     throw std::runtime_error("on_comment runtime exception");
93   }
94 };
95
96 void test_on_comment()
97 {
98   OnCommentTestParser parser;
99   bool exceptionThrown = false;
100   try
101   {
102     parser.parse_memory("<root><!--a comment--></root>");
103   }
104 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
105   catch(const std::runtime_error& e)
106 #else
107   catch(const xmlpp::exception& e)
108 #endif
109   {
110     exceptionThrown = true;
111     g_assert_cmpstr(e.what(), ==, "on_comment runtime exception");
112   }
113   g_assert_true(exceptionThrown);
114 }
115
116
117 class OnEndDocumentTestParser : public xmlpp::SaxParser
118 {
119 protected:
120   void on_end_document() override
121   {
122     throw std::runtime_error("on_end_document runtime exception");
123   }
124 };
125
126 void test_on_end_document()
127 {
128   OnEndDocumentTestParser parser;
129   bool exceptionThrown = false;
130   try
131   {
132     parser.parse_memory("<root></root>");
133   }
134 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
135   catch(const std::runtime_error& e)
136 #else
137   catch(const xmlpp::exception& e)
138 #endif
139   {
140     exceptionThrown = true;
141     g_assert_cmpstr(e.what(), ==, "on_end_document runtime exception");
142   }
143   g_assert_true(exceptionThrown);
144 }
145
146
147 class OnEndElementTestParser : public xmlpp::SaxParser
148 {
149 protected:
150   void on_end_element(const Glib::ustring& name) override
151   {
152     g_assert_cmpstr(name.c_str(), ==, "a:root");
153     throw std::runtime_error("on_end_element runtime exception");
154   }
155 };
156
157 void test_on_end_element()
158 {
159   OnEndElementTestParser parser;
160   bool exceptionThrown = false;
161   try
162   {
163     parser.parse_memory("<a:root xmlns:a=\"urn:test\"></a:root>");
164   }
165 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
166   catch(const std::runtime_error& e)
167 #else
168   catch(const xmlpp::exception& e)
169 #endif
170   {
171     exceptionThrown = true;
172     g_assert_cmpstr(e.what(), ==, "on_end_element runtime exception");
173   }
174   g_assert_true(exceptionThrown);
175 }
176
177
178 class OnEntityDeclarationTestParser : public xmlpp::SaxParser
179 {
180 protected:
181   void on_entity_declaration(const Glib::ustring& name, xmlpp::XmlEntityType /* type */,
182     const Glib::ustring& /* publicId */, const Glib::ustring& /* systemId */,
183     const Glib::ustring& content) override
184   {
185     g_assert_cmpstr(name.c_str(), ==, "number");
186     g_assert_cmpstr(content.c_str(), ==, "42");
187     throw std::runtime_error("on_entity_declaration runtime exception");
188   }
189 };
190
191 void test_on_entity_declaration()
192 {
193   OnEntityDeclarationTestParser parser;
194   bool exceptionThrown = false;
195   try
196   {
197     parser.parse_memory("<!DOCTYPE MyDocument [<!ENTITY number \"42\">]><root></root>");
198   }
199 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
200   catch(const std::runtime_error& e)
201 #else
202   catch(const xmlpp::exception& e)
203 #endif
204   {
205     exceptionThrown = true;
206     g_assert_cmpstr(e.what(), ==, "on_entity_declaration runtime exception");
207   }
208   g_assert_true(exceptionThrown);
209 }
210
211
212 class OnErrorTestParser : public xmlpp::SaxParser
213 {
214 protected:
215   void on_error(const Glib::ustring& /* text */) override
216   {
217     throw std::runtime_error("on_error runtime exception");
218   }
219 };
220
221 void test_on_error()
222 {
223   OnErrorTestParser parser;
224   bool exceptionThrown = false;
225   try
226   {
227     parser.parse_memory("<root>&unknown;</root>");
228   }
229 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
230   catch(const std::runtime_error& e)
231 #else
232   catch(const xmlpp::exception& e)
233 #endif
234   {
235     exceptionThrown = true;
236     g_assert_cmpstr(e.what(), ==, "on_error runtime exception");
237   }
238   g_assert_true(exceptionThrown);
239 }
240
241
242 class OnGetEntityTestParser : public xmlpp::SaxParser
243 {
244 public:
245   OnGetEntityTestParser()
246     : xmlpp::SaxParser(true)
247   {
248   }
249 protected:
250   _xmlEntity* on_get_entity(const Glib::ustring& name) override
251   {
252     g_assert_cmpstr(name.c_str(), ==, "number");
253     throw std::runtime_error("on_get_entity runtime exception");
254   }
255 };
256
257 void test_on_get_entity()
258 {
259   OnGetEntityTestParser parser;
260   bool exceptionThrown = false;
261   try
262   {
263     parser.parse_memory("<!DOCTYPE MyDocument [<!ENTITY number \"42\">]><root>&number;</root>");
264   }
265 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
266   catch(const std::runtime_error& e)
267 #else
268   catch(const xmlpp::exception& e)
269 #endif
270   {
271     exceptionThrown = true;
272     g_assert_cmpstr(e.what(), ==, "on_get_entity runtime exception");
273   }
274   g_assert_true(exceptionThrown);
275 }
276
277
278 class OnStartDocumentTestParser : public xmlpp::SaxParser
279 {
280 protected:
281   void on_start_document() override
282   {
283     throw std::runtime_error("on_start_document runtime exception");
284   }
285 };
286
287 void test_on_start_document()
288 {
289   OnStartDocumentTestParser parser;
290   bool exceptionThrown = false;
291   try
292   {
293     parser.parse_memory("<root></root>");
294   }
295 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
296   catch(const std::runtime_error& e)
297 #else
298   catch(const xmlpp::exception& e)
299 #endif
300   {
301     exceptionThrown = true;
302     g_assert_cmpstr(e.what(), ==, "on_start_document runtime exception");
303   }
304   g_assert_true(exceptionThrown);
305 }
306
307
308 class OnStartElementTestParser : public xmlpp::SaxParser
309 {
310 protected:
311   void on_start_element(const Glib::ustring& name, const xmlpp::SaxParser::AttributeList& attributes) override
312   {
313     g_assert_cmpstr(name.c_str(), ==, "b:root");
314     g_assert_cmpint(attributes.size(), ==, 2);
315     throw std::runtime_error("on_start_element runtime exception");
316   }
317 };
318
319 void test_on_start_element()
320 {
321   OnStartElementTestParser parser;
322   bool exceptionThrown = false;
323   try
324   {
325     parser.parse_memory("<b:root xmlns:b=\"urn:test\" someattr=\"test\"></b:root>");
326   }
327 #ifdef LIBXMLXX_HAVE_EXCEPTION_PTR
328   catch(const std::runtime_error& e)
329 #else
330   catch(const xmlpp::exception& e)
331 #endif
332   {
333     exceptionThrown = true;
334     g_assert_cmpstr(e.what(), ==, "on_start_element runtime exception");
335   }
336   g_assert_true(exceptionThrown);
337 }
338
339
340 int main()
341 {
342   Glib::init();
343
344   test_on_cdata_block();
345   test_on_characters();
346   test_on_comment();
347   test_on_end_document();
348   test_on_end_element();
349   test_on_entity_declaration();
350   test_on_error();
351   // TODO test on_fatal_error()
352   // This is not currently possible because the fatalError handler is never called;
353   // error is called for all errors.
354   // http://xmlsoft.org/html/libxml-parser.html#fatalErrorSAXFunc
355   test_on_get_entity();
356   // TODO test on_internal_subset()
357   test_on_start_document();
358   test_on_start_element();
359   // TODO test on_warning(), on_validity_error(), on_validity_warning()
360
361   return EXIT_SUCCESS;
362 }