aboutsummaryrefslogtreecommitdiffstats
path: root/external/libxml2_android/jni/libxml2/testOOM.c
diff options
context:
space:
mode:
Diffstat (limited to 'external/libxml2_android/jni/libxml2/testOOM.c')
-rw-r--r--external/libxml2_android/jni/libxml2/testOOM.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/external/libxml2_android/jni/libxml2/testOOM.c b/external/libxml2_android/jni/libxml2/testOOM.c
new file mode 100644
index 00000000..9ff13f2f
--- /dev/null
+++ b/external/libxml2_android/jni/libxml2/testOOM.c
@@ -0,0 +1,377 @@
+/*
+ * testOOM.c: Test out-of-memory handling
+ *
+ * See Copyright for the status of this software.
+ *
+ * hp@redhat.com
+ */
+
+#include "libxml.h"
+
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <libxml/xmlreader.h>
+
+#include "testOOMlib.h"
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#define EXIT_OOM 2
+
+int error = FALSE;
+int errcount = 0;
+int noent = 0;
+int count = 0;
+int valid = 0;
+int showErrs = 0;
+
+/*
+ * Since we are using the xmlTextReader functions, we set up
+ * strings for the element types to help in debugging any error
+ * output
+ */
+const char *elementNames[] = {
+ "XML_READER_TYPE_NONE",
+ "XML_READER_TYPE_ELEMENT",
+ "XML_READER_TYPE_ATTRIBUTE",
+ "XML_READER_TYPE_TEXT",
+ "XML_READER_TYPE_CDATA",
+ "XML_READER_TYPE_ENTITY_REFERENCE",
+ "XML_READER_TYPE_ENTITY",
+ "XML_READER_TYPE_PROCESSING_INSTRUCTION",
+ "XML_READER_TYPE_COMMENT",
+ "XML_READER_TYPE_DOCUMENT",
+ "XML_READER_TYPE_DOCUMENT_TYPE",
+ "XML_READER_TYPE_DOCUMENT_FRAGMENT",
+ "XML_READER_TYPE_NOTATION",
+ "XML_READER_TYPE_WHITESPACE",
+ "XML_READER_TYPE_SIGNIFICANT_WHITESPACE",
+ "XML_READER_TYPE_END_ELEMENT",
+ "XML_READER_TYPE_END_ENTITY",
+ "XML_READER_TYPE_XML_DECLARATION"};
+
+/* not using xmlBuff here because I don't want those
+ * mallocs to interfere */
+struct buffer {
+ char *str;
+ size_t len;
+ size_t max;
+};
+
+static struct buffer *buffer_create (size_t init_len)
+{
+ struct buffer *b;
+ b = malloc (sizeof *b);
+ if (b == NULL)
+ exit (EXIT_OOM);
+ if (init_len) {
+ b->str = malloc (init_len);
+ if (b->str == NULL)
+ exit (EXIT_OOM);
+ }
+ else
+ b->str = NULL;
+ b->len = 0;
+ b->max = init_len;
+ return b;
+}
+
+static void buffer_free (struct buffer *b)
+{
+ free (b->str);
+ free (b);
+}
+
+static size_t buffer_get_length (struct buffer *b)
+{
+ return b->len;
+}
+
+static void buffer_expand (struct buffer *b, size_t min)
+{
+ void *new_str;
+ size_t new_size = b->max ? b->max : 512;
+ while (new_size < b->len + min)
+ new_size *= 2;
+ if (new_size > b->max) {
+ new_str = realloc (b->str, new_size);
+ if (new_str == NULL)
+ exit (EXIT_OOM);
+ b->str = new_str;
+ b->max = new_size;
+ }
+}
+
+static void buffer_add_char (struct buffer *b, char c)
+{
+ buffer_expand (b, 1);
+ b->str[b->len] = c;
+ b->len += 1;
+}
+
+static void buffer_add_string (struct buffer *b, const char *s)
+{
+ size_t size = strlen(s) + 1;
+ unsigned int ix;
+ for (ix=0; ix<size-1; ix++) {
+ if (s[ix] < 0x20)
+ printf ("binary data [0x%02x]?\n", (unsigned char)s[ix]);
+ }
+ buffer_expand (b, size);
+ strcpy (b->str + b->len, s);
+ b->str[b->len+size-1] = '\n'; /* replace string term with newline */
+ b->len += size;
+}
+
+static int buffer_equal (struct buffer *b1, struct buffer *b2)
+{
+ return (b1->len == b2->len &&
+ (b1->len == 0 || (memcmp (b1->str, b2->str, b1->len) == 0)));
+}
+
+static void buffer_dump (struct buffer *b, const char *fname)
+{
+ FILE *f = fopen (fname, "wb");
+ if (f != NULL) {
+ fwrite (b->str, 1, b->len, f);
+ fclose (f);
+ }
+}
+
+
+static void usage(const char *progname) {
+ printf("Usage : %s [options] XMLfiles ...\n", progname);
+ printf("\tParse the XML files using the xmlTextReader API\n");
+ printf("\t --count: count the number of attribute and elements\n");
+ printf("\t --valid: validate the document\n");
+ printf("\t --show: display the error messages encountered\n");
+ exit(1);
+}
+static unsigned int elem, attrs, chars;
+
+static int processNode (xmlTextReaderPtr reader, void *data)
+{
+ struct buffer *buff = data;
+ int type;
+
+ type = xmlTextReaderNodeType(reader);
+ if (count) {
+ if (type == 1) {
+ elem++;
+ attrs += xmlTextReaderAttributeCount(reader);
+ } else if (type == 3) {
+ const xmlChar *txt;
+ txt = xmlTextReaderConstValue(reader);
+ if (txt != NULL)
+ chars += xmlStrlen (txt);
+ else
+ return FALSE;
+ }
+ }
+
+ if (buff != NULL) {
+ int ret;
+ const char *s;
+
+ buffer_add_string (buff, elementNames[type]);
+
+ if (type == 1) {
+ s = (const char *)xmlTextReaderConstName (reader);
+ if (s == NULL) return FALSE;
+ buffer_add_string (buff, s);
+ while ((ret = xmlTextReaderMoveToNextAttribute (reader)) == 1) {
+ s = (const char *)xmlTextReaderConstName (reader);
+ if (s == NULL) return FALSE;
+ buffer_add_string (buff, s);
+ buffer_add_char (buff, '=');
+ s = (const char *)xmlTextReaderConstValue (reader);
+ if (s == NULL) return FALSE;
+ buffer_add_string (buff, s);
+ }
+ if (ret == -1) return FALSE;
+ }
+ else if (type == 3) {
+ s = (const char *)xmlTextReaderConstValue (reader);
+ if (s == NULL) return FALSE;
+ buffer_add_string (buff, s);
+ }
+ }
+
+ return TRUE;
+}
+
+
+struct file_params {
+ const char *filename;
+ struct buffer *verif_buff;
+};
+
+static void
+error_func (void *data ATTRIBUTE_UNUSED, xmlErrorPtr err)
+{
+
+ errcount++;
+ if (err->level == XML_ERR_ERROR ||
+ err->level == XML_ERR_FATAL)
+ error = TRUE;
+ if (showErrs) {
+ printf("%3d line %d: %s\n", error, err->line, err->message);
+ }
+}
+
+static int
+check_load_file_memory_func (void *data)
+{
+ struct file_params *p = data;
+ struct buffer *b;
+ xmlTextReaderPtr reader;
+ int ret, status, first_run;
+
+ if (count) {
+ elem = 0;
+ attrs = 0;
+ chars = 0;
+ }
+
+ first_run = p->verif_buff == NULL;
+ status = TRUE;
+ error = FALSE;
+ if (first_run)
+ b = buffer_create (0);
+ else
+ b = buffer_create (buffer_get_length (p->verif_buff));
+
+ reader = xmlNewTextReaderFilename (p->filename);
+ if (reader == NULL)
+ goto out;
+
+ xmlTextReaderSetStructuredErrorHandler (reader, error_func, NULL);
+ xmlSetStructuredErrorFunc(NULL, error_func);
+
+ if (valid) {
+ if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1)
+ goto out;
+ }
+
+ /*
+ * Process all nodes in sequence
+ */
+ while ((ret = xmlTextReaderRead(reader)) == 1) {
+ if (!processNode(reader, b))
+ goto out;
+ }
+ if (ret == -1)
+ goto out;
+
+ if (error) {
+ fprintf (stdout, "error handler was called but parse completed successfully (last error #%d)\n", errcount);
+ return FALSE;
+ }
+
+ /*
+ * Done, cleanup and status
+ */
+ if (! first_run) {
+ status = buffer_equal (p->verif_buff, b);
+ if (! status) {
+ buffer_dump (p->verif_buff, ".OOM.verif_buff");
+ buffer_dump (b, ".OOM.buff");
+ }
+ }
+
+ if (count)
+ {
+ fprintf (stdout, "# %s: %u elems, %u attrs, %u chars %s\n",
+ p->filename, elem, attrs, chars,
+ status ? "ok" : "wrong");
+ }
+
+ out:
+ if (first_run)
+ p->verif_buff = b;
+ else
+ buffer_free (b);
+ if (reader)
+ xmlFreeTextReader (reader);
+ return status;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ int files = 0;
+
+ if (argc <= 1) {
+ usage(argv[0]);
+ return(1);
+ }
+ LIBXML_TEST_VERSION;
+
+ xmlMemSetup (test_free,
+ test_malloc,
+ test_realloc,
+ test_strdup);
+
+ xmlInitParser();
+
+ for (i = 1; i < argc ; i++) {
+ if ((!strcmp(argv[i], "-count")) || (!strcmp(argv[i], "--count")))
+ count++;
+ else if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
+ valid++;
+ else if ((!strcmp(argv[i], "-noent")) ||
+ (!strcmp(argv[i], "--noent")))
+ noent++;
+ else if ((!strcmp(argv[i], "-show")) ||
+ (!strcmp(argv[i], "--show")))
+ showErrs++;
+ }
+ if (noent != 0)
+ xmlSubstituteEntitiesDefault(1);
+ for (i = 1; i < argc ; i++) {
+ if (argv[i][0] != '-') {
+ struct file_params p;
+ p.filename = argv[i];
+ p.verif_buff = NULL;
+
+ if (!test_oom_handling (check_load_file_memory_func,
+ &p)) {
+ fprintf (stdout, "Failed!\n");
+ return 1;
+ }
+
+ buffer_free (p.verif_buff);
+ xmlCleanupParser();
+
+ if (test_get_malloc_blocks_outstanding () > 0) {
+ fprintf (stdout, "%d blocks leaked\n",
+ test_get_malloc_blocks_outstanding ());
+ xmlMemoryDump();
+ return 1;
+ }
+
+ files ++;
+ }
+ }
+ xmlMemoryDump();
+
+ return 0;
+}