7f1b072c2b
git-svn-id: svn://svn.openwrt.org/openwrt/packages@33578 3c298f89-4303-0410-b956-a3cf2f4a3e73
1029 lines
30 KiB
Diff
1029 lines
30 KiB
Diff
--- libxml2-2.7.8/dict.c 2010-10-12 08:25:31.000000000 +0200
|
|
+++ libxml2-2.7.8.patched/dict.c 2012-09-28 12:08:37.432414664 +0200
|
|
@@ -2,7 +2,7 @@
|
|
* dict.c: dictionary of reusable strings, just used to avoid allocation
|
|
* and freeing operations.
|
|
*
|
|
- * Copyright (C) 2003 Daniel Veillard.
|
|
+ * Copyright (C) 2003-2012 Daniel Veillard.
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
@@ -19,6 +19,28 @@
|
|
#define IN_LIBXML
|
|
#include "libxml.h"
|
|
|
|
+#ifdef HAVE_STDLIB_H
|
|
+#include <stdlib.h>
|
|
+#endif
|
|
+#ifdef HAVE_TIME_H
|
|
+#include <time.h>
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Following http://www.ocert.org/advisories/ocert-2011-003.html
|
|
+ * it seems that having hash randomization might be a good idea
|
|
+ * when using XML with untrusted data
|
|
+ * Note1: that it works correctly only if compiled with WITH_BIG_KEY
|
|
+ * which is the default.
|
|
+ * Note2: the fast function used for a small dict won't protect very
|
|
+ * well but since the attack is based on growing a very big hash
|
|
+ * list we will use the BigKey algo as soon as the hash size grows
|
|
+ * over MIN_DICT_SIZE so this actually works
|
|
+ */
|
|
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
|
|
+#define DICT_RANDOMIZATION
|
|
+#endif
|
|
+
|
|
#include <string.h>
|
|
#ifdef HAVE_STDINT_H
|
|
#include <stdint.h>
|
|
@@ -44,23 +66,23 @@
|
|
#define WITH_BIG_KEY
|
|
|
|
#ifdef WITH_BIG_KEY
|
|
-#define xmlDictComputeKey(dict, name, len) \
|
|
- (((dict)->size == MIN_DICT_SIZE) ? \
|
|
- xmlDictComputeFastKey(name, len) : \
|
|
- xmlDictComputeBigKey(name, len))
|
|
-
|
|
-#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
|
|
- (((prefix) == NULL) ? \
|
|
- (xmlDictComputeKey(dict, name, len)) : \
|
|
- (((dict)->size == MIN_DICT_SIZE) ? \
|
|
- xmlDictComputeFastQKey(prefix, plen, name, len) : \
|
|
- xmlDictComputeBigQKey(prefix, plen, name, len)))
|
|
+#define xmlDictComputeKey(dict, name, len) \
|
|
+ (((dict)->size == MIN_DICT_SIZE) ? \
|
|
+ xmlDictComputeFastKey(name, len, (dict)->seed) : \
|
|
+ xmlDictComputeBigKey(name, len, (dict)->seed))
|
|
+
|
|
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
|
|
+ (((prefix) == NULL) ? \
|
|
+ (xmlDictComputeKey(dict, name, len)) : \
|
|
+ (((dict)->size == MIN_DICT_SIZE) ? \
|
|
+ xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) : \
|
|
+ xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
|
|
|
|
#else /* !WITH_BIG_KEY */
|
|
-#define xmlDictComputeKey(dict, name, len) \
|
|
- xmlDictComputeFastKey(name, len)
|
|
-#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
|
|
- xmlDictComputeFastQKey(prefix, plen, name, len)
|
|
+#define xmlDictComputeKey(dict, name, len) \
|
|
+ xmlDictComputeFastKey(name, len, (dict)->seed)
|
|
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
|
|
+ xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
|
|
#endif /* WITH_BIG_KEY */
|
|
|
|
/*
|
|
@@ -98,6 +120,8 @@
|
|
xmlDictStringsPtr strings;
|
|
|
|
struct _xmlDict *subdict;
|
|
+ /* used for randomization */
|
|
+ int seed;
|
|
};
|
|
|
|
/*
|
|
@@ -125,6 +149,9 @@
|
|
if ((xmlDictMutex = xmlNewRMutex()) == NULL)
|
|
return(0);
|
|
|
|
+#ifdef DICT_RANDOMIZATION
|
|
+ srand(time(NULL));
|
|
+#endif
|
|
xmlDictInitialized = 1;
|
|
return(1);
|
|
}
|
|
@@ -277,13 +304,13 @@
|
|
*/
|
|
|
|
static uint32_t
|
|
-xmlDictComputeBigKey(const xmlChar* data, int namelen) {
|
|
+xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
|
|
uint32_t hash;
|
|
int i;
|
|
|
|
if (namelen <= 0 || data == NULL) return(0);
|
|
|
|
- hash = 0;
|
|
+ hash = seed;
|
|
|
|
for (i = 0;i < namelen; i++) {
|
|
hash += data[i];
|
|
@@ -310,12 +337,12 @@
|
|
*/
|
|
static unsigned long
|
|
xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
|
|
- const xmlChar *name, int len)
|
|
+ const xmlChar *name, int len, int seed)
|
|
{
|
|
uint32_t hash;
|
|
int i;
|
|
|
|
- hash = 0;
|
|
+ hash = seed;
|
|
|
|
for (i = 0;i < plen; i++) {
|
|
hash += prefix[i];
|
|
@@ -346,8 +373,8 @@
|
|
* for low hash table fill.
|
|
*/
|
|
static unsigned long
|
|
-xmlDictComputeFastKey(const xmlChar *name, int namelen) {
|
|
- unsigned long value = 0L;
|
|
+xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
|
|
+ unsigned long value = seed;
|
|
|
|
if (name == NULL) return(0);
|
|
value = *name;
|
|
@@ -381,9 +408,9 @@
|
|
*/
|
|
static unsigned long
|
|
xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
|
|
- const xmlChar *name, int len)
|
|
+ const xmlChar *name, int len, int seed)
|
|
{
|
|
- unsigned long value = 0L;
|
|
+ unsigned long value = (unsigned long) seed;
|
|
|
|
if (plen == 0)
|
|
value += 30 * (unsigned long) ':';
|
|
@@ -460,6 +487,11 @@
|
|
dict->subdict = NULL;
|
|
if (dict->dict) {
|
|
memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
|
|
+#ifdef DICT_RANDOMIZATION
|
|
+ dict->seed = rand();
|
|
+#else
|
|
+ dict->seed = 0;
|
|
+#endif
|
|
return(dict);
|
|
}
|
|
xmlFree(dict);
|
|
@@ -486,6 +518,7 @@
|
|
#ifdef DICT_DEBUG_PATTERNS
|
|
fprintf(stderr, "R");
|
|
#endif
|
|
+ dict->seed = sub->seed;
|
|
dict->subdict = sub;
|
|
xmlDictReference(dict->subdict);
|
|
}
|
|
--- libxml2-2.7.8/encoding.c 2010-11-04 17:40:06.000000000 +0100
|
|
+++ libxml2-2.7.8.patched/encoding.c 2012-09-28 12:08:37.440414665 +0200
|
|
@@ -1928,7 +1928,7 @@
|
|
if (in == NULL) return(-1);
|
|
|
|
/* calculate space available */
|
|
- written = out->size - out->use;
|
|
+ written = out->size - out->use - 1; /* count '\0' */
|
|
toconv = in->use;
|
|
/*
|
|
* echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
|
|
@@ -2059,7 +2059,7 @@
|
|
toconv = in->use;
|
|
if (toconv == 0)
|
|
return (0);
|
|
- written = out->size - out->use;
|
|
+ written = out->size - out->use - 1; /* count '\0' */
|
|
if (toconv * 2 >= written) {
|
|
xmlBufferGrow(out, out->size + toconv * 2);
|
|
written = out->size - out->use - 1;
|
|
--- libxml2-2.7.8/entities.c 2010-10-12 08:25:32.000000000 +0200
|
|
+++ libxml2-2.7.8.patched/entities.c 2012-09-28 12:08:37.432414664 +0200
|
|
@@ -528,13 +528,13 @@
|
|
* Macro used to grow the current buffer.
|
|
*/
|
|
#define growBufferReentrant() { \
|
|
- buffer_size *= 2; \
|
|
- buffer = (xmlChar *) \
|
|
- xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
|
|
- if (buffer == NULL) { \
|
|
- xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");\
|
|
- return(NULL); \
|
|
- } \
|
|
+ xmlChar *tmp; \
|
|
+ size_t new_size = buffer_size * 2; \
|
|
+ if (new_size < buffer_size) goto mem_error; \
|
|
+ tmp = (xmlChar *) xmlRealloc(buffer, new_size); \
|
|
+ if (tmp == NULL) goto mem_error; \
|
|
+ buffer = tmp; \
|
|
+ buffer_size = new_size; \
|
|
}
|
|
|
|
|
|
@@ -555,7 +555,7 @@
|
|
const xmlChar *cur = input;
|
|
xmlChar *buffer = NULL;
|
|
xmlChar *out = NULL;
|
|
- int buffer_size = 0;
|
|
+ size_t buffer_size = 0;
|
|
int html = 0;
|
|
|
|
if (input == NULL) return(NULL);
|
|
@@ -574,8 +574,8 @@
|
|
out = buffer;
|
|
|
|
while (*cur != '\0') {
|
|
- if (out - buffer > buffer_size - 100) {
|
|
- int indx = out - buffer;
|
|
+ size_t indx = out - buffer;
|
|
+ if (indx + 100 > buffer_size) {
|
|
|
|
growBufferReentrant();
|
|
out = &buffer[indx];
|
|
@@ -692,6 +692,11 @@
|
|
}
|
|
*out = 0;
|
|
return(buffer);
|
|
+
|
|
+mem_error:
|
|
+ xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");
|
|
+ xmlFree(buffer);
|
|
+ return(NULL);
|
|
}
|
|
|
|
/**
|
|
@@ -709,7 +714,7 @@
|
|
const xmlChar *cur = input;
|
|
xmlChar *buffer = NULL;
|
|
xmlChar *out = NULL;
|
|
- int buffer_size = 0;
|
|
+ size_t buffer_size = 0;
|
|
if (input == NULL) return(NULL);
|
|
|
|
/*
|
|
@@ -724,8 +729,8 @@
|
|
out = buffer;
|
|
|
|
while (*cur != '\0') {
|
|
- if (out - buffer > buffer_size - 10) {
|
|
- int indx = out - buffer;
|
|
+ size_t indx = out - buffer;
|
|
+ if (indx + 10 > buffer_size) {
|
|
|
|
growBufferReentrant();
|
|
out = &buffer[indx];
|
|
@@ -774,6 +779,11 @@
|
|
}
|
|
*out = 0;
|
|
return(buffer);
|
|
+
|
|
+mem_error:
|
|
+ xmlEntitiesErrMemory("xmlEncodeSpecialChars: realloc failed");
|
|
+ xmlFree(buffer);
|
|
+ return(NULL);
|
|
}
|
|
|
|
/**
|
|
--- libxml2-2.7.8/hash.c 2010-10-12 08:25:32.000000000 +0200
|
|
+++ libxml2-2.7.8.patched/hash.c 2012-09-28 12:08:37.392414663 +0200
|
|
@@ -3,7 +3,7 @@
|
|
*
|
|
* Reference: Your favorite introductory book on algorithms
|
|
*
|
|
- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
|
|
+ * Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard.
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
@@ -21,6 +21,22 @@
|
|
#include "libxml.h"
|
|
|
|
#include <string.h>
|
|
+#ifdef HAVE_STDLIB_H
|
|
+#include <stdlib.h>
|
|
+#endif
|
|
+#ifdef HAVE_TIME_H
|
|
+#include <time.h>
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Following http://www.ocert.org/advisories/ocert-2011-003.html
|
|
+ * it seems that having hash randomization might be a good idea
|
|
+ * when using XML with untrusted data
|
|
+ */
|
|
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
|
|
+#define HASH_RANDOMIZATION
|
|
+#endif
|
|
+
|
|
#include <libxml/parser.h>
|
|
#include <libxml/hash.h>
|
|
#include <libxml/xmlmemory.h>
|
|
@@ -31,6 +47,10 @@
|
|
|
|
/* #define DEBUG_GROW */
|
|
|
|
+#ifdef HASH_RANDOMIZATION
|
|
+static int hash_initialized = 0;
|
|
+#endif
|
|
+
|
|
/*
|
|
* A single entry in the hash table
|
|
*/
|
|
@@ -53,6 +73,9 @@
|
|
int size;
|
|
int nbElems;
|
|
xmlDictPtr dict;
|
|
+#ifdef HASH_RANDOMIZATION
|
|
+ int random_seed;
|
|
+#endif
|
|
};
|
|
|
|
/*
|
|
@@ -65,6 +88,9 @@
|
|
unsigned long value = 0L;
|
|
char ch;
|
|
|
|
+#ifdef HASH_RANDOMIZATION
|
|
+ value = table->random_seed;
|
|
+#endif
|
|
if (name != NULL) {
|
|
value += 30 * (*name);
|
|
while ((ch = *name++) != 0) {
|
|
@@ -92,6 +118,9 @@
|
|
unsigned long value = 0L;
|
|
char ch;
|
|
|
|
+#ifdef HASH_RANDOMIZATION
|
|
+ value = table->random_seed;
|
|
+#endif
|
|
if (prefix != NULL)
|
|
value += 30 * (*prefix);
|
|
else
|
|
@@ -156,6 +185,13 @@
|
|
table->table = xmlMalloc(size * sizeof(xmlHashEntry));
|
|
if (table->table) {
|
|
memset(table->table, 0, size * sizeof(xmlHashEntry));
|
|
+#ifdef HASH_RANDOMIZATION
|
|
+ if (!hash_initialized) {
|
|
+ srand(time(NULL));
|
|
+ hash_initialized = 1;
|
|
+ }
|
|
+ table->random_seed = rand();
|
|
+#endif
|
|
return(table);
|
|
}
|
|
xmlFree(table);
|
|
--- libxml2-2.7.8/parser.c 2010-11-04 16:55:45.000000000 +0100
|
|
+++ libxml2-2.7.8.patched/parser.c 2012-09-28 12:08:37.440414665 +0200
|
|
@@ -40,6 +40,7 @@
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
+#include <limits.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <libxml/xmlmemory.h>
|
|
@@ -114,10 +115,10 @@
|
|
* parser option.
|
|
*/
|
|
static int
|
|
-xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
|
|
+xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
|
|
xmlEntityPtr ent)
|
|
{
|
|
- unsigned long consumed = 0;
|
|
+ size_t consumed = 0;
|
|
|
|
if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
|
|
return (0);
|
|
@@ -2580,15 +2581,17 @@
|
|
|
|
/*
|
|
* Macro used to grow the current buffer.
|
|
+ * buffer##_size is expected to be a size_t
|
|
+ * mem_error: is expected to handle memory allocation failures
|
|
*/
|
|
#define growBuffer(buffer, n) { \
|
|
xmlChar *tmp; \
|
|
- buffer##_size *= 2; \
|
|
- buffer##_size += n; \
|
|
- tmp = (xmlChar *) \
|
|
- xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
|
|
+ size_t new_size = buffer##_size * 2 + n; \
|
|
+ if (new_size < buffer##_size) goto mem_error; \
|
|
+ tmp = (xmlChar *) xmlRealloc(buffer, new_size); \
|
|
if (tmp == NULL) goto mem_error; \
|
|
buffer = tmp; \
|
|
+ buffer##_size = new_size; \
|
|
}
|
|
|
|
/**
|
|
@@ -2614,14 +2617,14 @@
|
|
xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
|
|
int what, xmlChar end, xmlChar end2, xmlChar end3) {
|
|
xmlChar *buffer = NULL;
|
|
- int buffer_size = 0;
|
|
+ size_t buffer_size = 0;
|
|
+ size_t nbchars = 0;
|
|
|
|
xmlChar *current = NULL;
|
|
xmlChar *rep = NULL;
|
|
const xmlChar *last;
|
|
xmlEntityPtr ent;
|
|
int c,l;
|
|
- int nbchars = 0;
|
|
|
|
if ((ctxt == NULL) || (str == NULL) || (len < 0))
|
|
return(NULL);
|
|
@@ -2638,7 +2641,7 @@
|
|
* allocate a translation buffer.
|
|
*/
|
|
buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
|
|
- buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
|
|
+ buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
|
|
if (buffer == NULL) goto mem_error;
|
|
|
|
/*
|
|
@@ -2658,7 +2661,7 @@
|
|
if (val != 0) {
|
|
COPY_BUF(0,buffer,nbchars,val);
|
|
}
|
|
- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
|
|
+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
|
|
growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
|
|
}
|
|
} else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
|
|
@@ -2676,7 +2679,7 @@
|
|
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
|
|
if (ent->content != NULL) {
|
|
COPY_BUF(0,buffer,nbchars,ent->content[0]);
|
|
- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
|
|
+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
|
|
growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
|
|
}
|
|
} else {
|
|
@@ -2693,8 +2696,7 @@
|
|
current = rep;
|
|
while (*current != 0) { /* non input consuming loop */
|
|
buffer[nbchars++] = *current++;
|
|
- if (nbchars >
|
|
- buffer_size - XML_PARSER_BUFFER_SIZE) {
|
|
+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
|
|
if (xmlParserEntityCheck(ctxt, nbchars, ent))
|
|
goto int_error;
|
|
growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
|
|
@@ -2708,8 +2710,8 @@
|
|
const xmlChar *cur = ent->name;
|
|
|
|
buffer[nbchars++] = '&';
|
|
- if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
|
|
- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
|
|
+ if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
|
|
+ growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
|
|
}
|
|
for (;i > 0;i--)
|
|
buffer[nbchars++] = *cur++;
|
|
@@ -2736,8 +2738,7 @@
|
|
current = rep;
|
|
while (*current != 0) { /* non input consuming loop */
|
|
buffer[nbchars++] = *current++;
|
|
- if (nbchars >
|
|
- buffer_size - XML_PARSER_BUFFER_SIZE) {
|
|
+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
|
|
if (xmlParserEntityCheck(ctxt, nbchars, ent))
|
|
goto int_error;
|
|
growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
|
|
@@ -2750,8 +2751,8 @@
|
|
} else {
|
|
COPY_BUF(l,buffer,nbchars,c);
|
|
str += l;
|
|
- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
|
|
- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
|
|
+ if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
|
|
+ growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
|
|
}
|
|
}
|
|
if (str < last)
|
|
@@ -3755,8 +3756,8 @@
|
|
xmlChar limit = 0;
|
|
xmlChar *buf = NULL;
|
|
xmlChar *rep = NULL;
|
|
- int len = 0;
|
|
- int buf_size = 0;
|
|
+ size_t len = 0;
|
|
+ size_t buf_size = 0;
|
|
int c, l, in_space = 0;
|
|
xmlChar *current = NULL;
|
|
xmlEntityPtr ent;
|
|
@@ -3778,7 +3779,7 @@
|
|
* allocate a translation buffer.
|
|
*/
|
|
buf_size = XML_PARSER_BUFFER_SIZE;
|
|
- buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
|
|
+ buf = (xmlChar *) xmlMallocAtomic(buf_size);
|
|
if (buf == NULL) goto mem_error;
|
|
|
|
/*
|
|
@@ -3795,7 +3796,7 @@
|
|
|
|
if (val == '&') {
|
|
if (ctxt->replaceEntities) {
|
|
- if (len > buf_size - 10) {
|
|
+ if (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
buf[len++] = '&';
|
|
@@ -3804,7 +3805,7 @@
|
|
* The reparsing will be done in xmlStringGetNodeList()
|
|
* called by the attribute() function in SAX.c
|
|
*/
|
|
- if (len > buf_size - 10) {
|
|
+ if (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
buf[len++] = '&';
|
|
@@ -3814,7 +3815,7 @@
|
|
buf[len++] = ';';
|
|
}
|
|
} else if (val != 0) {
|
|
- if (len > buf_size - 10) {
|
|
+ if (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
len += xmlCopyChar(0, &buf[len], val);
|
|
@@ -3826,7 +3827,7 @@
|
|
ctxt->nbentities += ent->owner;
|
|
if ((ent != NULL) &&
|
|
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
|
|
- if (len > buf_size - 10) {
|
|
+ if (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
if ((ctxt->replaceEntities == 0) &&
|
|
@@ -3854,7 +3855,7 @@
|
|
current++;
|
|
} else
|
|
buf[len++] = *current++;
|
|
- if (len > buf_size - 10) {
|
|
+ if (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
}
|
|
@@ -3862,7 +3863,7 @@
|
|
rep = NULL;
|
|
}
|
|
} else {
|
|
- if (len > buf_size - 10) {
|
|
+ if (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
if (ent->content != NULL)
|
|
@@ -3890,7 +3891,7 @@
|
|
* Just output the reference
|
|
*/
|
|
buf[len++] = '&';
|
|
- while (len > buf_size - i - 10) {
|
|
+ while (len + i + 10 > buf_size) {
|
|
growBuffer(buf, i + 10);
|
|
}
|
|
for (;i > 0;i--)
|
|
@@ -3903,7 +3904,7 @@
|
|
if ((len != 0) || (!normalize)) {
|
|
if ((!normalize) || (!in_space)) {
|
|
COPY_BUF(l,buf,len,0x20);
|
|
- while (len > buf_size - 10) {
|
|
+ while (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
}
|
|
@@ -3912,7 +3913,7 @@
|
|
} else {
|
|
in_space = 0;
|
|
COPY_BUF(l,buf,len,c);
|
|
- if (len > buf_size - 10) {
|
|
+ if (len + 10 > buf_size) {
|
|
growBuffer(buf, 10);
|
|
}
|
|
}
|
|
@@ -3937,7 +3938,18 @@
|
|
}
|
|
} else
|
|
NEXT;
|
|
- if (attlen != NULL) *attlen = len;
|
|
+
|
|
+ /*
|
|
+ * There we potentially risk an overflow, don't allow attribute value of
|
|
+ * lenght more than INT_MAX it is a very reasonnable assumption !
|
|
+ */
|
|
+ if (len >= INT_MAX) {
|
|
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
|
+ "AttValue lenght too long\n");
|
|
+ goto mem_error;
|
|
+ }
|
|
+
|
|
+ if (attlen != NULL) *attlen = (int) len;
|
|
return(buf);
|
|
|
|
mem_error:
|
|
@@ -4949,7 +4961,8 @@
|
|
(ctxt->sax->processingInstruction != NULL))
|
|
ctxt->sax->processingInstruction(ctxt->userData,
|
|
target, NULL);
|
|
- ctxt->instate = state;
|
|
+ if (ctxt->instate != XML_PARSER_EOF)
|
|
+ ctxt->instate = state;
|
|
return;
|
|
}
|
|
buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
|
|
@@ -5029,7 +5042,8 @@
|
|
} else {
|
|
xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
|
|
}
|
|
- ctxt->instate = state;
|
|
+ if (ctxt->instate != XML_PARSER_EOF)
|
|
+ ctxt->instate = state;
|
|
}
|
|
}
|
|
|
|
@@ -9588,6 +9602,8 @@
|
|
else
|
|
name = xmlParseStartTag(ctxt);
|
|
#endif /* LIBXML_SAX1_ENABLED */
|
|
+ if (ctxt->instate == XML_PARSER_EOF)
|
|
+ return;
|
|
if (name == NULL) {
|
|
spacePop(ctxt);
|
|
return;
|
|
@@ -10967,6 +10983,8 @@
|
|
else
|
|
name = xmlParseStartTag(ctxt);
|
|
#endif /* LIBXML_SAX1_ENABLED */
|
|
+ if (ctxt->instate == XML_PARSER_EOF)
|
|
+ goto done;
|
|
if (name == NULL) {
|
|
spacePop(ctxt);
|
|
ctxt->instate = XML_PARSER_EOF;
|
|
@@ -11153,7 +11171,9 @@
|
|
else
|
|
xmlParseEndTag1(ctxt, 0);
|
|
#endif /* LIBXML_SAX1_ENABLED */
|
|
- if (ctxt->nameNr == 0) {
|
|
+ if (ctxt->instate == XML_PARSER_EOF) {
|
|
+ /* Nothing */
|
|
+ } else if (ctxt->nameNr == 0) {
|
|
ctxt->instate = XML_PARSER_EPILOG;
|
|
} else {
|
|
ctxt->instate = XML_PARSER_CONTENT;
|
|
--- libxml2-2.7.8/xmllint.c 2010-11-03 15:49:11.000000000 +0100
|
|
+++ libxml2-2.7.8.patched/xmllint.c 2012-09-28 12:08:37.436414665 +0200
|
|
@@ -2976,7 +2976,7 @@
|
|
printf("\t--huge : remove any internal arbitrary parser limits\n");
|
|
printf("\t--noent : substitute entity references by their value\n");
|
|
printf("\t--noout : don't output the result tree\n");
|
|
- printf("\t--path 'paths': provide a set of paths for resources\n");
|
|
+ printf("\t--path 'paths' : provide a set of paths for resources\n");
|
|
printf("\t--load-trace : print trace of all external entites loaded\n");
|
|
printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
|
|
printf("\t--nocompact : do not generate compact text nodes\n");
|
|
@@ -3032,7 +3032,7 @@
|
|
printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
|
|
printf("\t otherwise XML Catalogs starting from \n");
|
|
printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
|
|
- printf("\t--nocatalogs: deactivate all catalogs\n");
|
|
+ printf("\t--nocatalogs : deactivate all catalogs\n");
|
|
#endif
|
|
printf("\t--auto : generate a small doc on the fly\n");
|
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
|
--- libxml2-2.7.8/xpath.c 2010-11-03 20:18:27.000000000 +0100
|
|
+++ libxml2-2.7.8.patched/xpath.c 2012-09-28 12:08:37.444414664 +0200
|
|
@@ -252,6 +252,7 @@
|
|
"Encoding error\n",
|
|
"Char out of XML range\n",
|
|
"Invalid or incomplete context\n",
|
|
+ "Stack usage errror\n",
|
|
"?? Unknown error ??\n" /* Must be last in the list! */
|
|
};
|
|
#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \
|
|
@@ -2398,6 +2399,42 @@
|
|
************************************************************************/
|
|
|
|
/**
|
|
+ * xmlXPathSetFrame:
|
|
+ * @ctxt: an XPath parser context
|
|
+ *
|
|
+ * Set the callee evaluation frame
|
|
+ *
|
|
+ * Returns the previous frame value to be restored once done
|
|
+ */
|
|
+static int
|
|
+xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
|
|
+ int ret;
|
|
+
|
|
+ if (ctxt == NULL)
|
|
+ return(0);
|
|
+ ret = ctxt->valueFrame;
|
|
+ ctxt->valueFrame = ctxt->valueNr;
|
|
+ return(ret);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * xmlXPathPopFrame:
|
|
+ * @ctxt: an XPath parser context
|
|
+ * @frame: the previous frame value
|
|
+ *
|
|
+ * Remove the callee evaluation frame
|
|
+ */
|
|
+static void
|
|
+xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) {
|
|
+ if (ctxt == NULL)
|
|
+ return;
|
|
+ if (ctxt->valueNr < ctxt->valueFrame) {
|
|
+ xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
|
|
+ }
|
|
+ ctxt->valueFrame = frame;
|
|
+}
|
|
+
|
|
+/**
|
|
* valuePop:
|
|
* @ctxt: an XPath evaluation context
|
|
*
|
|
@@ -2412,6 +2449,12 @@
|
|
|
|
if ((ctxt == NULL) || (ctxt->valueNr <= 0))
|
|
return (NULL);
|
|
+
|
|
+ if (ctxt->valueNr <= ctxt->valueFrame) {
|
|
+ xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
|
|
+ return (NULL);
|
|
+ }
|
|
+
|
|
ctxt->valueNr--;
|
|
if (ctxt->valueNr > 0)
|
|
ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
|
|
@@ -3522,13 +3565,13 @@
|
|
} else if (cur->nodeNr == cur->nodeMax) {
|
|
xmlNodePtr *temp;
|
|
|
|
- cur->nodeMax *= 2;
|
|
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
|
|
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
|
|
sizeof(xmlNodePtr));
|
|
if (temp == NULL) {
|
|
xmlXPathErrMemory(NULL, "growing nodeset\n");
|
|
return;
|
|
}
|
|
+ cur->nodeMax *= 2;
|
|
cur->nodeTab = temp;
|
|
}
|
|
cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
|
|
@@ -3627,14 +3670,14 @@
|
|
} else if (cur->nodeNr == cur->nodeMax) {
|
|
xmlNodePtr *temp;
|
|
|
|
- cur->nodeMax *= 2;
|
|
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
|
|
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
|
|
sizeof(xmlNodePtr));
|
|
if (temp == NULL) {
|
|
xmlXPathErrMemory(NULL, "growing nodeset\n");
|
|
return;
|
|
}
|
|
cur->nodeTab = temp;
|
|
+ cur->nodeMax *= 2;
|
|
}
|
|
if (val->type == XML_NAMESPACE_DECL) {
|
|
xmlNsPtr ns = (xmlNsPtr) val;
|
|
@@ -3738,14 +3781,14 @@
|
|
} else if (val1->nodeNr == val1->nodeMax) {
|
|
xmlNodePtr *temp;
|
|
|
|
- val1->nodeMax *= 2;
|
|
- temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
|
|
+ temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
|
|
sizeof(xmlNodePtr));
|
|
if (temp == NULL) {
|
|
xmlXPathErrMemory(NULL, "merging nodeset\n");
|
|
return(NULL);
|
|
}
|
|
val1->nodeTab = temp;
|
|
+ val1->nodeMax *= 2;
|
|
}
|
|
if (n2->type == XML_NAMESPACE_DECL) {
|
|
xmlNsPtr ns = (xmlNsPtr) n2;
|
|
@@ -3907,14 +3950,14 @@
|
|
} else if (set1->nodeNr >= set1->nodeMax) {
|
|
xmlNodePtr *temp;
|
|
|
|
- set1->nodeMax *= 2;
|
|
temp = (xmlNodePtr *) xmlRealloc(
|
|
- set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
|
|
+ set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
|
|
if (temp == NULL) {
|
|
xmlXPathErrMemory(NULL, "merging nodeset\n");
|
|
return(NULL);
|
|
}
|
|
set1->nodeTab = temp;
|
|
+ set1->nodeMax *= 2;
|
|
}
|
|
if (n2->type == XML_NAMESPACE_DECL) {
|
|
xmlNsPtr ns = (xmlNsPtr) n2;
|
|
@@ -3991,14 +4034,14 @@
|
|
} else if (set1->nodeNr >= set1->nodeMax) {
|
|
xmlNodePtr *temp;
|
|
|
|
- set1->nodeMax *= 2;
|
|
temp = (xmlNodePtr *) xmlRealloc(
|
|
- set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
|
|
+ set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
|
|
if (temp == NULL) {
|
|
xmlXPathErrMemory(NULL, "merging nodeset\n");
|
|
return(NULL);
|
|
}
|
|
set1->nodeTab = temp;
|
|
+ set1->nodeMax *= 2;
|
|
}
|
|
set1->nodeTab[set1->nodeNr++] = n2;
|
|
}
|
|
@@ -6154,6 +6197,7 @@
|
|
ret->valueNr = 0;
|
|
ret->valueMax = 10;
|
|
ret->value = NULL;
|
|
+ ret->valueFrame = 0;
|
|
|
|
ret->context = ctxt;
|
|
ret->comp = comp;
|
|
@@ -11712,6 +11756,7 @@
|
|
xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
|
|
xmlNodePtr oldContextNode, contextNode = NULL;
|
|
xmlXPathContextPtr xpctxt = ctxt->context;
|
|
+ int frame;
|
|
|
|
#ifdef LIBXML_XPTR_ENABLED
|
|
/*
|
|
@@ -11731,6 +11776,8 @@
|
|
*/
|
|
exprOp = &ctxt->comp->steps[op->ch2];
|
|
for (i = 0; i < set->nodeNr; i++) {
|
|
+ xmlXPathObjectPtr tmp;
|
|
+
|
|
if (set->nodeTab[i] == NULL)
|
|
continue;
|
|
|
|
@@ -11758,18 +11805,25 @@
|
|
xmlXPathNodeSetAddUnique(contextObj->nodesetval,
|
|
contextNode);
|
|
|
|
+ frame = xmlXPathSetFrame(ctxt);
|
|
valuePush(ctxt, contextObj);
|
|
res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
|
|
+ tmp = valuePop(ctxt);
|
|
+ xmlXPathPopFrame(ctxt, frame);
|
|
|
|
if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
|
|
- xmlXPathObjectPtr tmp;
|
|
- /* pop the result */
|
|
- tmp = valuePop(ctxt);
|
|
- xmlXPathReleaseObject(xpctxt, tmp);
|
|
- /* then pop off contextObj, which will be freed later */
|
|
- valuePop(ctxt);
|
|
+ while (tmp != contextObj) {
|
|
+ /*
|
|
+ * Free up the result
|
|
+ * then pop off contextObj, which will be freed later
|
|
+ */
|
|
+ xmlXPathReleaseObject(xpctxt, tmp);
|
|
+ tmp = valuePop(ctxt);
|
|
+ }
|
|
goto evaluation_error;
|
|
}
|
|
+ /* push the result back onto the stack */
|
|
+ valuePush(ctxt, tmp);
|
|
|
|
if (res)
|
|
pos++;
|
|
@@ -13357,6 +13411,7 @@
|
|
xmlGenericError(xmlGenericErrorContext,
|
|
"xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
|
|
(char *) op->value4, (char *)op->value5);
|
|
+ ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
|
|
return (total);
|
|
}
|
|
val = xmlXPathVariableLookupNS(ctxt->context,
|
|
@@ -13373,7 +13428,9 @@
|
|
xmlXPathFunction func;
|
|
const xmlChar *oldFunc, *oldFuncURI;
|
|
int i;
|
|
+ int frame;
|
|
|
|
+ frame = xmlXPathSetFrame(ctxt);
|
|
if (op->ch1 != -1)
|
|
total +=
|
|
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
|
@@ -13381,15 +13438,18 @@
|
|
xmlGenericError(xmlGenericErrorContext,
|
|
"xmlXPathCompOpEval: parameter error\n");
|
|
ctxt->error = XPATH_INVALID_OPERAND;
|
|
+ xmlXPathPopFrame(ctxt, frame);
|
|
return (total);
|
|
}
|
|
- for (i = 0; i < op->value; i++)
|
|
+ for (i = 0; i < op->value; i++) {
|
|
if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
|
|
xmlGenericError(xmlGenericErrorContext,
|
|
"xmlXPathCompOpEval: parameter error\n");
|
|
ctxt->error = XPATH_INVALID_OPERAND;
|
|
+ xmlXPathPopFrame(ctxt, frame);
|
|
return (total);
|
|
}
|
|
+ }
|
|
if (op->cache != NULL)
|
|
XML_CAST_FPTR(func) = op->cache;
|
|
else {
|
|
@@ -13405,6 +13465,8 @@
|
|
xmlGenericError(xmlGenericErrorContext,
|
|
"xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
|
|
(char *)op->value4, (char *)op->value5);
|
|
+ ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
|
|
+ xmlXPathPopFrame(ctxt, frame);
|
|
return (total);
|
|
}
|
|
func = xmlXPathFunctionLookupNS(ctxt->context,
|
|
@@ -13426,6 +13488,7 @@
|
|
func(ctxt, op->value);
|
|
ctxt->context->function = oldFunc;
|
|
ctxt->context->functionURI = oldFuncURI;
|
|
+ xmlXPathPopFrame(ctxt, frame);
|
|
return (total);
|
|
}
|
|
case XPATH_OP_ARG:
|
|
@@ -14329,6 +14392,7 @@
|
|
ctxt->valueNr = 0;
|
|
ctxt->valueMax = 10;
|
|
ctxt->value = NULL;
|
|
+ ctxt->valueFrame = 0;
|
|
}
|
|
#ifdef XPATH_STREAMING
|
|
if (ctxt->comp->stream) {
|
|
--- libxml2-2.7.8/xpointer.c 2010-10-12 08:25:33.000000000 +0200
|
|
+++ libxml2-2.7.8.patched/xpointer.c 2012-09-28 12:08:37.428414664 +0200
|
|
@@ -1007,21 +1007,14 @@
|
|
NEXT;
|
|
break;
|
|
}
|
|
- *cur++ = CUR;
|
|
} else if (CUR == '(') {
|
|
level++;
|
|
- *cur++ = CUR;
|
|
} else if (CUR == '^') {
|
|
- NEXT;
|
|
- if ((CUR == ')') || (CUR == '(') || (CUR == '^')) {
|
|
- *cur++ = CUR;
|
|
- } else {
|
|
- *cur++ = '^';
|
|
- *cur++ = CUR;
|
|
- }
|
|
- } else {
|
|
- *cur++ = CUR;
|
|
+ if ((NXT(1) == ')') || (NXT(1) == '(') || (NXT(1) == '^')) {
|
|
+ NEXT;
|
|
+ }
|
|
}
|
|
+ *cur++ = CUR;
|
|
NEXT;
|
|
}
|
|
*cur = 0;
|
|
@@ -1269,6 +1262,7 @@
|
|
ctxt->valueNr = 0;
|
|
ctxt->valueMax = 10;
|
|
ctxt->value = NULL;
|
|
+ ctxt->valueFrame = 0;
|
|
}
|
|
SKIP_BLANKS;
|
|
if (CUR == '/') {
|
|
--- libxml2-2.7.8/libxml.h 2010-10-12 08:25:32.000000000 +0200
|
|
+++ libxml2-2.7.8.patched/libxml.h 2012-09-28 12:08:37.432414664 +0200
|
|
@@ -13,6 +13,9 @@
|
|
#ifndef _LARGEFILE_SOURCE
|
|
#define _LARGEFILE_SOURCE
|
|
#endif
|
|
+#ifndef _LARGEFILE64_SOURCE
|
|
+#define _LARGEFILE64_SOURCE
|
|
+#endif
|
|
#ifndef _FILE_OFFSET_BITS
|
|
#define _FILE_OFFSET_BITS 64
|
|
#endif
|
|
--- libxml2-2.7.8/include/libxml/xpath.h 2010-10-12 08:25:32.000000000 +0200
|
|
+++ libxml2-2.7.8.patched/include/libxml/xpath.h 2012-09-28 12:08:37.456414665 +0200
|
|
@@ -68,7 +68,8 @@
|
|
XPATH_UNDEF_PREFIX_ERROR,
|
|
XPATH_ENCODING_ERROR,
|
|
XPATH_INVALID_CHAR_ERROR,
|
|
- XPATH_INVALID_CTXT
|
|
+ XPATH_INVALID_CTXT,
|
|
+ XPATH_STACK_ERROR
|
|
} xmlXPathError;
|
|
|
|
/*
|
|
@@ -380,6 +381,8 @@
|
|
xmlXPathCompExprPtr comp; /* the precompiled expression */
|
|
int xptr; /* it this an XPointer expression */
|
|
xmlNodePtr ancestor; /* used for walking preceding axis */
|
|
+
|
|
+ int valueFrame; /* used to limit Pop on the stack */
|
|
};
|
|
|
|
/************************************************************************
|