]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/apr-util/test/testxml.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / apr-util / test / testxml.c
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "apr.h"
18 #include "apr_general.h"
19 #include "apr_xml.h"
20 #include "abts.h"
21 #include "testutil.h"
22
23 static apr_status_t create_dummy_file_error(abts_case *tc, apr_pool_t *p,
24                                             apr_file_t **fd)
25 {
26     int i;
27     apr_status_t rv;
28     apr_off_t off = 0L;
29     char template[] = "data/testxmldummyerrorXXXXXX";
30
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);
34
35     if (rv != APR_SUCCESS)
36         return rv;
37
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);
41
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);
46     }
47
48     rv = apr_file_puts("</mary>\n", *fd);
49     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
50
51     rv = apr_file_seek(*fd, APR_SET, &off);
52     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
53
54     return rv;
55 }
56
57 static apr_status_t create_dummy_file(abts_case *tc, apr_pool_t *p,
58                                       apr_file_t **fd)
59 {
60     int i;
61     apr_status_t rv;
62     apr_off_t off = 0L;
63     char template[] = "data/testxmldummyXXXXXX";
64
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);
68
69     if (rv != APR_SUCCESS)
70         return rv;
71
72     rv = apr_file_puts("<?xml version=\"1.0\" ?>\n<mary>\n", *fd);
73     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
74
75     for (i = 0; i < 5000; i++) {
76         rv = apr_file_puts("<hmm roast=\"lamb\" "
77                            "for=\"dinner &lt;&gt;&#x3D;\">yummy</hmm>\n", *fd);
78         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
79     }
80
81     rv = apr_file_puts("</mary>\n", *fd);
82     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
83
84     rv = apr_file_seek(*fd, APR_SET, &off);
85     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
86
87     return rv;
88 }
89
90 static void dump_xml(abts_case *tc, apr_xml_elem *e, int level)
91 {
92     apr_xml_attr *a;
93     apr_xml_elem *ec;
94
95     if (level == 0) {
96         ABTS_STR_EQUAL(tc, "mary", e->name);
97     } else {
98         ABTS_STR_EQUAL(tc, "hmm", e->name);
99     }
100
101     if (e->attr) {
102         a = e->attr;
103         ABTS_PTR_NOTNULL(tc, a);
104         ABTS_STR_EQUAL(tc, "for", a->name);
105         ABTS_STR_EQUAL(tc, "dinner <>=", a->value);
106         a = a->next;
107         ABTS_PTR_NOTNULL(tc, a);
108         ABTS_STR_EQUAL(tc, "roast", a->name);
109         ABTS_STR_EQUAL(tc, "lamb", a->value);
110     }
111     if (e->first_child) {
112         ec = e->first_child;
113         while (ec) {
114             dump_xml(tc, ec, level + 1);
115             ec = ec->next;
116         }
117     }
118 }
119
120 static void test_xml_parser(abts_case *tc, void *data)
121 {
122     apr_file_t *fd;
123     apr_xml_parser *parser;
124     apr_xml_doc *doc;
125     apr_status_t rv;
126
127     rv = create_dummy_file(tc, p, &fd);
128     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
129
130     if (rv != APR_SUCCESS)
131         return;
132
133     rv = apr_xml_parse_file(p, &parser, &doc, fd, 2000);
134     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
135
136     dump_xml(tc, doc->root, 0);
137
138     rv = apr_file_close(fd);
139     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
140
141     rv = create_dummy_file_error(tc, p, &fd);
142     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
143
144     if (rv != APR_SUCCESS)
145         return;
146
147     rv = apr_xml_parse_file(p, &parser, &doc, fd, 2000);
148     ABTS_TRUE(tc, rv != APR_SUCCESS);
149 }
150
151 static void test_billion_laughs(abts_case *tc, void *data)
152 {
153     apr_file_t *fd;
154     apr_xml_parser *parser;
155     apr_xml_doc *doc;
156     apr_status_t rv;
157
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);
161
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);
165
166     apr_file_close(fd);
167 }
168
169 static void test_CVE_2009_3720_alpha(abts_case *tc, void *data)
170 {
171     apr_xml_parser *xp;
172     apr_xml_doc *doc;
173     apr_status_t rv;
174
175     xp = apr_xml_parser_create(p);
176     
177     rv = apr_xml_parser_feed(xp, "\0\r\n", 3);
178     if (rv == APR_SUCCESS)
179         apr_xml_parser_done(xp, &doc);
180 }
181
182 static void test_CVE_2009_3720_beta(abts_case *tc, void *data)
183 {
184     apr_xml_parser *xp;
185     apr_xml_doc *doc;
186     apr_status_t rv;
187
188     xp = apr_xml_parser_create(p);
189     
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);
193 }
194
195 abts_suite *testxml(abts_suite *suite)
196 {
197     suite = ADD_SUITE(suite);
198
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);
203
204     return suite;
205 }