1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "apr_general.h"
23 static apr_status_t create_dummy_file_error(abts_case *tc, apr_pool_t *p,
29 char template[] = "data/testxmldummyerrorXXXXXX";
31 rv = apr_file_mktemp(fd, template, APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE | APR_FOPEN_DELONCLOSE |
32 APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_EXCL, p);
33 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
35 if (rv != APR_SUCCESS)
38 rv = apr_file_puts("<?xml version=\"1.0\" ?>\n<maryx>"
39 "<had a=\"little\"/><lamb/>\n", *fd);
40 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
42 for (i = 0; i < 5000; i++) {
43 rv = apr_file_puts("<hmm roast=\"lamb\" "
44 "for=\"dinner\">yummy</hmm>\n", *fd);
45 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
48 rv = apr_file_puts("</mary>\n", *fd);
49 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
51 rv = apr_file_seek(*fd, APR_SET, &off);
52 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
57 static apr_status_t create_dummy_file(abts_case *tc, apr_pool_t *p,
63 char template[] = "data/testxmldummyXXXXXX";
65 rv = apr_file_mktemp(fd, template, APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE | APR_FOPEN_DELONCLOSE |
66 APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_EXCL, p);
67 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
69 if (rv != APR_SUCCESS)
72 rv = apr_file_puts("<?xml version=\"1.0\" ?>\n<mary>\n", *fd);
73 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
75 for (i = 0; i < 5000; i++) {
76 rv = apr_file_puts("<hmm roast=\"lamb\" "
77 "for=\"dinner <>=\">yummy</hmm>\n", *fd);
78 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
81 rv = apr_file_puts("</mary>\n", *fd);
82 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
84 rv = apr_file_seek(*fd, APR_SET, &off);
85 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
90 static void dump_xml(abts_case *tc, apr_xml_elem *e, int level)
96 ABTS_STR_EQUAL(tc, "mary", e->name);
98 ABTS_STR_EQUAL(tc, "hmm", e->name);
103 ABTS_PTR_NOTNULL(tc, a);
104 ABTS_STR_EQUAL(tc, "for", a->name);
105 ABTS_STR_EQUAL(tc, "dinner <>=", a->value);
107 ABTS_PTR_NOTNULL(tc, a);
108 ABTS_STR_EQUAL(tc, "roast", a->name);
109 ABTS_STR_EQUAL(tc, "lamb", a->value);
111 if (e->first_child) {
114 dump_xml(tc, ec, level + 1);
120 static void test_xml_parser(abts_case *tc, void *data)
123 apr_xml_parser *parser;
127 rv = create_dummy_file(tc, p, &fd);
128 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
130 if (rv != APR_SUCCESS)
133 rv = apr_xml_parse_file(p, &parser, &doc, fd, 2000);
134 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
136 dump_xml(tc, doc->root, 0);
138 rv = apr_file_close(fd);
139 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
141 rv = create_dummy_file_error(tc, p, &fd);
142 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
144 if (rv != APR_SUCCESS)
147 rv = apr_xml_parse_file(p, &parser, &doc, fd, 2000);
148 ABTS_TRUE(tc, rv != APR_SUCCESS);
151 static void test_billion_laughs(abts_case *tc, void *data)
154 apr_xml_parser *parser;
158 rv = apr_file_open(&fd, "data/billion-laughs.xml",
159 APR_FOPEN_READ, 0, p);
160 apr_assert_success(tc, "open billion-laughs.xml", rv);
162 /* Don't test for return value; if it returns, chances are the bug
163 * is fixed or the machine has insane amounts of RAM. */
164 apr_xml_parse_file(p, &parser, &doc, fd, 2000);
169 static void test_CVE_2009_3720_alpha(abts_case *tc, void *data)
175 xp = apr_xml_parser_create(p);
177 rv = apr_xml_parser_feed(xp, "\0\r\n", 3);
178 if (rv == APR_SUCCESS)
179 apr_xml_parser_done(xp, &doc);
182 static void test_CVE_2009_3720_beta(abts_case *tc, void *data)
188 xp = apr_xml_parser_create(p);
190 rv = apr_xml_parser_feed(xp, "<?xml version\xc2\x85='1.0'?>\r\n", 25);
191 if (rv == APR_SUCCESS)
192 apr_xml_parser_done(xp, &doc);
195 abts_suite *testxml(abts_suite *suite)
197 suite = ADD_SUITE(suite);
199 abts_run_test(suite, test_xml_parser, NULL);
200 abts_run_test(suite, test_billion_laughs, NULL);
201 abts_run_test(suite, test_CVE_2009_3720_alpha, NULL);
202 abts_run_test(suite, test_CVE_2009_3720_beta, NULL);