summaryrefslogtreecommitdiffstats
path: root/rubbos/app/httpd-2.0.64/srclib/apr-util/test/testxml.c
diff options
context:
space:
mode:
Diffstat (limited to 'rubbos/app/httpd-2.0.64/srclib/apr-util/test/testxml.c')
-rw-r--r--rubbos/app/httpd-2.0.64/srclib/apr-util/test/testxml.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/rubbos/app/httpd-2.0.64/srclib/apr-util/test/testxml.c b/rubbos/app/httpd-2.0.64/srclib/apr-util/test/testxml.c
new file mode 100644
index 00000000..748f43b3
--- /dev/null
+++ b/rubbos/app/httpd-2.0.64/srclib/apr-util/test/testxml.c
@@ -0,0 +1,287 @@
+/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr.h"
+#include "apr_general.h"
+#include "apr_xml.h"
+
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h> /* for exit() */
+#endif
+
+static const char *progname;
+static const char *usage = "%s [xmlfile]\nIt will create "
+ "a dummy XML file if none is supplied";
+/*
+ * If our platform knows about the tmpnam() external buffer size, create
+ * a buffer to pass in. This is needed in a threaded environment, or
+ * one that thinks it is (like HP-UX).
+ */
+
+#ifdef L_tmpnam
+static char tname_buf[L_tmpnam];
+#else
+static char *tname_buf = NULL;
+#endif
+
+static apr_status_t create_dummy_file_error(apr_pool_t *p, apr_file_t **fd)
+{
+ apr_status_t rv;
+ char *tmpfile;
+ int i;
+ apr_off_t off = 0L;
+ tmpfile = tmpnam(tname_buf);
+
+ if ((tmpfile == NULL) || (*tmpfile == '\0')) {
+ fprintf(stderr, "unable to generate temporary filename\n");
+ if (errno == 0) {
+ errno = ENOENT;
+ }
+ perror("tmpnam");
+ return APR_ENOENT;
+ }
+ rv = apr_file_open(fd, tmpfile, APR_CREATE|APR_TRUNCATE|APR_DELONCLOSE|
+ APR_READ|APR_WRITE|APR_EXCL, APR_OS_DEFAULT, p);
+
+ if (rv != APR_SUCCESS)
+ return rv;
+ rv = apr_file_puts("<?xml version=\"1.0\" ?>\n<maryx>"
+ "<had a=\"little\"/><lamb its='fleece "
+ "was white as snow' />\n", *fd);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ for (i = 0; i < 5000; i++) {
+ rv = apr_file_puts("<hmm roast=\"lamb\" "
+ "for=\"dinner\">yummy</hmm>\n", *fd);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ rv = apr_file_puts("</mary>\n", *fd);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ return apr_file_seek(*fd, APR_SET, &off);
+}
+
+static apr_status_t create_dummy_file(apr_pool_t *p, apr_file_t **fd)
+{
+ apr_status_t rv;
+ char *tmpfile;
+ int i;
+ apr_off_t off = 0L;
+ tmpfile = tmpnam(tname_buf);
+
+ if ((tmpfile == NULL) || (*tmpfile == '\0')) {
+ fprintf(stderr, "unable to generate temporary filename\n");
+ if (errno == 0) {
+ errno = ENOENT;
+ }
+ perror("tmpnam");
+ return APR_ENOENT;
+ }
+ rv = apr_file_open(fd, tmpfile, APR_CREATE|APR_TRUNCATE|APR_DELONCLOSE|
+ APR_READ|APR_WRITE|APR_EXCL, APR_OS_DEFAULT, p);
+
+ if (rv != APR_SUCCESS)
+ return rv;
+ rv = apr_file_puts("<?xml version=\"1.0\" ?>\n<mary>"
+ "<had a=\"little\"/><lamb its='fleece "
+ "was white as snow' />\n", *fd);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ for (i = 0; i < 5000; i++) {
+ rv = apr_file_puts("<hmm roast=\"lamb\" "
+ "for=\"dinner\">yummy</hmm>\n", *fd);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ rv = apr_file_puts("</mary>\n", *fd);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ rv = apr_file_seek(*fd, APR_SET, &off);
+ return rv;
+}
+
+static void dump_xml(apr_xml_elem *e, int level)
+{
+ apr_xml_attr *a;
+ apr_xml_elem *ec;
+
+ printf("%d: element %s\n", level, e->name);
+ if (e->attr) {
+ a = e->attr;
+ printf("%d:\tattrs\t", level);
+ while (a) {
+ printf("%s=%s\t", a->name, a->value);
+ a = a->next;
+ }
+ printf("\n");
+ }
+ if (e->first_child) {
+ ec = e->first_child;
+ while (ec) {
+ dump_xml(ec, level + 1);
+ ec = ec->next;
+ }
+ }
+}
+
+static void oops(const char *s1, const char *s2, apr_status_t rv)
+{
+ if (progname)
+ fprintf(stderr, "%s: ", progname);
+ fprintf(stderr, s1, s2);
+ if (rv != APR_SUCCESS) {
+ char buf[120];
+
+ fprintf(stderr, " (%s)", apr_strerror(rv, buf, sizeof buf));
+ }
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+static int test_xml_parser(apr_pool_t *pool, const char *file)
+{
+ apr_file_t *fd;
+ apr_xml_parser *parser;
+ apr_xml_doc *doc;
+ apr_status_t rv;
+ char errbuf[2000];
+ char errbufXML[2000];
+
+ if (file == NULL) {
+ rv = create_dummy_file(pool, &fd);
+ if (rv != APR_SUCCESS) {
+ oops("cannot create dummy file", "oops", rv);
+ }
+ }
+ else {
+ rv = apr_file_open(&fd, file, APR_READ, APR_OS_DEFAULT, pool);
+ if (rv != APR_SUCCESS) {
+ oops("cannot open: %s", file, rv);
+ }
+ }
+
+ rv = apr_xml_parse_file(pool, &parser, &doc, fd, 2000);
+ if (rv != APR_SUCCESS) {
+ fprintf(stderr, "APR Error %s\nXML Error: %s\n",
+ apr_strerror(rv, errbuf, sizeof(errbuf)),
+ apr_xml_parser_geterror(parser, errbufXML, sizeof(errbufXML)));
+ return rv;
+ }
+
+ dump_xml(doc->root, 0);
+
+ rv = apr_file_close(fd);
+
+ if (file == NULL) {
+ rv = create_dummy_file_error(pool, &fd);
+ if (rv != APR_SUCCESS) {
+ oops("cannot create error dummy file", "oops", rv);
+ }
+ rv = apr_xml_parse_file(pool, &parser, &doc, fd, 2000);
+ if (rv != APR_SUCCESS) {
+ fprintf(stdout, "APR Error %s\nXML Error: %s "
+ "(EXPECTED) This is good.\n",
+ apr_strerror(rv, errbuf, sizeof(errbuf)),
+ apr_xml_parser_geterror(parser, errbufXML, sizeof(errbufXML)));
+ rv = APR_SUCCESS; /* reset the return code, as the test is supposed to get this error */
+ }
+ else {
+ fprintf(stderr, "Expected an error, but didn't get one ;( ");
+ return APR_EGENERAL;
+ }
+ }
+ return rv;
+}
+
+static void test_billion_laughs(apr_pool_t *pool)
+{
+ apr_file_t *fd;
+ apr_xml_parser *parser;
+ apr_xml_doc *doc;
+ apr_status_t rv;
+ char errbuf[2000];
+
+ rv = apr_file_open(&fd, "data/billion-laughs.xml",
+ APR_READ, 0, pool);
+ if (rv != APR_SUCCESS) {
+ fprintf(stderr, "APR Error %s\n",
+ apr_strerror(rv, errbuf, sizeof(errbuf)));
+ }
+
+ /* Don't test for return value; if it returns, chances are the bug
+ * is fixed or the machine has insane amounts of RAM. */
+ apr_xml_parse_file(pool, &parser, &doc, fd, 2000);
+
+ apr_file_close(fd);
+}
+
+static void test_CVE_2009_3720_alpha(apr_pool_t *pool)
+{
+ apr_xml_parser *xp;
+ apr_xml_doc *doc;
+ apr_status_t rv;
+
+ xp = apr_xml_parser_create(pool);
+
+ rv = apr_xml_parser_feed(xp, "\0\r\n", 3);
+ if (rv == APR_SUCCESS)
+ apr_xml_parser_done(xp, &doc);
+}
+
+static void test_CVE_2009_3720_beta(apr_pool_t *pool)
+{
+ apr_xml_parser *xp;
+ apr_xml_doc *doc;
+ apr_status_t rv;
+
+ xp = apr_xml_parser_create(pool);
+
+ rv = apr_xml_parser_feed(xp, "<?xml version\xc2\x85='1.0'?>\r\n", 25);
+ if (rv == APR_SUCCESS)
+ apr_xml_parser_done(xp, &doc);
+}
+
+int main(int argc, const char *const * argv)
+{
+ apr_pool_t *pool;
+ apr_status_t rv;
+
+ (void) apr_initialize();
+ apr_pool_create(&pool, NULL);
+ progname = argv[0];
+ if (argc == 1) {
+ rv = test_xml_parser(pool, NULL);
+ }
+ else {
+ if (argc == 2) {
+ rv = test_xml_parser(pool, argv[1]);
+ }
+ else {
+ oops("usage: %s", usage, 0);
+ }
+ }
+ test_billion_laughs(pool);
+ test_CVE_2009_3720_alpha(pool);
+ test_CVE_2009_3720_beta(pool);
+ apr_pool_destroy(pool);
+ apr_terminate();
+ return rv;
+}