~ubuntu-branches/ubuntu/hardy/ghostscript/hardy

« back to all changes in this revision

Viewing changes to expat/tests/runtests.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2007-11-22 12:17:43 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071122121743-cd70s3ypq0r243mp
Tags: 8.61.dfsg.1-0ubtuntu1
* New upstream release
  o Final 8.61 release
* debian/patches/09_ijs_krgb_support.dpatch: Adapted to upstream changes.
* debian/rules: Updated CUPS-related variables for "make install" calls.
* debian/rules: Remove /usr/include/ghostscript from the ghostscript
  package, they go into lings-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
 
2
   See the file COPYING for copying permission.
 
3
 
 
4
   runtest.c : run the Expat test suite
 
5
*/
 
6
 
 
7
#ifdef HAVE_EXPAT_CONFIG_H
 
8
#include <expat_config.h>
 
9
#endif
 
10
 
 
11
#include <assert.h>
 
12
#include <stdlib.h>
 
13
#include <stdio.h>
 
14
#include <string.h>
 
15
 
 
16
#include "expat.h"
 
17
#include "chardata.h"
 
18
#include "minicheck.h"
 
19
 
 
20
#if defined(__amigaos__) && defined(__USE_INLINE__)
 
21
#include <proto/expat.h>
 
22
#endif
 
23
 
 
24
#ifdef XML_LARGE_SIZE
 
25
#define XML_FMT_INT_MOD "ll"
 
26
#else
 
27
#define XML_FMT_INT_MOD "l"
 
28
#endif
 
29
 
 
30
static XML_Parser parser;
 
31
 
 
32
 
 
33
static void
 
34
basic_setup(void)
 
35
{
 
36
    parser = XML_ParserCreate(NULL);
 
37
    if (parser == NULL)
 
38
        fail("Parser not created.");
 
39
}
 
40
 
 
41
static void
 
42
basic_teardown(void)
 
43
{
 
44
    if (parser != NULL)
 
45
        XML_ParserFree(parser);
 
46
}
 
47
 
 
48
/* Generate a failure using the parser state to create an error message;
 
49
   this should be used when the parser reports an error we weren't
 
50
   expecting.
 
51
*/
 
52
static void
 
53
_xml_failure(XML_Parser parser, const char *file, int line)
 
54
{
 
55
    char buffer[1024];
 
56
    enum XML_Error err = XML_GetErrorCode(parser);
 
57
    sprintf(buffer,
 
58
            "    %d: %s (line %" XML_FMT_INT_MOD "u, offset %"\
 
59
                XML_FMT_INT_MOD "u)\n    reported from %s, line %d\n",
 
60
            err,
 
61
            XML_ErrorString(err),
 
62
            XML_GetCurrentLineNumber(parser),
 
63
            XML_GetCurrentColumnNumber(parser),
 
64
            file, line);
 
65
    _fail_unless(0, file, line, buffer);
 
66
}
 
67
 
 
68
#define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
 
69
 
 
70
static void
 
71
_expect_failure(char *text, enum XML_Error errorCode, char *errorMessage,
 
72
                char *file, int lineno)
 
73
{
 
74
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
 
75
        /* Hackish use of _fail_unless() macro, but let's us report
 
76
           the right filename and line number. */
 
77
        _fail_unless(0, file, lineno, errorMessage);
 
78
    if (XML_GetErrorCode(parser) != errorCode)
 
79
        _xml_failure(parser, file, lineno);
 
80
}
 
81
 
 
82
#define expect_failure(text, errorCode, errorMessage) \
 
83
        _expect_failure((text), (errorCode), (errorMessage), \
 
84
                        __FILE__, __LINE__)
 
85
 
 
86
/* Dummy handlers for when we need to set a handler to tickle a bug,
 
87
   but it doesn't need to do anything.
 
88
*/
 
89
 
 
90
static void XMLCALL
 
91
dummy_start_doctype_handler(void           *userData,
 
92
                            const XML_Char *doctypeName,
 
93
                            const XML_Char *sysid,
 
94
                            const XML_Char *pubid,
 
95
                            int            has_internal_subset)
 
96
{}
 
97
 
 
98
static void XMLCALL
 
99
dummy_end_doctype_handler(void *userData)
 
100
{}
 
101
 
 
102
static void XMLCALL
 
103
dummy_entity_decl_handler(void           *userData,
 
104
                          const XML_Char *entityName,
 
105
                          int            is_parameter_entity,
 
106
                          const XML_Char *value,
 
107
                          int            value_length,
 
108
                          const XML_Char *base,
 
109
                          const XML_Char *systemId,
 
110
                          const XML_Char *publicId,
 
111
                          const XML_Char *notationName)
 
112
{}
 
113
 
 
114
static void XMLCALL
 
115
dummy_notation_decl_handler(void *userData,
 
116
                            const XML_Char *notationName,
 
117
                            const XML_Char *base,
 
118
                            const XML_Char *systemId,
 
119
                            const XML_Char *publicId)
 
120
{}
 
121
 
 
122
static void XMLCALL
 
123
dummy_element_decl_handler(void *userData,
 
124
                           const XML_Char *name,
 
125
                           XML_Content *model)
 
126
{}
 
127
 
 
128
static void XMLCALL
 
129
dummy_attlist_decl_handler(void           *userData,
 
130
                           const XML_Char *elname,
 
131
                           const XML_Char *attname,
 
132
                           const XML_Char *att_type,
 
133
                           const XML_Char *dflt,
 
134
                           int            isrequired)
 
135
{}
 
136
 
 
137
static void XMLCALL
 
138
dummy_comment_handler(void *userData, const XML_Char *data)
 
139
{}
 
140
 
 
141
static void XMLCALL
 
142
dummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data)
 
143
{}
 
144
 
 
145
static void XMLCALL
 
146
dummy_start_element(void *userData,
 
147
                    const XML_Char *name, const XML_Char **atts)
 
148
{}
 
149
 
 
150
 
 
151
/*
 
152
 * Character & encoding tests.
 
153
 */
 
154
 
 
155
START_TEST(test_nul_byte)
 
