blob: 7d9b41162ea5f675a58bcfded1ccced6b05a6e39 [file] [log] [blame]
Daniel Veillarda76fe5c2003-04-24 16:06:47 +00001/*
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/* FIXME this test would be much better if instead of just checking
10 * for debug spew or crashes on OOM, it also validated the expected
11 * results of parsing a particular file vs. the actual results
12 */
13
14#include "libxml.h"
15
16#include <string.h>
17#include <stdarg.h>
18
19#ifdef HAVE_SYS_TYPES_H
20#include <sys/types.h>
21#endif
22#ifdef HAVE_UNISTD_H
23#include <unistd.h>
24#endif
25#ifdef HAVE_STDLIB_H
26#include <stdlib.h>
27#endif
28#ifdef HAVE_STRING_H
29#include <string.h>
30#endif
31
32#include <libxml/xmlreader.h>
33
34#include "testOOMlib.h"
35
36#ifndef TRUE
37#define TRUE (1)
38#endif
39#ifndef FALSE
40#define FALSE (0)
41#endif
42
43
44int debug = 0;
45int dump = 0;
46int noent = 0;
47int count = 0;
48int valid = 0;
49
50static void usage(const char *progname) {
51 printf("Usage : %s [options] XMLfiles ...\n", progname);
52 printf("\tParse the XML files using the xmlTextReader API\n");
53 printf("\t --count: count the number of attribute and elements\n");
54 printf("\t --valid: validate the document\n");
55 exit(1);
56}
William M. Brack9f797ab2004-07-28 07:40:12 +000057static unsigned int elem, attrs, chars;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +000058
59static int processNode(xmlTextReaderPtr reader) {
60 int type;
61
62 type = xmlTextReaderNodeType(reader);
63 if (count) {
64 if (type == 1) {
65 elem++;
66 attrs += xmlTextReaderAttributeCount(reader);
William M. Brack9f797ab2004-07-28 07:40:12 +000067 } else if (type == 3) {
68 const xmlChar *txt;
69 txt = xmlTextReaderConstValue(reader);
70 if (txt != NULL)
71 chars += xmlStrlen (txt);
72 else
73 return FALSE;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +000074 }
75 }
76
77 return TRUE;
78}
79
William M. Brack9f797ab2004-07-28 07:40:12 +000080
81struct file_params {
82 const char *filename;
83 unsigned int elem, attrs, chars;
84};
85
Daniel Veillarda76fe5c2003-04-24 16:06:47 +000086/* This always returns TRUE since we don't validate the results of
87 * parsing a particular document vs. the expected results of parsing
88 * that document. The idea is that such a failure would return FALSE.
89 */
90static int
91check_load_file_memory_func (void *data)
92{
William M. Brack9f797ab2004-07-28 07:40:12 +000093 struct file_params *p = data;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +000094 xmlTextReaderPtr reader;
William M. Brack9f797ab2004-07-28 07:40:12 +000095 int ret, status;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +000096
97 if (count) {
98 elem = 0;
99 attrs = 0;
William M. Brack9f797ab2004-07-28 07:40:12 +0000100 chars = 0;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000101 }
102
William M. Brack9f797ab2004-07-28 07:40:12 +0000103 status = TRUE;
104 reader = xmlNewTextReaderFilename(p->filename);
105
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000106 if (reader != NULL) {
107 if (valid) {
William M. Brack9f797ab2004-07-28 07:40:12 +0000108 if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1)
109 goto out;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000110 }
111
112 /*
113 * Process all nodes in sequence
114 */
William M. Brack9f797ab2004-07-28 07:40:12 +0000115 while ((ret = xmlTextReaderRead(reader)) == 1) {
116 if (!processNode(reader))
117 goto out;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000118 }
William M. Brack9f797ab2004-07-28 07:40:12 +0000119 if (ret == -1)
120 goto out;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000121
122 /*
123 * Done, cleanup and status
124 */
William M. Brack9f797ab2004-07-28 07:40:12 +0000125 if (count)
126 {
127 if (p->elem == (unsigned int)-1) {
128 p->elem = elem;
129 p->attrs = attrs;
130 p->chars = chars;
131 }
132 else {
133 status = (elem == p->elem && attrs == p->attrs && chars == p->chars);
134 fprintf (stderr, "# %s: %u elems, %u attrs, %u chars %s\n",
135 p->filename, elem, attrs, chars,
136 status ? "ok" : "wrong");
137 }
138 }
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000139 }
William M. Brack9f797ab2004-07-28 07:40:12 +0000140 out:
141 if (reader)
142 xmlFreeTextReader (reader);
143 return status;
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000144}
145
146int main(int argc, char **argv) {
147 int i;
148 int files = 0;
149
150 if (argc <= 1) {
151 usage(argv[0]);
152 return(1);
153 }
154 LIBXML_TEST_VERSION;
155
156 xmlMemSetup (test_free,
157 test_malloc,
158 test_realloc,
159 test_strdup);
160
161 for (i = 1; i < argc ; i++) {
162 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
163 debug++;
164 else if ((!strcmp(argv[i], "-dump")) || (!strcmp(argv[i], "--dump")))
165 dump++;
166 else if ((!strcmp(argv[i], "-count")) || (!strcmp(argv[i], "--count")))
167 count++;
168 else if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
169 valid++;
170 else if ((!strcmp(argv[i], "-noent")) ||
171 (!strcmp(argv[i], "--noent")))
172 noent++;
173 }
174 if (noent != 0)
175 xmlSubstituteEntitiesDefault(1);
176 for (i = 1; i < argc ; i++) {
177 if (argv[i][0] != '-') {
William M. Brack9f797ab2004-07-28 07:40:12 +0000178 struct file_params p;
179 p.filename = argv[i];
180 p.elem = -1;
181
182 /* Run once to count */
183 check_load_file_memory_func (&p);
184 if (count) {
185 fprintf (stderr, "# %s: %u elems, %u attrs, %u chars\n",
186 p.filename, p.elem, p.attrs, p.chars);
187 }
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000188 if (!test_oom_handling (check_load_file_memory_func,
William M. Brack9f797ab2004-07-28 07:40:12 +0000189 &p)) {
Daniel Veillarda76fe5c2003-04-24 16:06:47 +0000190 fprintf (stderr, "Failed!\n");
191 return (1);
192 }
193
194 xmlCleanupParser();
195
196 if (test_get_malloc_blocks_outstanding () > 0) {
197 fprintf (stderr, "%d blocks leaked\n",
198 test_get_malloc_blocks_outstanding ());
199 xmlMemoryDump();
200 return (1);
201 }
202
203 files ++;
204 }
205 }
206 xmlMemoryDump();
207
208 return(0);
209}