Update the embedded copy of the expat XML parser to 2.1.0. It brings

with it a vareity of bug fixes, both security and behavior.  See
http://www.libexpat.org/ for the list.

NOTE: I already backported the expat hash randomization fix in March.

Fixes issue #14340.
This commit is contained in:
Gregory P. Smith 2012-07-14 14:12:35 -07:00
parent 15810673dc
commit 7c6309c6af
12 changed files with 379 additions and 263 deletions

View file

@ -2,24 +2,27 @@
See the file COPYING for copying permission.
*/
#define XML_BUILDING_EXPAT 1
#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
#include "macconfig.h"
#elif defined(__amigaos4__)
#include "amigaconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
#include <expat_config.h>
#endif /* ndef COMPILED_FROM_DSP */
#include <stddef.h>
#include <string.h> /* memset(), memcpy() */
#include <assert.h>
#include <limits.h> /* UINT_MAX */
#include <time.h> /* time() */
#define XML_BUILDING_EXPAT 1
#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
#include "macconfig.h"
#elif defined(__amigaos__)
#include "amigaconfig.h"
#elif defined(__WATCOMC__)
#include "watcomconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
#include <expat_config.h>
#endif /* ndef COMPILED_FROM_DSP */
#include "ascii.h"
#include "expat.h"
#ifdef XML_UNICODE
@ -28,7 +31,8 @@
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
#define XmlEncode XmlUtf16Encode
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
/* Using pointer subtraction to convert to integer type. */
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
typedef unsigned short ICHAR;
#else
#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
@ -325,15 +329,15 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
static enum XML_Error
initializeEncoding(XML_Parser parser);
static enum XML_Error
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
const char *end, int tok, const char *next, const char **nextPtr,
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
const char *end, int tok, const char *next, const char **nextPtr,
XML_Bool haveMore);
static enum XML_Error
processInternalEntity(XML_Parser parser, ENTITY *entity,
processInternalEntity(XML_Parser parser, ENTITY *entity,
XML_Bool betweenDecl);
static enum XML_Error
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
const char *start, const char *end, const char **endPtr,
const char *start, const char *end, const char **endPtr,
XML_Bool haveMore);
static enum XML_Error
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
@ -351,7 +355,7 @@ static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
const XML_Char *uri, BINDING **bindingsPtr);
static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
@ -436,6 +440,7 @@ parserCreate(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep,
DTD *dtd);
static void
parserInit(XML_Parser parser, const XML_Char *encodingName);
@ -535,6 +540,9 @@ struct XML_ParserStruct {
NS_ATT *m_nsAtts;
unsigned long m_nsAttsVersion;
unsigned char m_nsAttsPower;
#ifdef XML_ATTR_INFO
XML_AttrInfo *m_attInfo;
#endif
POSITION m_position;
STRING_POOL m_tempPool;
STRING_POOL m_temp2Pool;
@ -643,6 +651,7 @@ struct XML_ParserStruct {
#define nsAtts (parser->m_nsAtts)
#define nsAttsVersion (parser->m_nsAttsVersion)
#define nsAttsPower (parser->m_nsAttsPower)
#define attInfo (parser->m_attInfo)
#define tempPool (parser->m_tempPool)
#define temp2Pool (parser->m_temp2Pool)
#define groupConnector (parser->m_groupConnector)
@ -673,10 +682,12 @@ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
}
static const XML_Char implicitContext[] = {
'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
};
static unsigned long
@ -690,23 +701,22 @@ generate_hash_secret_salt(void)
static XML_Bool /* only valid for root parser */
startParsing(XML_Parser parser)
{
/* hash functions must be initialized before setContext() is called */
if (hash_secret_salt == 0)
hash_secret_salt = generate_hash_secret_salt();
if (ns) {
/* implicit context only set for root parser, since child
parsers (i.e. external entity parsers) will inherit it
*/
return setContext(parser, implicitContext);
}
return XML_TRUE;
/* hash functions must be initialized before setContext() is called */
if (hash_secret_salt == 0)
hash_secret_salt = generate_hash_secret_salt();
if (ns) {
/* implicit context only set for root parser, since child
parsers (i.e. external entity parsers) will inherit it
*/
return setContext(parser, implicitContext);
}
return XML_TRUE;
}
XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep)
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep)
{
return parserCreate(encodingName, memsuite, nameSep, NULL);
}
@ -753,9 +763,20 @@ parserCreate(const XML_Char *encodingName,
FREE(parser);
return NULL;
}
#ifdef XML_ATTR_INFO
attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
if (attInfo == NULL) {
FREE(atts);
FREE(parser);
return NULL;
}
#endif
dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
if (dataBuf == NULL) {
FREE(atts);
#ifdef XML_ATTR_INFO
FREE(attInfo);
#endif
FREE(parser);
return NULL;
}
@ -768,6 +789,9 @@ parserCreate(const XML_Char *encodingName,
if (_dtd == NULL) {
FREE(dataBuf);
FREE(atts);
#ifdef XML_ATTR_INFO
FREE(attInfo);
#endif
FREE(parser);
return NULL;
}
@ -783,7 +807,7 @@ parserCreate(const XML_Char *encodingName,
unknownEncodingHandler = NULL;
unknownEncodingHandlerData = NULL;
namespaceSeparator = '!';
namespaceSeparator = ASCII_EXCL;
ns = XML_FALSE;
ns_triplets = XML_FALSE;
@ -1154,6 +1178,9 @@ XML_ParserFree(XML_Parser parser)
#endif /* XML_DTD */
dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
FREE((void *)atts);
#ifdef XML_ATTR_INFO
FREE((void *)attInfo);
#endif
FREE(groupConnector);
FREE(buffer);
FREE(dataBuf);
@ -1234,6 +1261,14 @@ XML_GetIdAttributeIndex(XML_Parser parser)
return idAttIndex;
}
#ifdef XML_ATTR_INFO
const XML_AttrInfo * XMLCALL
XML_GetAttributeInfo(XML_Parser parser)
{
return attInfo;
}
#endif
void XMLCALL
XML_SetElementHandler(XML_Parser parser,
XML_StartElementHandler start,
@ -1499,7 +1534,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
positionPtr = bufferPtr;
return XML_STATUS_SUSPENDED;
case XML_INITIALIZED:
case XML_INITIALIZED:
case XML_PARSING:
ps_parsing = XML_FINISHED;
/* fall through */
@ -1554,16 +1589,12 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
? (char *)MALLOC(len * 2)
: (char *)REALLOC(buffer, len * 2));
if (temp == NULL) {
errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
}
buffer = temp;
if (!buffer) {
errorCode = XML_ERROR_NO_MEMORY;
eventPtr = eventEndPtr = NULL;
processor = errorProcessor;
return XML_STATUS_ERROR;
}
buffer = temp;
bufferLim = buffer + len * 2;
}
memcpy(buffer, end, nLeftOver);
@ -1629,7 +1660,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_INITIALIZED:
case XML_PARSING:
if (isFinal) {
ps_parsing = XML_FINISHED;
@ -1719,6 +1750,8 @@ XML_GetBuffer(XML_Parser parser, int len)
bufferPtr = buffer = newBuf;
#endif /* not defined XML_CONTEXT_BYTES */
}
eventPtr = eventEndPtr = NULL;
positionPtr = NULL;
}
return bufferEnd;
}
@ -1776,7 +1809,7 @@ XML_ResumeParser(XML_Parser parser)
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_INITIALIZED:
case XML_PARSING:
if (ps_finalBuffer) {
ps_parsing = XML_FINISHED;
@ -2000,6 +2033,12 @@ XML_GetFeatureList(void)
#endif
#ifdef XML_NS
{XML_FEATURE_NS, XML_L("XML_NS"), 0},
#endif
#ifdef XML_LARGE_SIZE
{XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
#endif
#ifdef XML_ATTR_INFO
{XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
#endif
{XML_FEATURE_END, NULL, 0}
};
@ -2063,7 +2102,7 @@ contentProcessor(XML_Parser parser,
const char *end,
const char **endPtr)
{
enum XML_Error result = doContent(parser, 0, encoding, start, end,
enum XML_Error result = doContent(parser, 0, encoding, start, end,
endPtr, (XML_Bool)!ps_finalBuffer);
if (result == XML_ERROR_NONE) {
if (!storeRawNames(parser))
@ -2145,7 +2184,7 @@ externalEntityInitProcessor3(XML_Parser parser,
if (result != XML_ERROR_NONE)
return result;
switch (ps_parsing) {
case XML_SUSPENDED:
case XML_SUSPENDED:
*endPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
@ -2179,7 +2218,7 @@ externalEntityContentProcessor(XML_Parser parser,
const char *end,
const char **endPtr)
{
enum XML_Error result = doContent(parser, 1, encoding, start, end,
enum XML_Error result = doContent(parser, 1, encoding, start, end,
endPtr, (XML_Bool)!ps_finalBuffer);
if (result == XML_ERROR_NONE) {
if (!storeRawNames(parser))
@ -2198,7 +2237,7 @@ doContent(XML_Parser parser,
XML_Bool haveMore)
{
/* save one level of indirection */
DTD * const dtd = _dtd;
DTD * const dtd = _dtd;
const char **eventPP;
const char **eventEndPP;
@ -2229,8 +2268,8 @@ doContent(XML_Parser parser,
}
else if (defaultHandler)
reportDefault(parser, enc, s, end);
/* We are at the end of the final buffer, should we check for
XML_SUSPENDED, XML_FINISHED?
/* We are at the end of the final buffer, should we check for
XML_SUSPENDED, XML_FINISHED?
*/
if (startTagLevel == 0)
return XML_ERROR_NO_ELEMENTS;
@ -2581,8 +2620,8 @@ doContent(XML_Parser parser,
}
else if (defaultHandler)
reportDefault(parser, enc, s, end);
/* We are at the end of the final buffer, should we check for
XML_SUSPENDED, XML_FINISHED?
/* We are at the end of the final buffer, should we check for
XML_SUSPENDED, XML_FINISHED?
*/
if (startTagLevel == 0) {
*eventPP = end;
@ -2595,26 +2634,29 @@ doContent(XML_Parser parser,
*nextPtr = end;
return XML_ERROR_NONE;
case XML_TOK_DATA_CHARS:
if (characterDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
characterDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
if (s == next)
break;
*eventPP = s;
{
XML_CharacterDataHandler charDataHandler = characterDataHandler;
if (charDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
charDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
if (s == next)
break;
*eventPP = s;
}
}
else
charDataHandler(handlerArg,
(XML_Char *)s,
(int)((XML_Char *)next - (XML_Char *)s));
}
else
characterDataHandler(handlerArg,
(XML_Char *)s,
(int)((XML_Char *)next - (XML_Char *)s));
else if (defaultHandler)
reportDefault(parser, enc, s, next);
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
case XML_TOK_PI:
if (!reportProcessingInstruction(parser, enc, s, next))
@ -2631,7 +2673,7 @@ doContent(XML_Parser parser,
}
*eventPP = s = next;
switch (ps_parsing) {
case XML_SUSPENDED:
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
@ -2690,23 +2732,44 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
if (n + nDefaultAtts > attsSize) {
int oldAttsSize = attsSize;
ATTRIBUTE *temp;
#ifdef XML_ATTR_INFO
XML_AttrInfo *temp2;
#endif
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
if (temp == NULL)
return XML_ERROR_NO_MEMORY;
atts = temp;
#ifdef XML_ATTR_INFO
temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
if (temp2 == NULL)
return XML_ERROR_NO_MEMORY;
attInfo = temp2;
#endif
if (n > oldAttsSize)
XmlGetAttributes(enc, attStr, n, atts);
}
appAtts = (const XML_Char **)atts;
for (i = 0; i < n; i++) {
ATTRIBUTE *currAtt = &atts[i];
#ifdef XML_ATTR_INFO
XML_AttrInfo *currAttInfo = &attInfo[i];
#endif
/* add the name and value to the attribute list */
ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
atts[i].name
+ XmlNameLength(enc, atts[i].name));
ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
currAtt->name
+ XmlNameLength(enc, currAtt->name));
if (!attId)
return XML_ERROR_NO_MEMORY;
#ifdef XML_ATTR_INFO
currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
currAttInfo->nameEnd = currAttInfo->nameStart +
XmlNameLength(enc, currAtt->name);
currAttInfo->valueStart = parseEndByteIndex -
(parseEndPtr - currAtt->valuePtr);
currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
#endif
/* Detect duplicate attributes by their QNames. This does not work when
namespace processing is turned on and different prefixes for the same
namespace are used. For this case we have a check further down.
@ -2848,8 +2911,6 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
unsigned long uriHash = hash_secret_salt;
((XML_Char *)s)[-1] = 0; /* clear flag */
id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
if (!id)
return XML_ERROR_NO_MEMORY;
b = id->prefix->binding;
if (!b)
return XML_ERROR_UNBOUND_PREFIX;
@ -2861,7 +2922,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
return XML_ERROR_NO_MEMORY;
uriHash = CHAR_HASH(uriHash, c);
}
while (*s++ != XML_T(':'))
while (*s++ != XML_T(ASCII_COLON))
;
do { /* copies null terminator */
const XML_Char c = *s;
@ -2935,7 +2996,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
if (!binding)
return XML_ERROR_UNBOUND_PREFIX;
localPart = tagNamePtr->str;
while (*localPart++ != XML_T(':'))
while (*localPart++ != XML_T(ASCII_COLON))
;
}
else if (dtd->defaultPrefix.binding) {
@ -2990,25 +3051,29 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
const XML_Char *uri, BINDING **bindingsPtr)
{
static const XML_Char xmlNamespace[] = {
'h', 't', 't', 'p', ':', '/', '/',
'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
ASCII_e, '\0'
};
static const int xmlLen =
static const int xmlLen =
(int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
static const XML_Char xmlnsNamespace[] = {
'h', 't', 't', 'p', ':', '/', '/',
'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
'2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
ASCII_SLASH, '\0'
};
static const int xmlnsLen =
static const int xmlnsLen =
(int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
XML_Bool mustBeXML = XML_FALSE;
XML_Bool isXML = XML_TRUE;
XML_Bool isXMLNS = XML_TRUE;
BINDING *b;
int len;
@ -3017,13 +3082,13 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
return XML_ERROR_UNDECLARING_PREFIX;
if (prefix->name
&& prefix->name[0] == XML_T('x')
&& prefix->name[1] == XML_T('m')
&& prefix->name[2] == XML_T('l')) {
&& prefix->name[0] == XML_T(ASCII_x)
&& prefix->name[1] == XML_T(ASCII_m)
&& prefix->name[2] == XML_T(ASCII_l)) {
/* Not allowed to bind xmlns */
if (prefix->name[3] == XML_T('n')
&& prefix->name[4] == XML_T('s')
if (prefix->name[3] == XML_T(ASCII_n)
&& prefix->name[4] == XML_T(ASCII_s)
&& prefix->name[5] == XML_T('\0'))
return XML_ERROR_RESERVED_PREFIX_XMLNS;
@ -3035,7 +3100,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
isXML = XML_FALSE;
if (!mustBeXML && isXMLNS
if (!mustBeXML && isXMLNS
&& (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
isXMLNS = XML_FALSE;
}
@ -3177,26 +3242,29 @@ doCdataSection(XML_Parser parser,
reportDefault(parser, enc, s, next);
break;
case XML_TOK_DATA_CHARS:
if (characterDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = next;
characterDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
if (s == next)
break;
*eventPP = s;
{
XML_CharacterDataHandler charDataHandler = characterDataHandler;
if (charDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = next;
charDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
if (s == next)
break;
*eventPP = s;
}
}
else
charDataHandler(handlerArg,
(XML_Char *)s,
(int)((XML_Char *)next - (XML_Char *)s));
}
else
characterDataHandler(handlerArg,
(XML_Char *)s,
(int)((XML_Char *)next - (XML_Char *)s));
else if (defaultHandler)
reportDefault(parser, enc, s, next);
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
case XML_TOK_INVALID:
*eventPP = next;
@ -3243,7 +3311,7 @@ ignoreSectionProcessor(XML_Parser parser,
const char *end,
const char **endPtr)
{
enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
endPtr, (XML_Bool)!ps_finalBuffer);
if (result != XML_ERROR_NONE)
return result;
@ -3525,7 +3593,7 @@ entityValueInitProcessor(XML_Parser parser,
const char *next = start;
eventPtr = start;
for (;;) {
for (;;) {
tok = XmlPrologTok(encoding, start, end, &next);
eventEndPtr = next;
if (tok <= 0) {
@ -3553,7 +3621,7 @@ entityValueInitProcessor(XML_Parser parser,
if (result != XML_ERROR_NONE)
return result;
switch (ps_parsing) {
case XML_SUSPENDED:
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
@ -3618,7 +3686,7 @@ externalParEntProcessor(XML_Parser parser,
}
processor = prologProcessor;
return doProlog(parser, encoding, s, end, tok, next,
return doProlog(parser, encoding, s, end, tok, next,
nextPtr, (XML_Bool)!ps_finalBuffer);
}
@ -3668,7 +3736,7 @@ prologProcessor(XML_Parser parser,
{
const char *next = s;
int tok = XmlPrologTok(encoding, s, end, &next);
return doProlog(parser, encoding, s, end, tok, next,
return doProlog(parser, encoding, s, end, tok, next,
nextPtr, (XML_Bool)!ps_finalBuffer);
}
@ -3683,26 +3751,30 @@ doProlog(XML_Parser parser,
XML_Bool haveMore)
{
#ifdef XML_DTD
static const XML_Char externalSubsetName[] = { '#' , '\0' };
static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
#endif /* XML_DTD */
static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
static const XML_Char atypeID[] = { 'I', 'D', '\0' };
static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
static const XML_Char atypeENTITIES[] =
{ 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
static const XML_Char atypeCDATA[] =
{ ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
static const XML_Char atypeIDREF[] =
{ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
static const XML_Char atypeIDREFS[] =
{ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
static const XML_Char atypeENTITY[] =
{ ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
static const XML_Char atypeNMTOKEN[] = {
'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
static const XML_Char atypeNMTOKENS[] = {
'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
static const XML_Char notationPrefix[] = {
'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
static const XML_Char enumValueSep[] = { '|', '\0' };
static const XML_Char enumValueStart[] = { '(', '\0' };
ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
/* save one level of indirection */
DTD * const dtd = _dtd;
DTD * const dtd = _dtd;
const char **eventPP;
const char **eventEndPP;
@ -3818,15 +3890,17 @@ doProlog(XML_Parser parser,
#endif /* XML_DTD */
dtd->hasParamEntityRefs = XML_TRUE;
if (startDoctypeDeclHandler) {
XML_Char *pubId;
if (!XmlIsPublicId(enc, s, next, eventPP))
return XML_ERROR_PUBLICID;
doctypePubid = poolStoreString(&tempPool, enc,
s + enc->minBytesPerChar,
next - enc->minBytesPerChar);
if (!doctypePubid)
pubId = poolStoreString(&tempPool, enc,
s + enc->minBytesPerChar,
next - enc->minBytesPerChar);
if (!pubId)
return XML_ERROR_NO_MEMORY;
normalizePublicId((XML_Char *)doctypePubid);
normalizePublicId(pubId);
poolFinish(&tempPool);
doctypePubid = pubId;
handleDefault = XML_FALSE;
goto alreadyChecked;
}
@ -3881,8 +3955,8 @@ doProlog(XML_Parser parser,
entity->publicId))
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
if (dtd->paramEntityRead) {
if (!dtd->standalone &&
notStandaloneHandler &&
if (!dtd->standalone &&
notStandaloneHandler &&
!notStandaloneHandler(handlerArg))
return XML_ERROR_NOT_STANDALONE;
}
@ -4010,11 +4084,11 @@ doProlog(XML_Parser parser,
0, parser))
return XML_ERROR_NO_MEMORY;
if (attlistDeclHandler && declAttributeType) {
if (*declAttributeType == XML_T('(')
|| (*declAttributeType == XML_T('N')
&& declAttributeType[1] == XML_T('O'))) {
if (*declAttributeType == XML_T(ASCII_LPAREN)
|| (*declAttributeType == XML_T(ASCII_N)
&& declAttributeType[1] == XML_T(ASCII_O))) {
/* Enumerated or Notation type */
if (!poolAppendChar(&tempPool, XML_T(')'))
if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
|| !poolAppendChar(&tempPool, XML_T('\0')))
return XML_ERROR_NO_MEMORY;
declAttributeType = tempPool.start;
@ -4047,11 +4121,11 @@ doProlog(XML_Parser parser,
declAttributeIsCdata, XML_FALSE, attVal, parser))
return XML_ERROR_NO_MEMORY;
if (attlistDeclHandler && declAttributeType) {
if (*declAttributeType == XML_T('(')
|| (*declAttributeType == XML_T('N')
&& declAttributeType[1] == XML_T('O'))) {
if (*declAttributeType == XML_T(ASCII_LPAREN)
|| (*declAttributeType == XML_T(ASCII_N)
&& declAttributeType[1] == XML_T(ASCII_O))) {
/* Enumerated or Notation type */
if (!poolAppendChar(&tempPool, XML_T(')'))
if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
|| !poolAppendChar(&tempPool, XML_T('\0')))
return XML_ERROR_NO_MEMORY;
declAttributeType = tempPool.start;
@ -4321,7 +4395,7 @@ doProlog(XML_Parser parser,
switch (tok) {
case XML_TOK_PARAM_ENTITY_REF:
/* PE references in internal subset are
not allowed within declarations. */
not allowed within declarations. */
return XML_ERROR_PARAM_ENTITY_REF;
case XML_TOK_XML_DECL:
return XML_ERROR_MISPLACED_XML_PI;
@ -4379,14 +4453,14 @@ doProlog(XML_Parser parser,
}
break;
case XML_ROLE_GROUP_SEQUENCE:
if (groupConnector[prologState.level] == '|')
if (groupConnector[prologState.level] == ASCII_PIPE)
return XML_ERROR_SYNTAX;
groupConnector[prologState.level] = ',';
groupConnector[prologState.level] = ASCII_COMMA;
if (dtd->in_eldecl && elementDeclHandler)
handleDefault = XML_FALSE;
break;
case XML_ROLE_GROUP_CHOICE:
if (groupConnector[prologState.level] == ',')
if (groupConnector[prologState.level] == ASCII_COMMA)
return XML_ERROR_SYNTAX;
if (dtd->in_eldecl
&& !groupConnector[prologState.level]
@ -4398,7 +4472,7 @@ doProlog(XML_Parser parser,
if (elementDeclHandler)
handleDefault = XML_FALSE;
}
groupConnector[prologState.level] = '|';
groupConnector[prologState.level] = ASCII_PIPE;
break;
case XML_ROLE_PARAM_ENTITY_REF:
#ifdef XML_DTD
@ -4442,7 +4516,7 @@ doProlog(XML_Parser parser,
return XML_ERROR_RECURSIVE_ENTITY_REF;
if (entity->textPtr) {
enum XML_Error result;
XML_Bool betweenDecl =
XML_Bool betweenDecl =
(role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
result = processInternalEntity(parser, entity, betweenDecl);
if (result != XML_ERROR_NONE)
@ -4637,7 +4711,7 @@ doProlog(XML_Parser parser,
reportDefault(parser, enc, s, next);
switch (ps_parsing) {
case XML_SUSPENDED:
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
@ -4707,7 +4781,7 @@ epilogProcessor(XML_Parser parser,
}
eventPtr = s = next;
switch (ps_parsing) {
case XML_SUSPENDED:
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
@ -4750,12 +4824,12 @@ processInternalEntity(XML_Parser parser, ENTITY *entity,
#ifdef XML_DTD
if (entity->is_param) {
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
next, &next, XML_FALSE);
}
else
else
#endif /* XML_DTD */
result = doContent(parser, tagLevel, internalEncoding, textStart,
result = doContent(parser, tagLevel, internalEncoding, textStart,
textEnd, &next, XML_FALSE);
if (result == XML_ERROR_NONE) {
@ -4795,13 +4869,13 @@ internalEntityProcessor(XML_Parser parser,
#ifdef XML_DTD
if (entity->is_param) {
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
next, &next, XML_FALSE);
}
else
#endif /* XML_DTD */
result = doContent(parser, openEntity->startTagLevel, internalEncoding,
textStart, textEnd, &next, XML_FALSE);
result = doContent(parser, openEntity->startTagLevel, internalEncoding,
textStart, textEnd, &next, XML_FALSE);
if (result != XML_ERROR_NONE)
return result;
@ -4822,7 +4896,7 @@ internalEntityProcessor(XML_Parser parser,
int tok;
processor = prologProcessor;
tok = XmlPrologTok(encoding, s, end, &next);
return doProlog(parser, encoding, s, end, tok, next, nextPtr,
return doProlog(parser, encoding, s, end, tok, next, nextPtr,
(XML_Bool)!ps_finalBuffer);
}
else
@ -4831,8 +4905,8 @@ internalEntityProcessor(XML_Parser parser,
processor = contentProcessor;
/* see externalEntityContentProcessor vs contentProcessor */
return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
nextPtr, (XML_Bool)!ps_finalBuffer);
}
nextPtr, (XML_Bool)!ps_finalBuffer);
}
}
static enum XML_Error PTRCALL
@ -4985,7 +5059,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
if (!entity->textPtr) {
if (enc == encoding)
eventPtr = ptr;
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
}
else {
enum XML_Error result;
@ -5328,7 +5402,7 @@ setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
DTD * const dtd = _dtd; /* save one level of indirection */
const XML_Char *name;
for (name = elementType->name; *name; name++) {
if (*name == XML_T(':')) {
if (*name == XML_T(ASCII_COLON)) {
PREFIX *prefix;
const XML_Char *s;
for (s = elementType->name; s != name; s++) {
@ -5375,12 +5449,12 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
poolFinish(&dtd->pool);
if (!ns)
;
else if (name[0] == XML_T('x')
&& name[1] == XML_T('m')
&& name[2] == XML_T('l')
&& name[3] == XML_T('n')
&& name[4] == XML_T('s')
&& (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
else if (name[0] == XML_T(ASCII_x)
&& name[1] == XML_T(ASCII_m)
&& name[2] == XML_T(ASCII_l)
&& name[3] == XML_T(ASCII_n)
&& name[4] == XML_T(ASCII_s)
&& (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
if (name[5] == XML_T('\0'))
id->prefix = &dtd->defaultPrefix;
else
@ -5391,7 +5465,7 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
int i;
for (i = 0; name[i]; i++) {
/* attributes without prefix are *not* in the default namespace */
if (name[i] == XML_T(':')) {
if (name[i] == XML_T(ASCII_COLON)) {
int j;
for (j = 0; j < i; j++) {
if (!poolAppendChar(&dtd->pool, name[j]))
@ -5401,8 +5475,6 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
return NULL;
id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
sizeof(PREFIX));
if (!id->prefix)
return NULL;
if (id->prefix->name == poolStart(&dtd->pool))
poolFinish(&dtd->pool);
else
@ -5415,7 +5487,7 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
return id;
}
#define CONTEXT_SEP XML_T('\f')
#define CONTEXT_SEP XML_T(ASCII_FF)
static const XML_Char *
getContext(XML_Parser parser)
@ -5427,7 +5499,7 @@ getContext(XML_Parser parser)
if (dtd->defaultPrefix.binding) {
int i;
int len;
if (!poolAppendChar(&tempPool, XML_T('=')))
if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
return NULL;
len = dtd->defaultPrefix.binding->uriLen;
if (namespaceSeparator)
@ -5453,7 +5525,7 @@ getContext(XML_Parser parser)
for (s = prefix->name; *s; s++)
if (!poolAppendChar(&tempPool, *s))
return NULL;
if (!poolAppendChar(&tempPool, XML_T('=')))
if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
return NULL;
len = prefix->binding->uriLen;
if (namespaceSeparator)
@ -5505,7 +5577,7 @@ setContext(XML_Parser parser, const XML_Char *context)
context = s;
poolDiscard(&tempPool);
}
else if (*s == XML_T('=')) {
else if (*s == XML_T(ASCII_EQUALS)) {
PREFIX *prefix;
if (poolLength(&tempPool) == 0)
prefix = &dtd->defaultPrefix;
@ -6162,12 +6234,13 @@ poolGrow(STRING_POOL *pool)
}
if (pool->blocks && pool->start == pool->blocks->s) {
int blockSize = (int)(pool->end - pool->start)*2;
pool->blocks = (BLOCK *)
BLOCK *temp = (BLOCK *)
pool->mem->realloc_fcn(pool->blocks,
(offsetof(BLOCK, s)
+ blockSize * sizeof(XML_Char)));
if (pool->blocks == NULL)
if (temp == NULL)
return XML_FALSE;
pool->blocks = temp;
pool->blocks->size = blockSize;
pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
pool->start = pool->blocks->s;