VirtualBox

source: vbox/trunk/src/libs/libxml2-2.12.6/testOOM.c

Last change on this file was 104106, checked in by vboxsync, 8 weeks ago

libxml2-2.9.14: Applied and adjusted our libxml2 changes to 2.9.14. bugref:10640

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1/*
2 * testOOM.c: Test out-of-memory handling
3 *
4 * See Copyright for the status of this software.
5 *
6 * hp@redhat.com
7 */
8
9#include <string.h>
10#include <stdarg.h>
11#include <stdlib.h>
12
13#include <libxml/xmlreader.h>
14
15#include "testOOMlib.h"
16
17#ifndef TRUE
18#define TRUE (1)
19#endif
20#ifndef FALSE
21#define FALSE (0)
22#endif
23
24#define EXIT_OOM 2
25
26int error = FALSE;
27int errcount = 0;
28int noent = 0;
29int count = 0;
30int valid = 0;
31int showErrs = 0;
32
33/*
34 * Since we are using the xmlTextReader functions, we set up
35 * strings for the element types to help in debugging any error
36 * output
37 */
38const char *elementNames[] = {
39 "XML_READER_TYPE_NONE",
40 "XML_READER_TYPE_ELEMENT",
41 "XML_READER_TYPE_ATTRIBUTE",
42 "XML_READER_TYPE_TEXT",
43 "XML_READER_TYPE_CDATA",
44 "XML_READER_TYPE_ENTITY_REFERENCE",
45 "XML_READER_TYPE_ENTITY",
46 "XML_READER_TYPE_PROCESSING_INSTRUCTION",
47 "XML_READER_TYPE_COMMENT",
48 "XML_READER_TYPE_DOCUMENT",
49 "XML_READER_TYPE_DOCUMENT_TYPE",
50 "XML_READER_TYPE_DOCUMENT_FRAGMENT",
51 "XML_READER_TYPE_NOTATION",
52 "XML_READER_TYPE_WHITESPACE",
53 "XML_READER_TYPE_SIGNIFICANT_WHITESPACE",
54 "XML_READER_TYPE_END_ELEMENT",
55 "XML_READER_TYPE_END_ENTITY",
56 "XML_READER_TYPE_XML_DECLARATION"};
57
58/* not using xmlBuff here because I don't want those
59 * mallocs to interfere */
60struct buffer {
61 char *str;
62 size_t len;
63 size_t max;
64};
65
66static struct buffer *buffer_create (size_t init_len)
67{
68 struct buffer *b;
69 b = malloc (sizeof *b);
70 if (b == NULL)
71 exit (EXIT_OOM);
72 if (init_len) {
73 b->str = malloc (init_len);
74 if (b->str == NULL)
75 exit (EXIT_OOM);
76 }
77 else
78 b->str = NULL;
79 b->len = 0;
80 b->max = init_len;
81 return b;
82}
83
84static void buffer_free (struct buffer *b)
85{
86 free (b->str);
87 free (b);
88}
89
90static size_t buffer_get_length (struct buffer *b)
91{
92 return b->len;
93}
94
95static void buffer_expand (struct buffer *b, size_t min)
96{
97 void *new_str;
98 size_t new_size = b->max ? b->max : 512;
99 while (new_size < b->len + min)
100 new_size *= 2;
101 if (new_size > b->max) {
102 new_str = realloc (b->str, new_size);
103 if (new_str == NULL)
104 exit (EXIT_OOM);
105 b->str = new_str;
106 b->max = new_size;
107 }
108}
109
110static void buffer_add_char (struct buffer *b, char c)
111{
112 buffer_expand (b, 1);
113 b->str[b->len] = c;
114 b->len += 1;
115}
116
117static void buffer_add_string (struct buffer *b, const char *s)
118{
119 size_t size = strlen(s) + 1;
120 unsigned int ix;
121 for (ix=0; ix<size-1; ix++) {
122 if (s[ix] < 0x20)
123 printf ("binary data [0x%02x]?\n", (unsigned char)s[ix]);
124 }
125 buffer_expand (b, size);
126 strcpy (b->str + b->len, s);
127 b->str[b->len+size-1] = '\n'; /* replace string term with newline */
128 b->len += size;
129}
130
131static int buffer_equal (struct buffer *b1, struct buffer *b2)
132{
133 return (b1->len == b2->len &&
134 (b1->len == 0 || (memcmp (b1->str, b2->str, b1->len) == 0)));
135}
136
137static void buffer_dump (struct buffer *b, const char *fname)
138{
139 FILE *f = fopen (fname, "wb");
140 if (f != NULL) {
141 fwrite (b->str, 1, b->len, f);
142 fclose (f);
143 }
144}
145
146
147static void usage(const char *progname) {
148 printf("Usage : %s [options] XMLfiles ...\n", progname);
149 printf("\tParse the XML files using the xmlTextReader API\n");
150 printf("\t --count: count the number of attribute and elements\n");
151 printf("\t --valid: validate the document\n");
152 printf("\t --show: display the error messages encountered\n");
153 exit(1);
154}
155static unsigned int elem, attrs, chars;
156
157static int processNode (xmlTextReaderPtr reader, void *data)
158{
159 struct buffer *buff = data;
160 int type;
161
162 type = xmlTextReaderNodeType(reader);
163 if (count) {
164 if (type == 1) {
165 elem++;
166 attrs += xmlTextReaderAttributeCount(reader);
167 } else if (type == 3) {
168 const xmlChar *txt;
169 txt = xmlTextReaderConstValue(reader);
170 if (txt != NULL)
171 chars += xmlStrlen (txt);
172 else
173 return FALSE;
174 }
175 }
176
177 if (buff != NULL) {
178 int ret;
179 const char *s;
180
181 buffer_add_string (buff, elementNames[type]);
182
183 if (type == 1) {
184 s = (const char *)xmlTextReaderConstName (reader);
185 if (s == NULL) return FALSE;
186 buffer_add_string (buff, s);
187 while ((ret = xmlTextReaderMoveToNextAttribute (reader)) == 1) {
188 s = (const char *)xmlTextReaderConstName (reader);
189 if (s == NULL) return FALSE;
190 buffer_add_string (buff, s);
191 buffer_add_char (buff, '=');
192 s = (const char *)xmlTextReaderConstValue (reader);
193 if (s == NULL) return FALSE;
194 buffer_add_string (buff, s);
195 }
196 if (ret == -1) return FALSE;
197 }
198 else if (type == 3) {
199 s = (const char *)xmlTextReaderConstValue (reader);
200 if (s == NULL) return FALSE;
201 buffer_add_string (buff, s);
202 }
203 }
204
205 return TRUE;
206}
207
208
209struct file_params {
210 const char *filename;
211 struct buffer *verif_buff;
212};
213
214static void
215error_func (void *data ATTRIBUTE_UNUSED, xmlErrorPtr err)
216{
217
218 errcount++;
219 if (err->level == XML_ERR_ERROR ||
220 err->level == XML_ERR_FATAL)
221 error = TRUE;
222 if (showErrs) {
223 printf("%3d line %d: %s\n", error, err->line, err->message);
224 }
225}
226
227static int
228check_load_file_memory_func (void *data)
229{
230 struct file_params *p = data;
231 struct buffer *b;
232 xmlTextReaderPtr reader;
233 int ret, status, first_run;
234
235 if (count) {
236 elem = 0;
237 attrs = 0;
238 chars = 0;
239 }
240
241 first_run = p->verif_buff == NULL;
242 status = TRUE;
243 error = FALSE;
244 if (first_run)
245 b = buffer_create (0);
246 else
247 b = buffer_create (buffer_get_length (p->verif_buff));
248
249 reader = xmlNewTextReaderFilename (p->filename);
250 if (reader == NULL)
251 goto out;
252
253 xmlTextReaderSetStructuredErrorHandler (reader, error_func, NULL);
254 xmlSetStructuredErrorFunc(NULL, error_func);
255
256 if (valid) {
257 if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1)
258 goto out;
259 }
260
261 /*
262 * Process all nodes in sequence
263 */
264 while ((ret = xmlTextReaderRead(reader)) == 1) {
265 if (!processNode(reader, b))
266 goto out;
267 }
268 if (ret == -1)
269 goto out;
270
271 if (error) {
272 fprintf (stdout, "error handler was called but parse completed successfully (last error #%d)\n", errcount);
273 return FALSE;
274 }
275
276 /*
277 * Done, cleanup and status
278 */
279 if (! first_run) {
280 status = buffer_equal (p->verif_buff, b);
281 if (! status) {
282 buffer_dump (p->verif_buff, ".OOM.verif_buff");
283 buffer_dump (b, ".OOM.buff");
284 }
285 }
286
287 if (count)
288 {
289 fprintf (stdout, "# %s: %u elems, %u attrs, %u chars %s\n",
290 p->filename, elem, attrs, chars,
291 status ? "ok" : "wrong");
292 }
293
294 out:
295 if (first_run)
296 p->verif_buff = b;
297 else
298 buffer_free (b);
299 if (reader)
300 xmlFreeTextReader (reader);
301 return status;
302}
303
304int main(int argc, char **argv) {
305 int i;
306 int files = 0;
307
308 if (argc <= 1) {
309 usage(argv[0]);
310 return(1);
311 }
312 LIBXML_TEST_VERSION;
313
314 xmlMemSetup (test_free,
315 test_malloc,
316 test_realloc,
317 test_strdup);
318
319 xmlInitParser();
320
321 for (i = 1; i < argc ; i++) {
322 if ((!strcmp(argv[i], "-count")) || (!strcmp(argv[i], "--count")))
323 count++;
324 else if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
325 valid++;
326 else if ((!strcmp(argv[i], "-noent")) ||
327 (!strcmp(argv[i], "--noent")))
328 noent++;
329 else if ((!strcmp(argv[i], "-show")) ||
330 (!strcmp(argv[i], "--show")))
331 showErrs++;
332 }
333 if (noent != 0)
334 xmlSubstituteEntitiesDefault(1);
335 for (i = 1; i < argc ; i++) {
336 if (argv[i][0] != '-') {
337 struct file_params p;
338 p.filename = argv[i];
339 p.verif_buff = NULL;
340
341 if (!test_oom_handling (check_load_file_memory_func,
342 &p)) {
343 fprintf (stdout, "Failed!\n");
344 return 1;
345 }
346
347 buffer_free (p.verif_buff);
348 xmlCleanupParser();
349
350 if (test_get_malloc_blocks_outstanding () > 0) {
351 fprintf (stdout, "%d blocks leaked\n",
352 test_get_malloc_blocks_outstanding ());
353 return 1;
354 }
355
356 files ++;
357 }
358 }
359
360 return 0;
361}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use