~ubuntu-branches/ubuntu/wily/opencollada/wily-proposed

« back to all changes in this revision

Viewing changes to Externals/LibXML/testOOM.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2015-05-14 17:23:27 UTC
  • Revision ID: package-import@ubuntu.com-20150514172327-f862u8envms01fra
Tags: upstream-0.1.0~20140703.ddf8f47+dfsg1
ImportĀ upstreamĀ versionĀ 0.1.0~20140703.ddf8f47+dfsg1

Show diffs side-by-side

added added

removed removed

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