156
{
 
157
    char text[] = "<doc>\0</doc>";
 
158
 
 
159
    /* test that a NUL byte (in US-ASCII data) is an error */
 
160
    if (XML_Parse(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
 
161
        fail("Parser did not report error on NUL-byte.");
 
162
    if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
 
163
        xml_failure(parser);
 
164
}
 
165
END_TEST
 
166
 
 
167
 
 
168
START_TEST(test_u0000_char)
 
169
{
 
170
    /* test that a NUL byte (in US-ASCII data) is an error */
 
171
    expect_failure("<doc>&#0;</doc>",
 
172
                   XML_ERROR_BAD_CHAR_REF,
 
173
                   "Parser did not report error on NUL-byte.");
 
174
}
 
175
END_TEST
 
176
 
 
177
START_TEST(test_bom_utf8)
 
178
{
 
179
    /* This test is really just making sure we don't core on a UTF-8 BOM. */
 
180
    char *text = "\357\273\277<e/>";
 
181
 
 
182
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
183
        xml_failure(parser);
 
184
}
 
185
END_TEST
 
186
 
 
187
START_TEST(test_bom_utf16_be)
 
188
{
 
189
    char text[] = "\376\377\0<\0e\0/\0>";
 
190
 
 
191
    if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
 
192
        xml_failure(parser);
 
193
}
 
194
END_TEST
 
195
 
 
196
START_TEST(test_bom_utf16_le)
 
197
{
 
198
    char text[] = "\377\376<\0e\0/\0>\0";
 
199
 
 
200
    if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
 
201
        xml_failure(parser);
 
202
}
 
203
END_TEST
 
204
 
 
205
static void XMLCALL
 
206
accumulate_characters(void *userData, const XML_Char *s, int len)
 
207
{
 
208
    CharData_AppendXMLChars((CharData *)userData, s, len);
 
209
}
 
210
 
 
211
static void XMLCALL
 
212
accumulate_attribute(void *userData, const XML_Char *name,
 
213
                     const XML_Char **atts)
 
214
{
 
215
    CharData *storage = (CharData *)userData;
 
216
    if (storage->count < 0 && atts != NULL && atts[0] != NULL) {
 
217
        /* "accumulate" the value of the first attribute we see */
 
218
        CharData_AppendXMLChars(storage, atts[1], -1);
 
219
    }
 
220
}
 
221
 
 
222
 
 
223
static void
 
224
_run_character_check(XML_Char *text, XML_Char *expected,
 
225
                     const char *file, int line)
 
226
{
 
227
    CharData storage;
 
228
 
 
229
    CharData_Init(&storage);
 
230
    XML_SetUserData(parser, &storage);
 
231
    XML_SetCharacterDataHandler(parser, accumulate_characters);
 
232
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
233
        _xml_failure(parser, file, line);
 
234
    CharData_CheckXMLChars(&storage, expected);
 
235
}
 
236
 
 
237
#define run_character_check(text, expected) \
 
238
        _run_character_check(text, expected, __FILE__, __LINE__)
 
239
 
 
240
static void
 
241
_run_attribute_check(XML_Char *text, XML_Char *expected,
 
242
                     const char *file, int line)
 
243
{
 
244
    CharData storage;
 
245
 
 
246
    CharData_Init(&storage);
 
247
    XML_SetUserData(parser, &storage);
 
248
    XML_SetStartElementHandler(parser, accumulate_attribute);
 
249
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
250
        _xml_failure(parser, file, line);
 
251
    CharData_CheckXMLChars(&storage, expected);
 
252
}
 
253
 
 
254
#define run_attribute_check(text, expected) \
 
255
        _run_attribute_check(text, expected, __FILE__, __LINE__)
 
256
 
 
257
/* Regression test for SF bug #491986. */
 
258
START_TEST(test_danish_latin1)
 
259
{
 
260
    char *text =
 
261
        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
 
262
        "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
 
263
    run_character_check(text,
 
264
             "J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
 
265
}
 
266
END_TEST
 
267
 
 
268
 
 
269
/* Regression test for SF bug #514281. */
 
270
START_TEST(test_french_charref_hexidecimal)
 
271
{
 
272
    char *text =
 
273
        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
 
274
        "<doc>&#xE9;&#xE8;&#xE0;&#xE7;&#xEA;&#xC8;</doc>";
 
275
    run_character_check(text,
 
276
                        "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
 
277
}
 
278
END_TEST
 
279
 
 
280
START_TEST(test_french_charref_decimal)
 
281
{
 
282
    char *text =
 
283
        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
 
284
        "<doc>&#233;&#232;&#224;&#231;&#234;&#200;</doc>";
 
285
    run_character_check(text,
 
286
                        "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
 
287
}
 
288
END_TEST
 
289
 
 
290
START_TEST(test_french_latin1)
 
291
{
 
292
    char *text =
 
293
        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
 
294
        "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
 
295
    run_character_check(text,
 
296
                        "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
 
297
}
 
298
END_TEST
 
299
 
 
300
START_TEST(test_french_utf8)
 
301
{
 
302
    char *text =
 
303
        "<?xml version='1.0' encoding='utf-8'?>\n"
 
304
        "<doc>\xC3\xA9</doc>";
 
305
    run_character_check(text, "\xC3\xA9");
 
306
}
 
307
END_TEST
 
308
 
 
309
/* Regression test for SF bug #600479.
 
310
   XXX There should be a test that exercises all legal XML Unicode
 
311
   characters as PCDATA and attribute value content, and XML Name
 
312
   characters as part of element and attribute names.
 
313
*/
 
314
START_TEST(test_utf8_false_rejection)
 
315
{
 
316
    char *text = "<doc>\xEF\xBA\xBF</doc>";
 
317
    run_character_check(text, "\xEF\xBA\xBF");
 
318
}
 
319
END_TEST
 
320
 
 
321
/* Regression test for SF bug #477667.
 
322
   This test assures that any 8-bit character followed by a 7-bit
 
323
   character will not be mistakenly interpreted as a valid UTF-8
 
324
   sequence.
 
325
*/
 
326
START_TEST(test_illegal_utf8)
 
327
{
 
328
    char text[100];
 
329
    int i;
 
330
 
 
331
    for (i = 128; i <= 255; ++i) {
 
332
        sprintf(text, "<e>%ccd</e>", i);
 
333
        if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) {
 
334
            sprintf(text,
 
335
                    "expected token error for '%c' (ordinal %d) in UTF-8 text",
 
336
                    i, i);
 
337
            fail(text);
 
338
        }
 
339
        else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
 
340
            xml_failure(parser);
 
341
        /* Reset the parser since we use the same parser repeatedly. */
 
342
        XML_ParserReset(parser, NULL);
 
343
    }
 
344
}
 
345
END_TEST
 
346
 
 
347
START_TEST(test_utf16)
 
348
{
 
349
    /* <?xml version="1.0" encoding="UTF-16"?>
 
350
       <doc a='123'>some text</doc>
 
351
    */
 
352
    char text[] =
 
353
        "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
 
354
        "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
 
355
        "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
 
356
        "\000'\000?\000>\000\n"
 
357
        "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'"
 
358
        "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/"
 
359
        "\000d\000o\000c\000>";
 
360
    if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
 
361
        xml_failure(parser);
 
362
}
 
363
END_TEST
 
364
 
 
365
START_TEST(test_utf16_le_epilog_newline)
 
366
{
 
367
    unsigned int first_chunk_bytes = 17;
 
368
    char text[] = 
 
369
        "\xFF\xFE"                      /* BOM */
 
370
        "<\000e\000/\000>\000"          /* document element */
 
371
        "\r\000\n\000\r\000\n\000";     /* epilog */
 
372
 
 
373
    if (first_chunk_bytes >= sizeof(text) - 1)
 
374
        fail("bad value of first_chunk_bytes");
 
375
    if (  XML_Parse(parser, text, first_chunk_bytes, XML_FALSE)
 
376
          == XML_STATUS_ERROR)
 
377
        xml_failure(parser);
 
378
    else {
 
379
        enum XML_Status rc;
 
380
        rc = XML_Parse(parser, text + first_chunk_bytes,
 
381
                       sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
 
382
        if (rc == XML_STATUS_ERROR)
 
383
            xml_failure(parser);
 
384
    }
 
385
}
 
386
END_TEST
 
387
 
 
388
/* Regression test for SF bug #481609, #774028. */
 
389
START_TEST(test_latin1_umlauts)
 
390
{
 
391
    char *text =
 
392
        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
 
393
        "<e a='\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; >'\n"
 
394
        "  >\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; ></e>";
 
395
    char *utf8 =
 
396
        "\xC3\xA4 \xC3\xB6 \xC3\xBC "
 
397
        "\xC3\xA4 \xC3\xB6 \xC3\xBC "
 
398
        "\xC3\xA4 \xC3\xB6 \xC3\xBC >";
 
399
    run_character_check(text, utf8);
 
400
    XML_ParserReset(parser, NULL);
 
401
    run_attribute_check(text, utf8);
 
402
}
 
403
END_TEST
 
404
 
 
405
/* Regression test #1 for SF bug #653180. */
 
406
START_TEST(test_line_number_after_parse)
 
407
{  
 
408
    char *text =
 
409
        "<tag>\n"
 
410
        "\n"
 
411
        "\n</tag>";
 
412
    XML_Size lineno;
 
413
 
 
414
    if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
 
415
        xml_failure(parser);
 
416
    lineno = XML_GetCurrentLineNumber(parser);
 
417
    if (lineno != 4) {
 
418
        char buffer[100];
 
419
        sprintf(buffer, 
 
420
            "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
 
421
        fail(buffer);
 
422
    }
 
423
}
 
424
END_TEST
 
425
 
 
426
/* Regression test #2 for SF bug #653180. */
 
427
START_TEST(test_column_number_after_parse)
 
428
{
 
429
    char *text = "<tag></tag>";
 
430
    XML_Size colno;
 
431
 
 
432
    if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
 
433
        xml_failure(parser);
 
434
    colno = XML_GetCurrentColumnNumber(parser);
 
435
    if (colno != 11) {
 
436
        char buffer[100];
 
437
        sprintf(buffer, 
 
438
            "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
 
439
        fail(buffer);
 
440
    }
 
441
}
 
442
END_TEST
 
443
 
 
444
static void XMLCALL
 
445
start_element_event_handler2(void *userData, const XML_Char *name,
 
446
                             const XML_Char **attr)
 
447
{
 
448
    CharData *storage = (CharData *) userData;
 
449
    char buffer[100];
 
450
 
 
451
    sprintf(buffer,
 
452
        "<%s> at col:%" XML_FMT_INT_MOD "u line:%"\
 
453
            XML_FMT_INT_MOD "u\n", name,
 
454
            XML_GetCurrentColumnNumber(parser),
 
455
            XML_GetCurrentLineNumber(parser));
 
456
    CharData_AppendString(storage, buffer);
 
457
}
 
458
 
 
459
static void XMLCALL
 
460
end_element_event_handler2(void *userData, const XML_Char *name)
 
461
{
 
462
    CharData *storage = (CharData *) userData;
 
463
    char buffer[100];
 
464
 
 
465
    sprintf(buffer,
 
466
        "</%s> at col:%" XML_FMT_INT_MOD "u line:%"\
 
467
            XML_FMT_INT_MOD "u\n", name,
 
468
            XML_GetCurrentColumnNumber(parser),
 
469
            XML_GetCurrentLineNumber(parser));
 
470
    CharData_AppendString(storage, buffer);
 
471
}
 
472
 
 
473
/* Regression test #3 for SF bug #653180. */
 
474
START_TEST(test_line_and_column_numbers_inside_handlers)
 
475
{
 
476
    char *text =
 
477
        "<a>\n"        /* Unix end-of-line */
 
478
        "  <b>\r\n"    /* Windows end-of-line */
 
479
        "    <c/>\r"   /* Mac OS end-of-line */
 
480
        "  </b>\n"
 
481
        "  <d>\n"
 
482
        "    <f/>\n"
 
483
        "  </d>\n"
 
484
        "</a>";
 
485
    char *expected =
 
486
        "<a> at col:0 line:1\n"
 
487
        "<b> at col:2 line:2\n"
 
488
        "<c> at col:4 line:3\n"
 
489
        "</c> at col:8 line:3\n"
 
490
        "</b> at col:2 line:4\n"
 
491
        "<d> at col:2 line:5\n"
 
492
        "<f> at col:4 line:6\n"
 
493
        "</f> at col:8 line:6\n"
 
494
        "</d> at col:2 line:7\n"
 
495
        "</a> at col:0 line:8\n";
 
496
    CharData storage;
 
497
 
 
498
    CharData_Init(&storage);
 
499
    XML_SetUserData(parser, &storage);
 
500
    XML_SetStartElementHandler(parser, start_element_event_handler2);
 
501
    XML_SetEndElementHandler(parser, end_element_event_handler2);
 
502
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
503
        xml_failure(parser);
 
504
 
 
505
    CharData_CheckString(&storage, expected); 
 
506
}
 
507
END_TEST
 
508
 
 
509
/* Regression test #4 for SF bug #653180. */
 
510
START_TEST(test_line_number_after_error)
 
511
{
 
512
    char *text =
 
513
        "<a>\n"
 
514
        "  <b>\n"
 
515
        "  </a>";  /* missing </b> */
 
516
    XML_Size lineno;
 
517
    if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
 
518
        fail("Expected a parse error");
 
519
 
 
520
    lineno = XML_GetCurrentLineNumber(parser);
 
521
    if (lineno != 3) {
 
522
        char buffer[100];
 
523
        sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
 
524
        fail(buffer);
 
525
    }
 
526
}
 
527
END_TEST
 
528
    
 
529
/* Regression test #5 for SF bug #653180. */
 
530
START_TEST(test_column_number_after_error)
 
531
{
 
532
    char *text =
 
533
        "<a>\n"
 
534
        "  <b>\n"
 
535
        "  </a>";  /* missing </b> */
 
536
    XML_Size colno;
 
537
    if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
 
538
        fail("Expected a parse error");
 
539
 
 
540
    colno = XML_GetCurrentColumnNumber(parser);
 
541
    if (colno != 4) { 
 
542
        char buffer[100];
 
543
        sprintf(buffer, 
 
544
            "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
 
545
        fail(buffer);
 
546
    }
 
547
}
 
548
END_TEST
 
549
 
 
550
/* Regression test for SF bug #478332. */
 
551
START_TEST(test_really_long_lines)
 
552
{
 
553
    /* This parses an input line longer than INIT_DATA_BUF_SIZE
 
554
       characters long (defined to be 1024 in xmlparse.c).  We take a
 
555
       really cheesy approach to building the input buffer, because
 
556
       this avoids writing bugs in buffer-filling code.
 
557
    */
 
558
    char *text =
 
559
        "<e>"
 
560
        /* 64 chars */
 
561
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
562
        /* until we have at least 1024 characters on the line: */
 
563
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
564
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
565
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
566
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
567
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
568
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
569
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
570
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
571
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
572
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
573
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
574
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
575
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
576
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
577
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
578
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
 
579
        "</e>";
 
580
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
581
        xml_failure(parser);
 
582
}
 
583
END_TEST
 
584
 
 
585
 
 
586
/*
 
587
 * Element event tests.
 
588
 */
 
589
 
 
590
static void XMLCALL
 
591
end_element_event_handler(void *userData, const XML_Char *name)
 
592
{
 
593
    CharData *storage = (CharData *) userData;
 
594
    CharData_AppendString(storage, "/");
 
595
    CharData_AppendXMLChars(storage, name, -1);
 
596
}
 
597
 
 
598
START_TEST(test_end_element_events)
 
599
{
 
600
    char *text = "<a><b><c/></b><d><f/></d></a>";
 
601
    char *expected = "/c/b/f/d/a";
 
602
    CharData storage;
 
603
 
 
604
    CharData_Init(&storage);
 
605
    XML_SetUserData(parser, &storage);
 
606
    XML_SetEndElementHandler(parser, end_element_event_handler);
 
607
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
608
        xml_failure(parser);
 
609
    CharData_CheckString(&storage, expected);
 
610
}
 
611
END_TEST
 
612
 
 
613
 
 
614
/*
 
615
 * Attribute tests.
 
616
 */
 
617
 
 
618
/* Helpers used by the following test; this checks any "attr" and "refs"
 
619
   attributes to make sure whitespace has been normalized.
 
620
 
 
621
   Return true if whitespace has been normalized in a string, using
 
622
   the rules for attribute value normalization.  The 'is_cdata' flag
 
623
   is needed since CDATA attributes don't need to have multiple
 
624
   whitespace characters collapsed to a single space, while other
 
625
   attribute data types do.  (Section 3.3.3 of the recommendation.)
 
626
*/
 
627
static int
 
628
is_whitespace_normalized(const XML_Char *s, int is_cdata)
 
629
{
 
630
    int blanks = 0;
 
631
    int at_start = 1;
 
632
    while (*s) {
 
633
        if (*s == ' ')
 
634
            ++blanks;
 
635
        else if (*s == '\t' || *s == '\n' || *s == '\r')
 
636
            return 0;
 
637
        else {
 
638
            if (at_start) {
 
639
                at_start = 0;
 
640
                if (blanks && !is_cdata)
 
641
                    /* illegal leading blanks */
 
642
                    return 0;
 
643
            }
 
644
            else if (blanks > 1 && !is_cdata)
 
645
                return 0;
 
646
            blanks = 0;
 
647
        }
 
648
        ++s;
 
649
    }
 
650
    if (blanks && !is_cdata)
 
651
        return 0;
 
652
    return 1;
 
653
}
 
654
 
 
655
/* Check the attribute whitespace checker: */
 
656
static void
 
657
testhelper_is_whitespace_normalized(void)
 
658
{
 
659
    assert(is_whitespace_normalized("abc", 0));
 
660
    assert(is_whitespace_normalized("abc", 1));
 
661
    assert(is_whitespace_normalized("abc def ghi", 0));
 
662
    assert(is_whitespace_normalized("abc def ghi", 1));
 
663
    assert(!is_whitespace_normalized(" abc def ghi", 0));
 
664
    assert(is_whitespace_normalized(" abc def ghi", 1));
 
665
    assert(!is_whitespace_normalized("abc  def ghi", 0));
 
666
    assert(is_whitespace_normalized("abc  def ghi", 1));
 
667
    assert(!is_whitespace_normalized("abc def ghi ", 0));
 
668
    assert(is_whitespace_normalized("abc def ghi ", 1));
 
669
    assert(!is_whitespace_normalized(" ", 0));
 
670
    assert(is_whitespace_normalized(" ", 1));
 
671
    assert(!is_whitespace_normalized("\t", 0));
 
672
    assert(!is_whitespace_normalized("\t", 1));
 
673
    assert(!is_whitespace_normalized("\n", 0));
 
674
    assert(!is_whitespace_normalized("\n", 1));
 
675
    assert(!is_whitespace_normalized("\r", 0));
 
676
    assert(!is_whitespace_normalized("\r", 1));
 
677
    assert(!is_whitespace_normalized("abc\t def", 1));
 
678
}
 
679
 
 
680
static void XMLCALL
 
681
check_attr_contains_normalized_whitespace(void *userData,
 
682
                                          const XML_Char *name,
 
683
                                          const XML_Char **atts)
 
684
{
 
685
    int i;
 
686
    for (i = 0; atts[i] != NULL; i += 2) {
 
687
        const XML_Char *attrname = atts[i];
 
688
        const XML_Char *value = atts[i + 1];
 
689
        if (strcmp("attr", attrname) == 0
 
690
            || strcmp("ents", attrname) == 0
 
691
            || strcmp("refs", attrname) == 0) {
 
692
            if (!is_whitespace_normalized(value, 0)) {
 
693
                char buffer[256];
 
694
                sprintf(buffer, "attribute value not normalized: %s='%s'",
 
695
                        attrname, value);
 
696
                fail(buffer);
 
697
            }
 
698
        }
 
699
    }
 
700
}
 
701
 
 
702
START_TEST(test_attr_whitespace_normalization)
 
703
{
 
704
    char *text =
 
705
        "<!DOCTYPE doc [\n"
 
706
        "  <!ATTLIST doc\n"
 
707
        "            attr NMTOKENS #REQUIRED\n"
 
708
        "            ents ENTITIES #REQUIRED\n"
 
709
        "            refs IDREFS   #REQUIRED>\n"
 
710
        "]>\n"
 
711
        "<doc attr='    a  b c\t\td\te\t' refs=' id-1   \t  id-2\t\t'  \n"
 
712
        "     ents=' ent-1   \t\r\n"
 
713
        "            ent-2  ' >\n"
 
714
        "  <e id='id-1'/>\n"
 
715
        "  <e id='id-2'/>\n"
 
716
        "</doc>";
 
717
 
 
718
    XML_SetStartElementHandler(parser,
 
719
                               check_attr_contains_normalized_whitespace);
 
720
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
721
        xml_failure(parser);
 
722
}
 
723
END_TEST
 
724
 
 
725
 
 
726
/*
 
727
 * XML declaration tests.
 
728
 */
 
729
 
 
730
START_TEST(test_xmldecl_misplaced)
 
731
{
 
732
    expect_failure("\n"
 
733
                   "<?xml version='1.0'?>\n"
 
734
                   "<a/>",
 
735
                   XML_ERROR_MISPLACED_XML_PI,
 
736
                   "failed to report misplaced XML declaration");
 
737
}
 
738
END_TEST
 
739
 
 
740
/* Regression test for SF bug #584832. */
 
741
static int XMLCALL
 
742
UnknownEncodingHandler(void *data,const XML_Char *encoding,XML_Encoding *info)
 
743
{
 
744
    if (strcmp(encoding,"unsupported-encoding") == 0) {
 
745
        int i;
 
746
        for (i = 0; i < 256; ++i)
 
747
            info->map[i] = i;
 
748
        info->data = NULL;
 
749
        info->convert = NULL;
 
750
        info->release = NULL;
 
751
        return XML_STATUS_OK;
 
752
    }
 
753
    return XML_STATUS_ERROR;
 
754
}
 
755
 
 
756
START_TEST(test_unknown_encoding_internal_entity)
 
757
{
 
758
    char *text =
 
759
        "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
 
760
        "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
 
761
        "<test a='&foo;'/>";
 
762
 
 
763
    XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
 
764
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
765
        xml_failure(parser);
 
766
}
 
767
END_TEST
 
768
 
 
769
/* Regression test for SF bug #620106. */
 
770
static int XMLCALL
 
771
external_entity_loader_set_encoding(XML_Parser parser,
 
772
                                    const XML_Char *context,
 
773
                                    const XML_Char *base,
 
774
                                    const XML_Char *systemId,
 
775
                                    const XML_Char *publicId)
 
776
{
 
777
    /* This text says it's an unsupported encoding, but it's really
 
778
       UTF-8, which we tell Expat using XML_SetEncoding().
 
779
    */
 
780
    char *text =
 
781
        "<?xml encoding='iso-8859-3'?>"
 
782
        "\xC3\xA9";
 
783
    XML_Parser extparser;
 
784
 
 
785
    extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
 
786
    if (extparser == NULL)
 
787
        fail("Could not create external entity parser.");
 
788
    if (!XML_SetEncoding(extparser, "utf-8"))
 
789
        fail("XML_SetEncoding() ignored for external entity");
 
790
    if (  XML_Parse(extparser, text, strlen(text), XML_TRUE)
 
791
          == XML_STATUS_ERROR) {
 
792
        xml_failure(parser);
 
793
        return 0;
 
794
    }
 
795
    return 1;
 
796
}
 
797
 
 
798
START_TEST(test_ext_entity_set_encoding)
 
799
{
 
800
    char *text =
 
801
        "<!DOCTYPE doc [\n"
 
802
        "  <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
 
803
        "]>\n"
 
804
        "<doc>&en;</doc>";
 
805
 
 
806
    XML_SetExternalEntityRefHandler(parser,
 
807
                                    external_entity_loader_set_encoding);
 
808
    run_character_check(text, "\xC3\xA9");
 
809
}
 
810
END_TEST
 
811
 
 
812
/* Test that no error is reported for unknown entities if we don't
 
813
   read an external subset.  This was fixed in Expat 1.95.5.
 
814
*/
 
815
START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
 
816
    char *text =
 
817
        "<!DOCTYPE doc SYSTEM 'foo'>\n"
 
818
        "<doc>&entity;</doc>";
 
819
 
 
820
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
821
        xml_failure(parser);
 
822
}
 
823
END_TEST
 
824
 
 
825
/* Test that an error is reported for unknown entities if we don't
 
826
   have an external subset.
 
827
*/
 
828
START_TEST(test_wfc_undeclared_entity_no_external_subset) {
 
829
    expect_failure("<doc>&entity;</doc>",
 
830
                   XML_ERROR_UNDEFINED_ENTITY,
 
831
                   "Parser did not report undefined entity w/out a DTD.");
 
832
}
 
833
END_TEST
 
834
 
 
835
/* Test that an error is reported for unknown entities if we don't
 
836
   read an external subset, but have been declared standalone.
 
837
*/
 
838
START_TEST(test_wfc_undeclared_entity_standalone) {
 
839
    char *text =
 
840
        "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
 
841
        "<!DOCTYPE doc SYSTEM 'foo'>\n"
 
842
        "<doc>&entity;</doc>";
 
843
 
 
844
    expect_failure(text,
 
845
                   XML_ERROR_UNDEFINED_ENTITY,
 
846
                   "Parser did not report undefined entity (standalone).");
 
847
}
 
848
END_TEST
 
849
 
 
850
static int XMLCALL
 
851
external_entity_loader(XML_Parser parser,
 
852
                       const XML_Char *context,
 
853
                       const XML_Char *base,
 
854
                       const XML_Char *systemId,
 
855
                       const XML_Char *publicId)
 
856
{
 
857
    char *text = (char *)XML_GetUserData(parser);
 
858
    XML_Parser extparser;
 
859
 
 
860
    extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
 
861
    if (extparser == NULL)
 
862
        fail("Could not create external entity parser.");
 
863
    if (  XML_Parse(extparser, text, strlen(text), XML_TRUE)
 
864
          == XML_STATUS_ERROR) {
 
865
        xml_failure(parser);
 
866
        return XML_STATUS_ERROR;
 
867
    }
 
868
    return XML_STATUS_OK;
 
869
}
 
870
 
 
871
/* Test that an error is reported for unknown entities if we have read
 
872
   an external subset, and standalone is true.
 
873
*/
 
874
START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
 
875
    char *text =
 
876
        "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
 
877
        "<!DOCTYPE doc SYSTEM 'foo'>\n"
 
878
        "<doc>&entity;</doc>";
 
879
    char *foo_text =
 
880
        "<!ELEMENT doc (#PCDATA)*>";
 
881
 
 
882
    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
 
883
    XML_SetUserData(parser, foo_text);
 
884
    XML_SetExternalEntityRefHandler(parser, external_entity_loader);
 
885
    expect_failure(text,
 
886
                   XML_ERROR_UNDEFINED_ENTITY,
 
887
                   "Parser did not report undefined entity (external DTD).");
 
888
}
 
889
END_TEST
 
890
 
 
891
/* Test that no error is reported for unknown entities if we have read
 
892
   an external subset, and standalone is false.
 
893
*/
 
894
START_TEST(test_wfc_undeclared_entity_with_external_subset) {
 
895
    char *text =
 
896
        "<?xml version='1.0' encoding='us-ascii'?>\n"
 
897
        "<!DOCTYPE doc SYSTEM 'foo'>\n"
 
898
        "<doc>&entity;</doc>";
 
899
    char *foo_text =
 
900
        "<!ELEMENT doc (#PCDATA)*>";
 
901
 
 
902
    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
 
903
    XML_SetUserData(parser, foo_text);
 
904
    XML_SetExternalEntityRefHandler(parser, external_entity_loader);
 
905
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
906
        xml_failure(parser);
 
907
}
 
908
END_TEST
 
909
 
 
910
START_TEST(test_wfc_no_recursive_entity_refs)
 
911
{
 
912
    char *text =
 
913
        "<!DOCTYPE doc [\n"
 
914
        "  <!ENTITY entity '&#38;entity;'>\n"
 
915
        "]>\n"
 
916
        "<doc>&entity;</doc>";
 
917
 
 
918
    expect_failure(text,
 
919
                   XML_ERROR_RECURSIVE_ENTITY_REF,
 
920
                   "Parser did not report recursive entity reference.");
 
921
}
 
922
END_TEST
 
923
 
 
924
/* Regression test for SF bug #483514. */
 
925
START_TEST(test_dtd_default_handling)
 
926
{
 
927
    char *text =
 
928
        "<!DOCTYPE doc [\n"
 
929
        "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
 
930
        "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
 
931
        "<!ELEMENT doc EMPTY>\n"
 
932
        "<!ATTLIST doc a CDATA #IMPLIED>\n"
 
933
        "<?pi in dtd?>\n"
 
934
        "<!--comment in dtd-->\n"
 
935
        "]><doc/>";
 
936
 
 
937
    XML_SetDefaultHandler(parser, accumulate_characters);
 
938
    XML_SetDoctypeDeclHandler(parser,
 
939
                              dummy_start_doctype_handler,
 
940
                              dummy_end_doctype_handler);
 
941
    XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
 
942
    XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
 
943
    XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
 
944
    XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
 
945
    XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
 
946
    XML_SetCommentHandler(parser, dummy_comment_handler);
 
947
    run_character_check(text, "\n\n\n\n\n\n\n<doc/>");
 
948
}
 
949
END_TEST
 
950
 
 
951
/* See related SF bug #673791.
 
952
   When namespace processing is enabled, setting the namespace URI for
 
953
   a prefix is not allowed; this test ensures that it *is* allowed
 
954
   when namespace processing is not enabled.
 
955
   (See Namespaces in XML, section 2.)
 
956
*/
 
957
START_TEST(test_empty_ns_without_namespaces)
 
958
{
 
959
    char *text =
 
960
        "<doc xmlns:prefix='http://www.example.com/'>\n"
 
961
        "  <e xmlns:prefix=''/>\n"
 
962
        "</doc>";
 
963
 
 
964
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
965
        xml_failure(parser);
 
966
}
 
967
END_TEST
 
968
 
 
969
/* Regression test for SF bug #824420.
 
970
   Checks that an xmlns:prefix attribute set in an attribute's default
 
971
   value isn't misinterpreted.
 
972
*/
 
973
START_TEST(test_ns_in_attribute_default_without_namespaces)
 
974
{
 
975
    char *text =
 
976
        "<!DOCTYPE e:element [\n"
 
977
        "  <!ATTLIST e:element\n"
 
978
        "    xmlns:e CDATA 'http://example.com/'>\n"
 
979
        "      ]>\n"
 
980
        "<e:element/>";
 
981
 
 
982
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
983
        xml_failure(parser);
 
984
}
 
985
END_TEST
 
986
 
 
987
static char *long_character_data_text =
 
988
    "<?xml version='1.0' encoding='iso-8859-1'?><s>"
 
989
    "012345678901234567890123456789012345678901234567890123456789"
 
990
    "012345678901234567890123456789012345678901234567890123456789"
 
991
    "012345678901234567890123456789012345678901234567890123456789"
 
992
    "012345678901234567890123456789012345678901234567890123456789"
 
993
    "012345678901234567890123456789012345678901234567890123456789"
 
994
    "012345678901234567890123456789012345678901234567890123456789"
 
995
    "012345678901234567890123456789012345678901234567890123456789"
 
996
    "012345678901234567890123456789012345678901234567890123456789"
 
997
    "012345678901234567890123456789012345678901234567890123456789"
 
998
    "012345678901234567890123456789012345678901234567890123456789"
 
999
    "012345678901234567890123456789012345678901234567890123456789"
 
1000
    "012345678901234567890123456789012345678901234567890123456789"
 
1001
    "012345678901234567890123456789012345678901234567890123456789"
 
1002
    "012345678901234567890123456789012345678901234567890123456789"
 
1003
    "012345678901234567890123456789012345678901234567890123456789"
 
1004
    "012345678901234567890123456789012345678901234567890123456789"
 
1005
    "012345678901234567890123456789012345678901234567890123456789"
 
1006
    "012345678901234567890123456789012345678901234567890123456789"
 
1007
    "012345678901234567890123456789012345678901234567890123456789"
 
1008
    "012345678901234567890123456789012345678901234567890123456789"
 
1009
    "</s>";
 
1010
 
 
1011
static XML_Bool resumable = XML_FALSE;
 
1012
 
 
1013
static void
 
1014
clearing_aborting_character_handler(void *userData,
 
1015
                                    const XML_Char *s, int len)
 
1016
{
 
1017
    XML_StopParser(parser, resumable);
 
1018
    XML_SetCharacterDataHandler(parser, NULL);
 
1019
}
 
1020
 
 
1021
/* Regression test for SF bug #1515266: missing check of stopped
 
1022
   parser in doContext() 'for' loop. */
 
1023
START_TEST(test_stop_parser_between_char_data_calls)
 
1024
{
 
1025
    /* The sample data must be big enough that there are two calls to
 
1026
       the character data handler from within the inner "for" loop of
 
1027
       the XML_TOK_DATA_CHARS case in doContent(), and the character
 
1028
       handler must stop the parser and clear the character data
 
1029
       handler.
 
1030
    */
 
1031
    char *text = long_character_data_text;
 
1032
 
 
1033
    XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
 
1034
    resumable = XML_FALSE;
 
1035
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
 
1036
        xml_failure(parser);
 
1037
    if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
 
1038
        xml_failure(parser);
 
1039
}
 
1040
END_TEST
 
1041
 
 
1042
/* Regression test for SF bug #1515266: missing check of stopped
 
1043
   parser in doContext() 'for' loop. */
 
1044
START_TEST(test_suspend_parser_between_char_data_calls)
 
1045
{
 
1046
    /* The sample data must be big enough that there are two calls to
 
1047
       the character data handler from within the inner "for" loop of
 
1048
       the XML_TOK_DATA_CHARS case in doContent(), and the character
 
1049
       handler must stop the parser and clear the character data
 
1050
       handler.
 
1051
    */
 
1052
    char *text = long_character_data_text;
 
1053
 
 
1054
    XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
 
1055
    resumable = XML_TRUE;
 
1056
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED)
 
1057
        xml_failure(parser);
 
1058
    if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
 
1059
        xml_failure(parser);
 
1060
}
 
1061
END_TEST
 
1062
 
 
1063
 
 
1064
/*
 
1065
 * Namespaces tests.
 
1066
 */
 
1067
 
 
1068
static void
 
1069
namespace_setup(void)
 
1070
{
 
1071
    parser = XML_ParserCreateNS(NULL, ' ');
 
1072
    if (parser == NULL)
 
1073
        fail("Parser not created.");
 
1074
}
 
1075
 
 
1076
static void
 
1077
namespace_teardown(void)
 
1078
{
 
1079
    basic_teardown();
 
1080
}
 
1081
 
 
1082
/* Check that an element name and attribute name match the expected values.
 
1083
   The expected values are passed as an array reference of string pointers
 
1084
   provided as the userData argument; the first is the expected
 
1085
   element name, and the second is the expected attribute name.
 
1086
*/
 
1087
static void XMLCALL
 
1088
triplet_start_checker(void *userData, const XML_Char *name,
 
1089
                      const XML_Char **atts)
 
1090
{
 
1091
    char **elemstr = (char **)userData;
 
1092
    char buffer[1024];
 
1093
    if (strcmp(elemstr[0], name) != 0) {
 
1094
        sprintf(buffer, "unexpected start string: '%s'", name);
 
1095
        fail(buffer);
 
1096
    }
 
1097
    if (strcmp(elemstr[1], atts[0]) != 0) {
 
1098
        sprintf(buffer, "unexpected attribute string: '%s'", atts[0]);
 
1099
        fail(buffer);
 
1100
    }
 
1101
}
 
1102
 
 
1103
/* Check that the element name passed to the end-element handler matches
 
1104
   the expected value.  The expected value is passed as the first element
 
1105
   in an array of strings passed as the userData argument.
 
1106
*/
 
1107
static void XMLCALL
 
1108
triplet_end_checker(void *userData, const XML_Char *name)
 
1109
{
 
1110
    char **elemstr = (char **)userData;
 
1111
    if (strcmp(elemstr[0], name) != 0) {
 
1112
        char buffer[1024];
 
1113
        sprintf(buffer, "unexpected end string: '%s'", name);
 
1114
        fail(buffer);
 
1115
    }
 
1116
}
 
1117
 
 
1118
START_TEST(test_return_ns_triplet)
 
1119
{
 
1120
    char *text =
 
1121
        "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
 
1122
        "       xmlns:bar='http://expat.sf.net/'></foo:e>";
 
1123
    char *elemstr[] = {
 
1124
        "http://expat.sf.net/ e foo",
 
1125
        "http://expat.sf.net/ a bar"
 
1126
    };
 
1127
    XML_SetReturnNSTriplet(parser, XML_TRUE);
 
1128
    XML_SetUserData(parser, elemstr);
 
1129
    XML_SetElementHandler(parser, triplet_start_checker, triplet_end_checker);
 
1130
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
1131
        xml_failure(parser);
 
1132
}
 
1133
END_TEST
 
1134
 
 
1135
static void XMLCALL
 
1136
overwrite_start_checker(void *userData, const XML_Char *name,
 
1137
                        const XML_Char **atts)
 
1138
{
 
1139
    CharData *storage = (CharData *) userData;
 
1140
    CharData_AppendString(storage, "start ");
 
1141
    CharData_AppendXMLChars(storage, name, -1);
 
1142
    while (*atts != NULL) {
 
1143
        CharData_AppendString(storage, "\nattribute ");
 
1144
        CharData_AppendXMLChars(storage, *atts, -1);
 
1145
        atts += 2;
 
1146
    }
 
1147
    CharData_AppendString(storage, "\n");
 
1148
}
 
1149
 
 
1150
static void XMLCALL
 
1151
overwrite_end_checker(void *userData, const XML_Char *name)
 
1152
{
 
1153
    CharData *storage = (CharData *) userData;
 
1154
    CharData_AppendString(storage, "end ");
 
1155
    CharData_AppendXMLChars(storage, name, -1);
 
1156
    CharData_AppendString(storage, "\n");
 
1157
}
 
1158
 
 
1159
static void
 
1160
run_ns_tagname_overwrite_test(char *text, char *result)
 
1161
{
 
1162
    CharData storage;
 
1163
    CharData_Init(&storage);
 
1164
    XML_SetUserData(parser, &storage);
 
1165
    XML_SetElementHandler(parser,
 
1166
                          overwrite_start_checker, overwrite_end_checker);
 
1167
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
1168
        xml_failure(parser);
 
1169
    CharData_CheckString(&storage, result);
 
1170
}
 
1171
 
 
1172
/* Regression test for SF bug #566334. */
 
1173
START_TEST(test_ns_tagname_overwrite)
 
1174
{
 
1175
    char *text =
 
1176
        "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
 
1177
        "  <n:f n:attr='foo'/>\n"
 
1178
        "  <n:g n:attr2='bar'/>\n"
 
1179
        "</n:e>";
 
1180
    char *result =
 
1181
        "start http://xml.libexpat.org/ e\n"
 
1182
        "start http://xml.libexpat.org/ f\n"
 
1183
        "attribute http://xml.libexpat.org/ attr\n"
 
1184
        "end http://xml.libexpat.org/ f\n"
 
1185
        "start http://xml.libexpat.org/ g\n"
 
1186
        "attribute http://xml.libexpat.org/ attr2\n"
 
1187
        "end http://xml.libexpat.org/ g\n"
 
1188
        "end http://xml.libexpat.org/ e\n";
 
1189
    run_ns_tagname_overwrite_test(text, result);
 
1190
}
 
1191
END_TEST
 
1192
 
 
1193
/* Regression test for SF bug #566334. */
 
1194
START_TEST(test_ns_tagname_overwrite_triplet)
 
1195
{
 
1196
    char *text =
 
1197
        "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
 
1198
        "  <n:f n:attr='foo'/>\n"
 
1199
        "  <n:g n:attr2='bar'/>\n"
 
1200
        "</n:e>";
 
1201
    char *result =
 
1202
        "start http://xml.libexpat.org/ e n\n"
 
1203
        "start http://xml.libexpat.org/ f n\n"
 
1204
        "attribute http://xml.libexpat.org/ attr n\n"
 
1205
        "end http://xml.libexpat.org/ f n\n"
 
1206
        "start http://xml.libexpat.org/ g n\n"
 
1207
        "attribute http://xml.libexpat.org/ attr2 n\n"
 
1208
        "end http://xml.libexpat.org/ g n\n"
 
1209
        "end http://xml.libexpat.org/ e n\n";
 
1210
    XML_SetReturnNSTriplet(parser, XML_TRUE);
 
1211
    run_ns_tagname_overwrite_test(text, result);
 
1212
}
 
1213
END_TEST
 
1214
 
 
1215
 
 
1216
/* Regression test for SF bug #620343. */
 
1217
static void XMLCALL
 
1218
start_element_fail(void *userData,
 
1219
                   const XML_Char *name, const XML_Char **atts)
 
1220
{
 
1221
    /* We should never get here. */
 
1222
    fail("should never reach start_element_fail()");
 
1223
}
 
1224
 
 
1225
static void XMLCALL
 
1226
start_ns_clearing_start_element(void *userData,
 
1227
                                const XML_Char *prefix,
 
1228
                                const XML_Char *uri)
 
1229
{
 
1230
    XML_SetStartElementHandler((XML_Parser) userData, NULL);
 
1231
}
 
1232
 
 
1233
START_TEST(test_start_ns_clears_start_element)
 
1234
{
 
1235
    /* This needs to use separate start/end tags; using the empty tag
 
1236
       syntax doesn't cause the problematic path through Expat to be
 
1237
       taken.
 
1238
    */
 
1239
    char *text = "<e xmlns='http://xml.libexpat.org/'></e>";
 
1240
 
 
1241
    XML_SetStartElementHandler(parser, start_element_fail);
 
1242
    XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
 
1243
    XML_UseParserAsHandlerArg(parser);
 
1244
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
1245
        xml_failure(parser);
 
1246
}
 
1247
END_TEST
 
1248
 
 
1249
/* Regression test for SF bug #616863. */
 
1250
static int XMLCALL
 
1251
external_entity_handler(XML_Parser parser,
 
1252
                        const XML_Char *context,
 
1253
                        const XML_Char *base,
 
1254
                        const XML_Char *systemId,
 
1255
                        const XML_Char *publicId) 
 
1256
{
 
1257
    long callno = 1 + (long)XML_GetUserData(parser);
 
1258
    char *text;
 
1259
    XML_Parser p2;
 
1260
 
 
1261
    if (callno == 1)
 
1262
        text = ("<!ELEMENT doc (e+)>\n"
 
1263
                "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
 
1264
                "<!ELEMENT e EMPTY>\n");
 
1265
    else
 
1266
        text = ("<?xml version='1.0' encoding='us-ascii'?>"
 
1267
                "<e/>");
 
1268
 
 
1269
    XML_SetUserData(parser, (void *) callno);
 
1270
    p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
 
1271
    if (XML_Parse(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
 
1272
        xml_failure(p2);
 
1273
        return 0;
 
1274
    }
 
1275
    XML_ParserFree(p2);
 
1276
    return 1;
 
1277
}
 
1278
 
 
1279
START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
 
1280
{
 
1281
    char *text =
 
1282
        "<?xml version='1.0'?>\n"
 
1283
        "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
 
1284
        "  <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
 
1285
        "]>\n"
 
1286
        "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
 
1287
        "&en;\n"
 
1288
        "</doc>";
 
1289
 
 
1290
    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
 
1291
    XML_SetExternalEntityRefHandler(parser, external_entity_handler);
 
1292
    /* We actually need to set this handler to tickle this bug. */
 
1293
    XML_SetStartElementHandler(parser, dummy_start_element);
 
1294
    XML_SetUserData(parser, NULL);
 
1295
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
1296
        xml_failure(parser);
 
1297
}
 
1298
END_TEST
 
1299
 
 
1300
/* Regression test #1 for SF bug #673791. */
 
1301
START_TEST(test_ns_prefix_with_empty_uri_1)
 
1302
{
 
1303
    char *text =
 
1304
        "<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
 
1305
        "  <e xmlns:prefix=''/>\n"
 
1306
        "</doc>";
 
1307
 
 
1308
    expect_failure(text,
 
1309
                   XML_ERROR_UNDECLARING_PREFIX,
 
1310
                   "Did not report re-setting namespace"
 
1311
                   " URI with prefix to ''.");
 
1312
}
 
1313
END_TEST
 
1314
 
 
1315
/* Regression test #2 for SF bug #673791. */
 
1316
START_TEST(test_ns_prefix_with_empty_uri_2)
 
1317
{
 
1318
    char *text =
 
1319
        "<?xml version='1.0'?>\n"
 
1320
        "<docelem xmlns:pre=''/>";
 
1321
 
 
1322
    expect_failure(text,
 
1323
                   XML_ERROR_UNDECLARING_PREFIX,
 
1324
                   "Did not report setting namespace URI with prefix to ''.");
 
1325
}
 
1326
END_TEST
 
1327
 
 
1328
/* Regression test #3 for SF bug #673791. */
 
1329
START_TEST(test_ns_prefix_with_empty_uri_3)
 
1330
{
 
1331
    char *text =
 
1332
        "<!DOCTYPE doc [\n"
 
1333
        "  <!ELEMENT doc EMPTY>\n"
 
1334
        "  <!ATTLIST doc\n"
 
1335
        "    xmlns:prefix CDATA ''>\n"
 
1336
        "]>\n"
 
1337
        "<doc/>";
 
1338
 
 
1339
    expect_failure(text,
 
1340
                   XML_ERROR_UNDECLARING_PREFIX,
 
1341
                   "Didn't report attr default setting NS w/ prefix to ''.");
 
1342
}
 
1343
END_TEST
 
1344
 
 
1345
/* Regression test #4 for SF bug #673791. */
 
1346
START_TEST(test_ns_prefix_with_empty_uri_4)
 
1347
{
 
1348
    char *text =
 
1349
        "<!DOCTYPE doc [\n"
 
1350
        "  <!ELEMENT prefix:doc EMPTY>\n"
 
1351
        "  <!ATTLIST prefix:doc\n"
 
1352
        "    xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
 
1353
        "]>\n"
 
1354
        "<prefix:doc/>";
 
1355
    /* Packaged info expected by the end element handler;
 
1356
       the weird structuring lets us re-use the triplet_end_checker()
 
1357
       function also used for another test. */
 
1358
    char *elemstr[] = {
 
1359
        "http://xml.libexpat.org/ doc prefix"
 
1360
    };
 
1361
    XML_SetReturnNSTriplet(parser, XML_TRUE);
 
1362
    XML_SetUserData(parser, elemstr);
 
1363
    XML_SetEndElementHandler(parser, triplet_end_checker);
 
1364
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
1365
        xml_failure(parser);
 
1366
}
 
1367
END_TEST
 
1368
 
 
1369
START_TEST(test_ns_default_with_empty_uri)
 
1370
{
 
1371
    char *text =
 
1372
        "<doc xmlns='http://xml.libexpat.org/'>\n"
 
1373
        "  <e xmlns=''/>\n"
 
1374
        "</doc>";
 
1375
    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
 
1376
        xml_failure(parser);
 
1377
}
 
1378
END_TEST
 
1379
 
 
1380
/* Regression test for SF bug #692964: two prefixes for one namespace. */
 
1381
START_TEST(test_ns_duplicate_attrs_diff_prefixes)
 
1382
{
 
1383
    char *text =
 
1384
        "<doc xmlns:a='http://xml.libexpat.org/a'\n"
 
1385
        "     xmlns:b='http://xml.libexpat.org/a'\n"
 
1386
        "     a:a='v' b:a='v' />";
 
1387
    expect_failure(text,
 
1388
                   XML_ERROR_DUPLICATE_ATTRIBUTE,
 
1389
                   "did not report multiple attributes with same URI+name");
 
1390
}
 
1391
END_TEST
 
1392
 
 
1393
/* Regression test for SF bug #695401: unbound prefix. */
 
1394
START_TEST(test_ns_unbound_prefix_on_attribute)
 
1395
{
 
1396
    char *text = "<doc a:attr=''/>";
 
1397
    expect_failure(text,
 
1398
                   XML_ERROR_UNBOUND_PREFIX,
 
1399
                   "did not report unbound prefix on attribute");
 
1400
}
 
1401
END_TEST
 
1402
 
 
1403
/* Regression test for SF bug #695401: unbound prefix. */
 
1404
START_TEST(test_ns_unbound_prefix_on_element)
 
1405
{
 
1406
    char *text = "<a:doc/>";
 
1407
    expect_failure(text,
 
1408
                   XML_ERROR_UNBOUND_PREFIX,
 
1409
                   "did not report unbound prefix on element");
 
1410
}
 
1411
END_TEST
 
1412
 
 
1413
static Suite *
 
1414
make_suite(void)
 
1415
{
 
1416
    Suite *s = suite_create("basic");
 
1417
    TCase *tc_basic = tcase_create("basic tests");
 
1418
    TCase *tc_namespace = tcase_create("XML namespaces");
 
1419
 
 
1420
    suite_add_tcase(s, tc_basic);
 
1421
    tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
 
1422
    tcase_add_test(tc_basic, test_nul_byte);
 
1423
    tcase_add_test(tc_basic, test_u0000_char);
 
1424
    tcase_add_test(tc_basic, test_bom_utf8);
 
1425
    tcase_add_test(tc_basic, test_bom_utf16_be);
 
1426
    tcase_add_test(tc_basic, test_bom_utf16_le);
 
1427
    tcase_add_test(tc_basic, test_illegal_utf8);
 
1428
    tcase_add_test(tc_basic, test_utf16);
 
1429
    tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
 
1430
    tcase_add_test(tc_basic, test_latin1_umlauts);
 
1431
    /* Regression test for SF bug #491986. */
 
1432
    tcase_add_test(tc_basic, test_danish_latin1);
 
1433
    /* Regression test for SF bug #514281. */
 
1434
    tcase_add_test(tc_basic, test_french_charref_hexidecimal);
 
1435
    tcase_add_test(tc_basic, test_french_charref_decimal);
 
1436
    tcase_add_test(tc_basic, test_french_latin1);
 
1437
    tcase_add_test(tc_basic, test_french_utf8);
 
1438
    tcase_add_test(tc_basic, test_utf8_false_rejection);
 
1439
    tcase_add_test(tc_basic, test_line_number_after_parse);
 
1440
    tcase_add_test(tc_basic, test_column_number_after_parse);
 
1441
    tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
 
1442
    tcase_add_test(tc_basic, test_line_number_after_error);
 
1443
    tcase_add_test(tc_basic, test_column_number_after_error);
 
1444
    tcase_add_test(tc_basic, test_really_long_lines);
 
1445
    tcase_add_test(tc_basic, test_end_element_events);
 
1446
    tcase_add_test(tc_basic, test_attr_whitespace_normalization);
 
1447
    tcase_add_test(tc_basic, test_xmldecl_misplaced);
 
1448
    tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
 
1449
    tcase_add_test(tc_basic,
 
1450
                   test_wfc_undeclared_entity_unread_external_subset);
 
1451
    tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
 
1452
    tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
 
1453
    tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
 
1454
    tcase_add_test(tc_basic,
 
1455
                   test_wfc_undeclared_entity_with_external_subset_standalone);
 
1456
    tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
 
1457
    tcase_add_test(tc_basic, test_ext_entity_set_encoding);
 
1458
    tcase_add_test(tc_basic, test_dtd_default_handling);
 
1459
    tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
 
1460
    tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
 
1461
    tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
 
1462
    tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
 
1463
 
 
1464
    suite_add_tcase(s, tc_namespace);
 
1465
    tcase_add_checked_fixture(tc_namespace,
 
1466
                              namespace_setup, namespace_teardown);
 
1467
    tcase_add_test(tc_namespace, test_return_ns_triplet);
 
1468
    tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
 
1469
    tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
 
1470
    tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
 
1471
    tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
 
1472
    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
 
1473
    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
 
1474
    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
 
1475
    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
 
1476
    tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
 
1477
    tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
 
1478
    tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
 
1479
    tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
 
1480
 
 
1481
    return s;
 
1482
}
 
1483
 
 
1484
 
 
1485
int
 
1486
main(int argc, char *argv[])
 
1487
{
 
1488
    int i, nf;
 
1489
    int verbosity = CK_NORMAL;
 
1490
    Suite *s = make_suite();
 
1491
    SRunner *sr = srunner_create(s);
 
1492
 
 
1493
    /* run the tests for internal helper functions */
 
1494
    testhelper_is_whitespace_normalized();
 
1495
 
 
1496
    for (i = 1; i < argc; ++i) {
 
1497
        char *opt = argv[i];
 
1498
        if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
 
1499
            verbosity = CK_VERBOSE;
 
1500
        else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
 
1501
            verbosity = CK_SILENT;
 
1502
        else {
 
1503
            fprintf(stderr, "runtests: unknown option '%s'\n", opt);
 
1504
            return 2;
 
1505
        }
 
1506
    }
 
1507
    if (verbosity != CK_SILENT)
 
1508
        printf("Expat version: %s\n", XML_ExpatVersion());
 
1509
    srunner_run_all(sr, verbosity);
 
1510
    nf = srunner_ntests_failed(sr);
 
1511
    srunner_free(sr);
 
1512
 
 
1513
    return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 
1514
}