diff --git a/mozilla/parser/expat/COPYING b/mozilla/parser/expat/COPYING index e3ad54e969a..5c5d524a1f8 100644 --- a/mozilla/parser/expat/COPYING +++ b/mozilla/parser/expat/COPYING @@ -1,6 +1,6 @@ Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper -Copyright (c) 2001, 2002 Expat maintainers. +Copyright (c) 2001, 2002, 2003 Expat maintainers. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/mozilla/parser/expat/expat_config.h b/mozilla/parser/expat/expat_config.h index 0e392835a81..73c3cca2fa5 100644 --- a/mozilla/parser/expat/expat_config.h +++ b/mozilla/parser/expat/expat_config.h @@ -133,6 +133,9 @@ typedef char XML_LChar; #define XML_Parse MOZ_XML_Parse #define XML_GetBuffer MOZ_XML_GetBuffer #define XML_ParseBuffer MOZ_XML_ParseBuffer +#define XML_StopParser MOZ_XML_StopParser +#define XML_ResumeParser MOZ_XML_ResumeParser +#define XML_GetParsingStatus MOZ_XML_GetParsingStatus #define XML_ExternalEntityParserCreate MOZ_XML_ExternalEntityParserCreate #define XML_SetParamEntityParsing MOZ_XML_SetParamEntityParsing #define XML_GetErrorCode MOZ_XML_GetErrorCode diff --git a/mozilla/parser/expat/lib/Makefile.in b/mozilla/parser/expat/lib/Makefile.in index ce9a4eafc51..35c8ebde688 100644 --- a/mozilla/parser/expat/lib/Makefile.in +++ b/mozilla/parser/expat/lib/Makefile.in @@ -51,7 +51,9 @@ CSRCS = \ xmltok.c \ $(NULL) -EXPORTS = expat.h +EXPORTS = \ + expat.h \ + expat_external.h # We want only the static lib, not the shared lib FORCE_STATIC_LIB = 1 diff --git a/mozilla/parser/expat/lib/expat.h b/mozilla/parser/expat/lib/expat.h index b140e7b0283..8a621e7bdec 100644 --- a/mozilla/parser/expat/lib/expat.h +++ b/mozilla/parser/expat/lib/expat.h @@ -15,103 +15,11 @@ #endif #include - -#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) -#define XML_USE_MSC_EXTENSIONS 1 -#endif - -/* Expat tries very hard to make the API boundary very specifically - defined. There are two macros defined to control this boundary; - each of these can be defined before including this header to - achieve some different behavior, but doing so it not recommended or - tested frequently. - - XMLCALL - The calling convention to use for all calls across the - "library boundary." This will default to cdecl, and - try really hard to tell the compiler that's what we - want. - - XMLIMPORT - Whatever magic is needed to note that a function is - to be imported from a dynamically loaded library - (.dll, .so, or .sl, depending on your platform). - - The XMLCALL macro was added in Expat 1.95.7. The only one which is - expected to be directly useful in client code is XMLCALL. - - Note that on at least some Unix versions, the Expat library must be - compiled with the cdecl calling convention as the default since - system headers may assume the cdecl convention. -*/ -#ifndef XMLCALL -#if defined(XML_USE_MSC_EXTENSIONS) -#define XMLCALL __cdecl -#elif defined(__GNUC__) -#define XMLCALL __attribute__((cdecl)) -#else -/* For any platform which uses this definition and supports more than - one calling convention, we need to extend this definition to - declare the convention used on that platform, if it's possible to - do so. - - If this is the case for your platform, please file a bug report - with information on how to identify your platform via the C - pre-processor and how to specify the same calling convention as the - platform's malloc() implementation. -*/ -#define XMLCALL -#endif -#endif /* not defined XMLCALL */ - - -#if !defined(XML_STATIC) && !defined(XMLIMPORT) -#ifndef XML_BUILDING_EXPAT -/* using Expat from an application */ - -#ifdef XML_USE_MSC_EXTENSIONS -#define XMLIMPORT __declspec(dllimport) -#endif - -#endif -#endif /* not defined XML_STATIC */ - -/* If we didn't define it above, define it away: */ -#ifndef XMLIMPORT -#define XMLIMPORT -#endif - - -#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef XML_UNICODE_WCHAR_T -#define XML_UNICODE -#endif +#include "expat_external.h" struct XML_ParserStruct; typedef struct XML_ParserStruct *XML_Parser; -/* BEGIN MOZILLA CHANGE (typedef XML_Char to PRUnichar) */ -#if 0 - -#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ -#ifdef XML_UNICODE_WCHAR_T -typedef wchar_t XML_Char; -typedef wchar_t XML_LChar; -#else -typedef unsigned short XML_Char; -typedef char XML_LChar; -#endif /* XML_UNICODE_WCHAR_T */ -#else /* Information is UTF-8 encoded. */ -typedef char XML_Char; -typedef char XML_LChar; -#endif /* XML_UNICODE */ - -#endif -/* END MOZILLA CHANGE */ - /* Should this be defined using stdbool.h when C99 is available? */ typedef unsigned char XML_Bool; #define XML_TRUE ((XML_Bool) 1) @@ -133,8 +41,10 @@ typedef unsigned char XML_Bool; enum XML_Status { XML_STATUS_ERROR = 0, #define XML_STATUS_ERROR XML_STATUS_ERROR - XML_STATUS_OK = 1 + XML_STATUS_OK = 1, #define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED }; enum XML_Error { @@ -165,10 +75,19 @@ enum XML_Error { XML_ERROR_ENTITY_DECLARED_IN_PE, XML_ERROR_FEATURE_REQUIRES_XML_DTD, XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, - XML_ERROR_UNBOUND_PREFIX -/* BEGIN MOZILLA CHANGE (blocking parser) */ - , XML_ERROR_SUSPENDED, -/* END MOZILLA CHANGE */ + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, /* BEGIN MOZILLA CHANGE (backport of bug fix from Expat trunk) */ XML_ERROR_RESERVED_PREFIX_XML, XML_ERROR_RESERVED_PREFIX_XMLNS, @@ -272,9 +191,9 @@ XML_SetXmlDeclHandler(XML_Parser parser, typedef struct { - void *(XMLCALL *malloc_fcn)(size_t size); - void *(XMLCALL *realloc_fcn)(void *ptr, size_t size); - void (XMLCALL *free_fcn)(void *ptr); + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); } XML_Memory_Handling_Suite; /* Constructs a new parser; encoding is the encoding specified by the @@ -614,10 +533,12 @@ XML_SetElementHandler(XML_Parser parser, XML_EndElementHandler end); XMLPARSEAPI(void) -XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler); +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); XMLPARSEAPI(void) -XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler); +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); XMLPARSEAPI(void) XML_SetCharacterDataHandler(XML_Parser parser, @@ -706,7 +627,8 @@ XML_SetExternalEntityRefHandler(XML_Parser parser, instead of the parser object. */ XMLPARSEAPI(void) -XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); XMLPARSEAPI(void) XML_SetSkippedEntityHandler(XML_Parser parser, @@ -769,6 +691,9 @@ XML_UseParserAsHandlerArg(XML_Parser parser); specified in the document. In such a case the parser will call the externalEntityRefHandler with a value of NULL for the systemId argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. Note: If this function is called, then this must be done before the first call to XML_Parse or XML_ParseBuffer, since it will have no effect after that. Returns @@ -832,13 +757,74 @@ XML_GetBuffer(XML_Parser parser, int len); XMLPARSEAPI(enum XML_Status) XML_ParseBuffer(XML_Parser parser, int len, int isFinal); -/* BEGIN MOZILLA CHANGE (blocking parser) */ -XMLPARSEAPI(enum XML_Status) -MOZ_XML_StopParser(XML_Parser parser, XML_Bool resumable); +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ XMLPARSEAPI(enum XML_Status) -MOZ_XML_ResumeParser(XML_Parser parser); -/* END MOZILLA CHANGE */ +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); /* Creates an XML_Parser object that can parse an external general entity; context is a '\0'-terminated string specifying the parse @@ -1014,7 +1000,7 @@ XML_GetFeatureList(void); */ #define XML_MAJOR_VERSION 1 #define XML_MINOR_VERSION 95 -#define XML_MICRO_VERSION 7 +#define XML_MICRO_VERSION 8 /* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */ XMLPARSEAPI(const XML_Char*) diff --git a/mozilla/parser/expat/lib/internal.h b/mozilla/parser/expat/lib/internal.h index 807d02b8d66..08dfb1a7555 100644 --- a/mozilla/parser/expat/lib/internal.h +++ b/mozilla/parser/expat/lib/internal.h @@ -20,7 +20,10 @@ and therefore subject to change. */ +/* BEGIN MOZILLA CHANGE (https://bugzilla.mozilla.org/show_bug.cgi?id=297604) */ +// #if defined(__GNUC__) && defined(__i386__) #if defined(__GNUC__) && defined(__i386__) && !defined(XP_MACOSX) +/* END MOZILLA CHANGE */ /* We'll use this version by default only where we know it helps. regparm() generates warnings on Solaris boxes. See SF bug #692878. diff --git a/mozilla/parser/expat/lib/xmlparse.c b/mozilla/parser/expat/lib/xmlparse.c index 9a1750fbef6..d840bc1dad9 100644 --- a/mozilla/parser/expat/lib/xmlparse.c +++ b/mozilla/parser/expat/lib/xmlparse.c @@ -4,6 +4,7 @@ #include #include /* memset(), memcpy() */ +#include #define XML_BUILDING_EXPAT 1 @@ -11,10 +12,8 @@ #include "winconfig.h" #elif defined(MACOS_CLASSIC) #include "macconfig.h" -#else -#ifdef HAVE_EXPAT_CONFIG_H +#elif defined(HAVE_EXPAT_CONFIG_H) #include -#endif #endif /* ndef COMPILED_FROM_DSP */ #include "expat.h" @@ -190,7 +189,8 @@ typedef struct tag { typedef struct { const XML_Char *name; const XML_Char *textPtr; - int textLen; + int textLen; /* length in XML_Chars */ + int processed; /* # of processed bytes - when suspended */ const XML_Char *systemId; const XML_Char *base; const XML_Char *publicId; @@ -291,6 +291,8 @@ typedef struct open_internal_entity { const char *internalEventEndPtr; struct open_internal_entity *next; ENTITY *entity; + int startTagLevel; + XML_Bool betweenDecl; /* WFC: PE Between Declarations */ } OPEN_INTERNAL_ENTITY; typedef enum XML_Error PTRCALL Processor(XML_Parser parser, @@ -315,29 +317,33 @@ static Processor externalEntityInitProcessor; static Processor externalEntityInitProcessor2; static Processor externalEntityInitProcessor3; static Processor externalEntityContentProcessor; +static Processor internalEntityProcessor; static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, - const char *, const char *); + const char *s, const char *next); 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 -processInternalParamEntity(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, - const char *end, const char **nextPtr); + const char *end, const char **nextPtr, XML_Bool haveMore); #ifdef XML_DTD static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, - const char *end, const char **nextPtr); + const char *end, const char **nextPtr, XML_Bool haveMore); #endif /* XML_DTD */ static enum XML_Error @@ -347,9 +353,8 @@ 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, XML_Bool isId, const XML_Char *dfltValue, - XML_Parser parser); +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, const char *, const char *, STRING_POOL *); @@ -493,7 +498,7 @@ struct XML_ParserStruct { void *m_unknownEncodingMem; void *m_unknownEncodingData; void *m_unknownEncodingHandlerData; - void (*m_unknownEncodingRelease)(void *); + void (XMLCALL *m_unknownEncodingRelease)(void *); PROLOG_STATE m_prologState; Processor *m_processor; enum XML_Error m_errorCode; @@ -501,6 +506,7 @@ struct XML_ParserStruct { const char *m_eventEndPtr; const char *m_positionPtr; OPEN_INTERNAL_ENTITY *m_openInternalEntities; + OPEN_INTERNAL_ENTITY *m_freeInternalEntities; XML_Bool m_defaultExpandInternalEntities; int m_tagLevel; ENTITY *m_declEntity; @@ -534,14 +540,12 @@ struct XML_ParserStruct { unsigned int m_groupSize; XML_Char m_namespaceSeparator; XML_Parser m_parentParser; + XML_ParsingStatus m_parsingStatus; #ifdef XML_DTD XML_Bool m_isParamEntity; XML_Bool m_useForeignDTD; enum XML_ParamEntityParsing m_paramEntityParsing; #endif -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - XML_Bool m_blocked; -/* END MOZILLA CHANGE */ /* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */ const XML_Char* m_mismatch; /* END MOZILLA CHANGE */ @@ -603,6 +607,7 @@ struct XML_ParserStruct { #define positionPtr (parser->m_positionPtr) #define position (parser->m_position) #define openInternalEntities (parser->m_openInternalEntities) +#define freeInternalEntities (parser->m_freeInternalEntities) #define defaultExpandInternalEntities \ (parser->m_defaultExpandInternalEntities) #define tagLevel (parser->m_tagLevel) @@ -644,38 +649,17 @@ struct XML_ParserStruct { #define groupSize (parser->m_groupSize) #define namespaceSeparator (parser->m_namespaceSeparator) #define parentParser (parser->m_parentParser) +#define parsing (parser->m_parsingStatus.parsing) +#define finalBuffer (parser->m_parsingStatus.finalBuffer) #ifdef XML_DTD #define isParamEntity (parser->m_isParamEntity) #define useForeignDTD (parser->m_useForeignDTD) #define paramEntityParsing (parser->m_paramEntityParsing) #endif /* XML_DTD */ -/* BEGIN MOZILLA CHANGE (Blocking parser) */ -#define blocked (parser->m_blocked) -/* END MOZILLA CHANGE */ /* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */ #define mismatch (parser->m_mismatch) /* END MOZILLA CHANGE */ -#ifdef XML_DTD -#define parsing \ - (parentParser \ - ? \ - (isParamEntity \ - ? \ - (processor != externalParEntInitProcessor) \ - : \ - (processor != externalEntityInitProcessor)) \ - : \ - (processor != prologInitProcessor)) -#else -#define parsing \ - (parentParser \ - ? \ - (processor != externalEntityInitProcessor) \ - : \ - (processor != prologInitProcessor)) -#endif /* XML_DTD */ - /* BEGIN MOZILLA CHANGE (unused API) */ #ifdef TX_EXE XML_Parser XMLCALL @@ -785,6 +769,7 @@ parserCreate(const XML_Char *encodingName, freeBindingList = NULL; freeTagList = NULL; + freeInternalEntities = NULL; groupSize = 0; groupConnector = NULL; @@ -818,9 +803,6 @@ parserCreate(const XML_Char *encodingName, internalEncoding = XmlGetInternalEncoding(); } -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - blocked = XML_FALSE; -/* END MOZILLA CHANGE */ /* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */ mismatch = NULL; /* END MOZILLA CHANGE */ @@ -882,7 +864,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) eventPtr = NULL; eventEndPtr = NULL; positionPtr = NULL; - openInternalEntities = 0; + openInternalEntities = NULL; defaultExpandInternalEntities = XML_TRUE; tagLevel = 0; tagStack = NULL; @@ -892,6 +874,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) unknownEncodingRelease = NULL; unknownEncodingData = NULL; parentParser = NULL; + parsing = XML_INITIALIZED; #ifdef XML_DTD isParamEntity = XML_FALSE; useForeignDTD = XML_FALSE; @@ -917,6 +900,7 @@ XML_Bool XMLCALL XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { TAG *tStk; + OPEN_INTERNAL_ENTITY *openEntityList; if (parentParser) return XML_FALSE; /* move tagStack to freeTagList */ @@ -929,6 +913,14 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) tag->bindings = NULL; freeTagList = tag; } + /* move openInternalEntities to freeInternalEntities */ + openEntityList = openInternalEntities; + while (openEntityList) { + OPEN_INTERNAL_ENTITY *openEntity = openEntityList; + openEntityList = openEntity->next; + openEntity->next = freeInternalEntities; + freeInternalEntities = openEntity; + } moveToFreeBindingList(parser, inheritedBindings); FREE(unknownEncodingMem); if (unknownEncodingRelease) @@ -947,7 +939,7 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. */ - if (parsing) + if (parsing == XML_PARSING || parsing == XML_SUSPENDED) return XML_STATUS_ERROR; if (encodingName == NULL) protocolEncodingName = NULL; @@ -1107,20 +1099,41 @@ destroyBindings(BINDING *bindings, XML_Parser parser) void XMLCALL XML_ParserFree(XML_Parser parser) { + TAG *tagList; + OPEN_INTERNAL_ENTITY *entityList; + if (parser == NULL) + return; + /* free tagStack and freeTagList */ + tagList = tagStack; for (;;) { TAG *p; - if (tagStack == NULL) { + if (tagList == NULL) { if (freeTagList == NULL) break; - tagStack = freeTagList; + tagList = freeTagList; freeTagList = NULL; } - p = tagStack; - tagStack = tagStack->parent; + p = tagList; + tagList = tagList->parent; FREE(p->buf); destroyBindings(p->bindings, parser); FREE(p); } + /* free openInternalEntities and freeInternalEntities */ + entityList = openInternalEntities; + for (;;) { + OPEN_INTERNAL_ENTITY *openEntity; + if (entityList == NULL) { + if (freeInternalEntities == NULL) + break; + entityList = freeInternalEntities; + freeInternalEntities = NULL; + } + openEntity = entityList; + entityList = entityList->next; + FREE(openEntity); + } + destroyBindings(freeBindingList, parser); destroyBindings(inheritedBindings, parser); poolDestroy(&tempPool); @@ -1158,7 +1171,7 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parsing) + if (parsing == XML_PARSING || parsing == XML_SUSPENDED) return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; useForeignDTD = useDTD; return XML_ERROR_NONE; @@ -1173,7 +1186,7 @@ void XMLCALL XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parsing) + if (parsing == XML_PARSING || parsing == XML_SUSPENDED) return; ns_triplets = do_nst ? XML_TRUE : XML_FALSE; } @@ -1441,7 +1454,7 @@ XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing peParsing) { /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parsing) + if (parsing == XML_PARSING || parsing == XML_SUSPENDED) return 0; #ifdef XML_DTD paramEntityParsing = peParsing; @@ -1454,28 +1467,44 @@ XML_SetParamEntityParsing(XML_Parser parser, enum XML_Status XMLCALL XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (blocked) { - /* First unblock parser */ + switch (parsing) { + case XML_SUSPENDED: + errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; + case XML_FINISHED: + errorCode = XML_ERROR_FINISHED; + return XML_STATUS_ERROR; + default: + parsing = XML_PARSING; } -/* END MOZILLA CHANGE */ if (len == 0) { + finalBuffer = (XML_Bool)isFinal; if (!isFinal) return XML_STATUS_OK; positionPtr = bufferPtr; - errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); - if (errorCode == XML_ERROR_NONE) - return XML_STATUS_OK; -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (errorCode == XML_ERROR_SUSPENDED) { - bufferPtr = eventPtr; - parseEndPtr = eventEndPtr; - XmlUpdatePosition(encoding, positionPtr, eventEndPtr, &position); - return XML_STATUS_ERROR; + parseEndPtr = bufferEnd; + + /* If data are left over from last buffer, and we now know that these + data are the final chunk of input, then we have to check them again + to detect errors based on this information. + */ + errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); + + if (errorCode == XML_ERROR_NONE) { + switch (parsing) { + case XML_SUSPENDED: + XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); + positionPtr = bufferPtr; + return XML_STATUS_SUSPENDED; + case XML_INITIALIZED: + case XML_PARSING: + parsing = XML_FINISHED; + /* fall through */ + default: + return XML_STATUS_OK; + } } -/* END MOZILLA CHANGE */ eventEndPtr = eventPtr; processor = errorProcessor; return XML_STATUS_ERROR; @@ -1484,33 +1513,39 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) else if (bufferPtr == bufferEnd) { const char *end; int nLeftOver; + enum XML_Error result; parseEndByteIndex += len; positionPtr = s; - if (isFinal) { - errorCode = processor(parser, s, parseEndPtr = s + len, 0); - if (errorCode == XML_ERROR_NONE) - return XML_STATUS_OK; - eventEndPtr = eventPtr; - processor = errorProcessor; - return XML_STATUS_ERROR; - } + finalBuffer = (XML_Bool)isFinal; + errorCode = processor(parser, s, parseEndPtr = s + len, &end); + if (errorCode != XML_ERROR_NONE) { -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (blocked) { - parseEndPtr = eventEndPtr; - parseEndByteIndex -= len - (eventPtr - s); /* This is how much we've read thus far*/ - XmlUpdatePosition(encoding, positionPtr, eventEndPtr, &position); - eventEndPtr = eventPtr; - return XML_STATUS_ERROR; - } -/* END MOZILLA CHANGE */ eventEndPtr = eventPtr; processor = errorProcessor; return XML_STATUS_ERROR; } + else { + switch (parsing) { + case XML_SUSPENDED: + result = XML_STATUS_SUSPENDED; + break; + case XML_INITIALIZED: + case XML_PARSING: + result = XML_STATUS_OK; + if (isFinal) { + parsing = XML_FINISHED; + return result; + } + } + } + XmlUpdatePosition(encoding, positionPtr, end, &position); +/* BEGIN MOZILLA CHANGE (backport of bug fix from Expat trunk) */ +#if 0 positionPtr = end; +#endif +/* END MOZILLA CHANGE */ nLeftOver = s + len - end; if (nLeftOver) { if (buffer == NULL || nLeftOver > bufferLim - buffer) { @@ -1533,10 +1568,22 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) bufferLim = buffer + len * 2; } memcpy(buffer, end, nLeftOver); +/* BEGIN MOZILLA CHANGE (backport of bug fix from Expat trunk) */ +#if 0 bufferPtr = buffer; bufferEnd = buffer + nLeftOver; } - return XML_STATUS_OK; +#else + } + bufferPtr = buffer; + bufferEnd = buffer + nLeftOver; + positionPtr = bufferPtr; + parseEndPtr = bufferEnd; + eventPtr = bufferPtr; + eventEndPtr = bufferPtr; +#endif +/* END MOZILLA CHANGE */ + return result; } #endif /* not defined XML_CONTEXT_BYTES */ else { @@ -1553,40 +1600,67 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) enum XML_Status XMLCALL XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { - const char *start = bufferPtr; + const char *start; + enum XML_Error result = XML_STATUS_OK; + + switch (parsing) { + case XML_SUSPENDED: + errorCode = XML_ERROR_SUSPENDED; + return XML_STATUS_ERROR; + case XML_FINISHED: + errorCode = XML_ERROR_FINISHED; + return XML_STATUS_ERROR; + default: + parsing = XML_PARSING; + } + + start = bufferPtr; positionPtr = start; bufferEnd += len; + parseEndPtr = bufferEnd; parseEndByteIndex += len; - errorCode = processor(parser, start, parseEndPtr = bufferEnd, - isFinal ? (const char **)NULL : &bufferPtr); - if (errorCode == XML_ERROR_NONE) { - if (!isFinal) { - XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); - positionPtr = bufferPtr; - } - return XML_STATUS_OK; - } -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - else if (errorCode == XML_ERROR_SUSPENDED) { - int unparsed = bufferEnd - eventEndPtr; - bufferPtr = eventPtr; - parseEndPtr = eventEndPtr; - bufferEnd -= unparsed; /* Substract what we haven't parsed */ - parseEndByteIndex -= unparsed; - XmlUpdatePosition(encoding, positionPtr, eventEndPtr, &position); - return XML_STATUS_ERROR; - } -/* END MOZILLA CHANGE */ - else { + finalBuffer = (XML_Bool)isFinal; + + errorCode = processor(parser, start, parseEndPtr, &bufferPtr); + + if (errorCode != XML_ERROR_NONE) { eventEndPtr = eventPtr; processor = errorProcessor; return XML_STATUS_ERROR; } + else { + switch (parsing) { + case XML_SUSPENDED: + result = XML_STATUS_SUSPENDED; + break; + case XML_INITIALIZED: + case XML_PARSING: + if (isFinal) { + parsing = XML_FINISHED; + return result; + } + default: ; /* should not happen */ + } + } + + XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); + positionPtr = bufferPtr; + return result; } void * XMLCALL XML_GetBuffer(XML_Parser parser, int len) { + switch (parsing) { + case XML_SUSPENDED: + errorCode = XML_ERROR_SUSPENDED; + return NULL; + case XML_FINISHED: + errorCode = XML_ERROR_FINISHED; + return NULL; + default: ; + } + if (len > bufferLim - bufferEnd) { /* FIXME avoid integer overflow */ int neededSize = len + (bufferEnd - bufferPtr); @@ -1653,21 +1727,82 @@ XML_GetBuffer(XML_Parser parser, int len) return bufferEnd; } -/* BEGIN MOZILLA CHANGE (Blocking parser) */ enum XML_Status XMLCALL -MOZ_XML_StopParser(XML_Parser parser, XML_Bool resumable) +XML_StopParser(XML_Parser parser, XML_Bool resumable) { - blocked = XML_TRUE; + switch (parsing) { + case XML_SUSPENDED: + if (resumable) { + errorCode = XML_ERROR_SUSPENDED; + return XML_STATUS_ERROR; + } + parsing = XML_FINISHED; + break; + case XML_FINISHED: + errorCode = XML_ERROR_FINISHED; + return XML_STATUS_ERROR; + default: + if (resumable) { +#ifdef XML_DTD + if (isParamEntity) { + errorCode = XML_ERROR_SUSPEND_PE; + return XML_STATUS_ERROR; + } +#endif + parsing = XML_SUSPENDED; + } + else + parsing = XML_FINISHED; + } return XML_STATUS_OK; } enum XML_Status XMLCALL -MOZ_XML_ResumeParser(XML_Parser parser) +XML_ResumeParser(XML_Parser parser) { - blocked = XML_FALSE; - return XML_STATUS_OK; + enum XML_Error result = XML_STATUS_OK; + + if (parsing != XML_SUSPENDED) { + errorCode = XML_ERROR_NOT_SUSPENDED; + return XML_STATUS_ERROR; + } + parsing = XML_PARSING; + + errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); + + if (errorCode != XML_ERROR_NONE) { + eventEndPtr = eventPtr; + processor = errorProcessor; + return XML_STATUS_ERROR; + } + else { + switch (parsing) { + case XML_SUSPENDED: + result = XML_STATUS_SUSPENDED; + break; + case XML_INITIALIZED: + case XML_PARSING: + if (finalBuffer) { + parsing = XML_FINISHED; + return result; + } + default: ; + } + } + + XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); + positionPtr = bufferPtr; + eventPtr = bufferPtr; + eventEndPtr = bufferPtr; + return result; +} + +void XMLCALL +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) +{ + assert(status != NULL); + *status = parser->m_parsingStatus; } -/* END MOZILLA CHANGE */ enum XML_Error XMLCALL XML_GetErrorCode(XML_Parser parser) @@ -1711,7 +1846,7 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size) int XMLCALL XML_GetCurrentLineNumber(XML_Parser parser) { - if (eventPtr) { + if (eventPtr && eventPtr >= positionPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; } @@ -1721,7 +1856,7 @@ XML_GetCurrentLineNumber(XML_Parser parser) int XMLCALL XML_GetCurrentColumnNumber(XML_Parser parser) { - if (eventPtr) { + if (eventPtr && eventPtr >= positionPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; } @@ -1801,7 +1936,17 @@ XML_ErrorString(enum XML_Error code) XML_L("entity declared in parameter entity"), XML_L("requested feature requires XML_DTD support in Expat"), XML_L("cannot change setting once parsing has begun"), - XML_L("unbound prefix") + XML_L("unbound prefix"), + XML_L("must not undeclare prefix"), + XML_L("incomplete markup in parameter entity"), + XML_L("XML declaration not well-formed"), + XML_L("text declaration not well-formed"), + XML_L("illegal character(s) in public id"), + XML_L("parser suspended"), + XML_L("parser not suspended"), + XML_L("parsing aborted"), + XML_L("parsing finished"), + XML_L("cannot suspend in external parameter entity") }; if (code > 0 && code < sizeof(message)/sizeof(message[0])) return message[code]; @@ -1938,12 +2083,12 @@ contentProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = - doContent(parser, 0, encoding, start, end, endPtr); - if (result != XML_ERROR_NONE) - return result; - if (!storeRawNames(parser)) - return XML_ERROR_NO_MEMORY; + enum XML_Error result = doContent(parser, 0, encoding, start, end, + endPtr, (XML_Bool)!finalBuffer); + if (result == XML_ERROR_NONE) { + if (!storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } return result; } @@ -1975,21 +2120,21 @@ externalEntityInitProcessor2(XML_Parser parser, doContent (by detecting XML_TOK_NONE) without processing any xml text declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. */ - if (next == end && endPtr) { + if (next == end && !finalBuffer) { *endPtr = next; return XML_ERROR_NONE; } start = next; break; case XML_TOK_PARTIAL: - if (endPtr) { + if (!finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (endPtr) { + if (!finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } @@ -2006,30 +2151,41 @@ externalEntityInitProcessor3(XML_Parser parser, const char *end, const char **endPtr) { + int tok; const char *next = start; /* XmlContentTok doesn't always set the last arg */ - int tok = XmlContentTok(encoding, start, end, &next); + eventPtr = start; + tok = XmlContentTok(encoding, start, end, &next); + eventEndPtr = next; + switch (tok) { case XML_TOK_XML_DECL: { - enum XML_Error result = processXmlDecl(parser, 1, start, next); + enum XML_Error result; + result = processXmlDecl(parser, 1, start, next); if (result != XML_ERROR_NONE) return result; - start = next; + switch (parsing) { + case XML_SUSPENDED: + *endPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: + start = next; + } } break; case XML_TOK_PARTIAL: - if (endPtr) { + if (!finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } - eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (endPtr) { + if (!finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } - eventPtr = start; return XML_ERROR_PARTIAL_CHAR; } processor = externalEntityContentProcessor; @@ -2043,12 +2199,12 @@ externalEntityContentProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = - doContent(parser, 1, encoding, start, end, endPtr); - if (result != XML_ERROR_NONE) - return result; - if (!storeRawNames(parser)) - return XML_ERROR_NO_MEMORY; + enum XML_Error result = doContent(parser, 1, encoding, start, end, + endPtr, (XML_Bool)!finalBuffer); + if (result == XML_ERROR_NONE) { + if (!storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } return result; } @@ -2058,9 +2214,12 @@ doContent(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, - const char **nextPtr) + const char **nextPtr, + XML_Bool haveMore) { - DTD * const dtd = _dtd; /* save one level of indirection */ + /* save one level of indirection */ + DTD * const dtd = _dtd; + const char **eventPP; const char **eventEndPP; if (enc == encoding) { @@ -2072,13 +2231,14 @@ doContent(XML_Parser parser, eventEndPP = &(openInternalEntities->internalEventEndPtr); } *eventPP = s; + for (;;) { const char *next = s; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { case XML_TOK_TRAILING_CR: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } @@ -2089,19 +2249,24 @@ 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? + */ if (startTagLevel == 0) return XML_ERROR_NO_ELEMENTS; if (tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; + *nextPtr = end; return XML_ERROR_NONE; case XML_TOK_NONE: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } if (startTagLevel > 0) { if (tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; + *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_NO_ELEMENTS; @@ -2109,13 +2274,13 @@ doContent(XML_Parser parser, *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } @@ -2170,7 +2335,6 @@ doContent(XML_Parser parser, return XML_ERROR_BINARY_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; - OPEN_INTERNAL_ENTITY openEntity; if (!defaultExpandInternalEntities) { if (skippedEntityHandler) skippedEntityHandler(handlerArg, entity->name, 0); @@ -2178,21 +2342,8 @@ doContent(XML_Parser parser, reportDefault(parser, enc, s, next); break; } - entity->open = XML_TRUE; - openEntity.next = openInternalEntities; - openInternalEntities = &openEntity; - openEntity.entity = entity; - openEntity.internalEventPtr = NULL; - openEntity.internalEventEndPtr = NULL; - result = doContent(parser, - tagLevel, - internalEncoding, - (char *)entity->textPtr, - (char *)(entity->textPtr + entity->textLen), - 0); - entity->open = XML_FALSE; - openInternalEntities = openEntity.next; - if (result) + result = processInternalEntity(parser, entity, XML_FALSE); + if (result != XML_ERROR_NONE) return result; } else if (externalEntityRefHandler) { @@ -2202,7 +2353,7 @@ doContent(XML_Parser parser, entity->open = XML_FALSE; if (!context) return XML_ERROR_NO_MEMORY; - if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg, + if (!externalEntityRefHandler(externalEntityRefHandlerArg, context, entity->base, entity->systemId, @@ -2281,11 +2432,6 @@ doContent(XML_Parser parser, else if (defaultHandler) reportDefault(parser, enc, s, next); poolClear(&tempPool); -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (blocked) { - return XML_ERROR_SUSPENDED; - } -/* END MOZILLA CHANGE */ break; } case XML_TOK_EMPTY_ELEMENT_NO_ATTS: @@ -2308,11 +2454,6 @@ doContent(XML_Parser parser, poolFinish(&tempPool); if (startElementHandler) { startElementHandler(handlerArg, name.str, (const XML_Char **)atts); -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (blocked) { - return XML_ERROR_SUSPENDED; - } -/* END MOZILLA CHANGE */ noElmHandlers = XML_FALSE; } if (endElementHandler) { @@ -2333,11 +2474,6 @@ doContent(XML_Parser parser, freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (blocked) { - return XML_ERROR_SUSPENDED; - } -/* END MOZILLA CHANGE */ } if (tagLevel == 0) return epilogProcessor(parser, next, end, nextPtr); @@ -2416,12 +2552,6 @@ doContent(XML_Parser parser, freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (blocked) { - *eventPP = s = next; /* fix bug 119727 */ - return XML_ERROR_SUSPENDED; - } -/* END MOZILLA CHANGE */ if (tagLevel == 0) return epilogProcessor(parser, next, end, nextPtr); } @@ -2472,15 +2602,17 @@ doContent(XML_Parser parser, #endif else if (defaultHandler) reportDefault(parser, enc, s, next); - result = doCdataSection(parser, enc, &next, end, nextPtr); - if (!next) { + result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); + if (result != XML_ERROR_NONE) + return result; + else if (!next) { processor = cdataSectionProcessor; return result; } } break; case XML_TOK_TRAILING_RSQB: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } @@ -2498,6 +2630,9 @@ 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? + */ if (startTagLevel == 0) { *eventPP = end; return XML_ERROR_NO_ELEMENTS; @@ -2506,6 +2641,7 @@ doContent(XML_Parser parser, *eventPP = end; return XML_ERROR_ASYNC_ENTITY; } + *nextPtr = end; return XML_ERROR_NONE; case XML_TOK_DATA_CHARS: if (characterDataHandler) { @@ -2543,6 +2679,14 @@ doContent(XML_Parser parser, break; } *eventPP = s = next; + switch (parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: ; + } } /* not reached */ } @@ -3000,9 +3144,9 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, BINDING *b; int len; - /* empty string is only valid when there is no prefix per XML NS 1.0 */ + /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ if (*uri == XML_T('\0') && prefix->name) - return XML_ERROR_SYNTAX; + return XML_ERROR_UNDECLARING_PREFIX; /* BEGIN MOZILLA CHANGE (backport of bug fix from Expat trunk) */ if (prefix->name @@ -3078,7 +3222,8 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, prefix->binding = b; b->nextTagBinding = *bindingsPtr; *bindingsPtr = b; - if (startNamespaceDeclHandler) + /* if attId == NULL then we are not starting a namespace scope */ + if (attId && startNamespaceDeclHandler) startNamespaceDeclHandler(handlerArg, prefix->name, prefix->binding ? uri : 0); return XML_ERROR_NONE; @@ -3093,8 +3238,10 @@ cdataSectionProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = doCdataSection(parser, encoding, &start, - end, endPtr); + enum XML_Error result = doCdataSection(parser, encoding, &start, end, + endPtr, (XML_Bool)!finalBuffer); + if (result != XML_ERROR_NONE) + return result; if (start) { if (parentParser) { /* we are parsing an external entity */ processor = externalEntityContentProcessor; @@ -3108,7 +3255,7 @@ cdataSectionProcessor(XML_Parser parser, return result; } -/* startPtr gets set to non-null is the section is closed, and to null if +/* startPtr gets set to non-null if the section is closed, and to null if the section is not yet closed. */ static enum XML_Error @@ -3116,7 +3263,8 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, - const char **nextPtr) + const char **nextPtr, + XML_Bool haveMore) { const char *s = *startPtr; const char **eventPP; @@ -3132,6 +3280,7 @@ doCdataSection(XML_Parser parser, } *eventPP = s; *startPtr = NULL; + for (;;) { const char *next; int tok = XmlCdataSectionTok(enc, s, end, &next); @@ -3148,7 +3297,11 @@ doCdataSection(XML_Parser parser, else if (defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; - return XML_ERROR_NONE; + *nextPtr = next; + if (parsing == XML_FINISHED) + return XML_ERROR_ABORTED; + else + return XML_ERROR_NONE; case XML_TOK_DATA_NEWLINE: if (characterDataHandler) { XML_Char c = 0xA; @@ -3183,14 +3336,14 @@ doCdataSection(XML_Parser parser, *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_PARTIAL: case XML_TOK_NONE: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } @@ -3199,7 +3352,16 @@ doCdataSection(XML_Parser parser, *eventPP = next; return XML_ERROR_UNEXPECTED_STATE; } + *eventPP = s = next; + switch (parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: ; + } } /* not reached */ } @@ -3215,8 +3377,10 @@ ignoreSectionProcessor(XML_Parser parser, const char *end, const char **endPtr) { - enum XML_Error result = doIgnoreSection(parser, encoding, &start, - end, endPtr); + enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, + endPtr, (XML_Bool)!finalBuffer); + if (result != XML_ERROR_NONE) + return result; if (start) { processor = prologProcessor; return prologProcessor(parser, start, end, endPtr); @@ -3232,7 +3396,8 @@ doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, - const char **nextPtr) + const char **nextPtr, + XML_Bool haveMore) { const char *next; int tok; @@ -3257,19 +3422,23 @@ doIgnoreSection(XML_Parser parser, if (defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; - return XML_ERROR_NONE; + *nextPtr = next; + if (parsing == XML_FINISHED) + return XML_ERROR_ABORTED; + else + return XML_ERROR_NONE; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_PARTIAL: case XML_TOK_NONE: - if (nextPtr) { + if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } @@ -3334,8 +3503,12 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, &versionend, &encodingName, &newEncoding, - &standalone)) - return XML_ERROR_SYNTAX; + &standalone)) { + if (isGeneralTextEntity) + return XML_ERROR_TEXT_DECL; + else + return XML_ERROR_XML_DECL; + } if (!isGeneralTextEntity && standalone == 1) { _dtd->standalone = XML_TRUE; #ifdef XML_DTD @@ -3481,35 +3654,47 @@ entityValueInitProcessor(XML_Parser parser, const char *end, const char **nextPtr) { - const char *start = s; - const char *next = s; int tok; + const char *start = s; + const char *next = start; + eventPtr = start; - for (;;) { + for (;;) { tok = XmlPrologTok(encoding, start, end, &next); + eventEndPtr = next; if (tok <= 0) { - if (nextPtr != 0 && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; + if (!finalBuffer && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; + return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; + return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; + return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } + /* found end of entity value - can store it now */ return storeEntityValue(parser, encoding, s, end); } else if (tok == XML_TOK_XML_DECL) { - enum XML_Error result = processXmlDecl(parser, 0, start, next); - if (result != XML_ERROR_NONE) - return result; - if (nextPtr) *nextPtr = next; + enum XML_Error result; + result = processXmlDecl(parser, 0, start, next); + if (result != XML_ERROR_NONE) + return result; + switch (parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: + *nextPtr = next; + } /* stop scanning for text declaration - we found one */ processor = entityValueProcessor; return entityValueProcessor(parser, next, end, nextPtr); @@ -3521,11 +3706,12 @@ entityValueInitProcessor(XML_Parser parser, then, when this routine is entered the next time, XmlPrologTok will return XML_TOK_INVALID, since the BOM is still in the buffer */ - else if (tok == XML_TOK_BOM && next == end && nextPtr) { + else if (tok == XML_TOK_BOM && next == end && !finalBuffer) { *nextPtr = next; return XML_ERROR_NONE; } start = next; + eventPtr = start; } } @@ -3535,13 +3721,12 @@ externalParEntProcessor(XML_Parser parser, const char *end, const char **nextPtr) { - const char *start = s; const char *next = s; int tok; - tok = XmlPrologTok(encoding, start, end, &next); + tok = XmlPrologTok(encoding, s, end, &next); if (tok <= 0) { - if (nextPtr != 0 && tok != XML_TOK_INVALID) { + if (!finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -3567,7 +3752,8 @@ externalParEntProcessor(XML_Parser parser, } processor = prologProcessor; - return doProlog(parser, encoding, s, end, tok, next, nextPtr); + return doProlog(parser, encoding, s, end, tok, next, + nextPtr, (XML_Bool)!finalBuffer); } static enum XML_Error PTRCALL @@ -3584,21 +3770,22 @@ entityValueProcessor(XML_Parser parser, for (;;) { tok = XmlPrologTok(enc, start, end, &next); if (tok <= 0) { - if (nextPtr != 0 && tok != XML_TOK_INVALID) { + if (!finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; + return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; + return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; + return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } + /* found end of entity value - can store it now */ return storeEntityValue(parser, enc, s, end); } start = next; @@ -3615,7 +3802,8 @@ prologProcessor(XML_Parser parser, { const char *next = s; int 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)!finalBuffer); } static enum XML_Error @@ -3625,7 +3813,8 @@ doProlog(XML_Parser parser, const char *end, int tok, const char *next, - const char **nextPtr) + const char **nextPtr, + XML_Bool haveMore) { #ifdef XML_DTD static const XML_Char externalSubsetName[] = { '#' , '\0' }; @@ -3646,7 +3835,8 @@ doProlog(XML_Parser parser, static const XML_Char enumValueSep[] = { '|', '\0' }; static const XML_Char enumValueStart[] = { '(', '\0' }; - DTD * const dtd = _dtd; /* save one level of indirection */ + /* save one level of indirection */ + DTD * const dtd = _dtd; const char **eventPP; const char **eventEndPP; @@ -3660,13 +3850,14 @@ doProlog(XML_Parser parser, eventPP = &(openInternalEntities->internalEventPtr); eventEndPP = &(openInternalEntities->internalEventEndPtr); } + for (;;) { int role; XML_Bool handleDefault = XML_TRUE; *eventPP = s; *eventEndPP = next; if (tok <= 0) { - if (nextPtr != 0 && tok != XML_TOK_INVALID) { + if (haveMore && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } @@ -3680,12 +3871,20 @@ doProlog(XML_Parser parser, return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: #ifdef XML_DTD - if (enc != encoding) + /* for internal PE NOT referenced between declarations */ + if (enc != encoding && !openInternalEntities->betweenDecl) { + *nextPtr = s; return XML_ERROR_NONE; - if (isParamEntity) { + } + /* WFC: PE Between Declarations - must check that PE contains + complete markup, not only for external PEs, but also for + internal PEs if the reference occurs between declarations. + */ + if (isParamEntity || enc != encoding) { if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) == XML_ROLE_ERROR) - return XML_ERROR_SYNTAX; + return XML_ERROR_INCOMPLETE_PE; + *nextPtr = s; return XML_ERROR_NONE; } #endif /* XML_DTD */ @@ -3741,28 +3940,31 @@ doProlog(XML_Parser parser, case XML_ROLE_DOCTYPE_PUBLIC_ID: #ifdef XML_DTD useForeignDTD = XML_FALSE; -#endif /* XML_DTD */ - dtd->hasParamEntityRefs = XML_TRUE; - if (startDoctypeDeclHandler) { - doctypePubid = poolStoreString(&tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!doctypePubid) - return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - handleDefault = XML_FALSE; - } -#ifdef XML_DTD declEntity = (ENTITY *)lookup(&dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (!declEntity) return XML_ERROR_NO_MEMORY; #endif /* XML_DTD */ + dtd->hasParamEntityRefs = XML_TRUE; + if (startDoctypeDeclHandler) { + if (!XmlIsPublicId(enc, s, next, eventPP)) + return XML_ERROR_PUBLICID; + doctypePubid = poolStoreString(&tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!doctypePubid) + return XML_ERROR_NO_MEMORY; + normalizePublicId((XML_Char *)doctypePubid); + poolFinish(&tempPool); + handleDefault = XML_FALSE; + goto alreadyChecked; + } /* fall through */ case XML_ROLE_ENTITY_PUBLIC_ID: if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_SYNTAX; + return XML_ERROR_PUBLICID; + alreadyChecked: if (dtd->keepProcessing && declEntity) { XML_Char *tem = poolStoreString(&dtd->pool, enc, @@ -4185,7 +4387,7 @@ doProlog(XML_Parser parser, break; case XML_ROLE_NOTATION_PUBLIC_ID: if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_SYNTAX; + return XML_ERROR_PUBLICID; if (declNotationName) { /* means notationDeclHandler != NULL */ XML_Char *tem = poolStoreString(&tempPool, enc, @@ -4232,6 +4434,8 @@ doProlog(XML_Parser parser, case XML_ROLE_ERROR: switch (tok) { case XML_TOK_PARAM_ENTITY_REF: + /* PE references in internal subset are + not allowed within declarations. */ return XML_ERROR_PARAM_ENTITY_REF; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; @@ -4245,8 +4449,10 @@ doProlog(XML_Parser parser, if (defaultHandler) reportDefault(parser, enc, s, next); handleDefault = XML_FALSE; - result = doIgnoreSection(parser, enc, &next, end, nextPtr); - if (!next) { + result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); + if (result != XML_ERROR_NONE) + return result; + else if (!next) { processor = ignoreSectionProcessor; return result; } @@ -4311,11 +4517,6 @@ doProlog(XML_Parser parser, case XML_ROLE_PARAM_ENTITY_REF: #ifdef XML_DTD case XML_ROLE_INNER_PARAM_ENTITY_REF: - /* PE references in internal subset are - not allowed within declarations */ - if (prologState.documentEntity && - role == XML_ROLE_INNER_PARAM_ENTITY_REF) - return XML_ERROR_PARAM_ENTITY_REF; dtd->hasParamEntityRefs = XML_TRUE; if (!paramEntityParsing) dtd->keepProcessing = dtd->standalone; @@ -4355,7 +4556,9 @@ doProlog(XML_Parser parser, return XML_ERROR_RECURSIVE_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; - result = processInternalParamEntity(parser, entity); + XML_Bool betweenDecl = + (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); + result = processInternalEntity(parser, entity, betweenDecl); if (result != XML_ERROR_NONE) return result; handleDefault = XML_FALSE; @@ -4512,20 +4715,8 @@ doProlog(XML_Parser parser, /* End element declaration stuff */ case XML_ROLE_PI: -/* BEGIN MOZILLA CHANGE (Blocking parser) */ -#if 0 if (!reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; -#else - if (!reportProcessingInstruction(parser, enc, s, next)) { - if (blocked) { - eventPtr = next; - return XML_ERROR_SUSPENDED; - } - return XML_ERROR_NO_MEMORY; - } -#endif -/* END MOZILLA CHANGE */ handleDefault = XML_FALSE; break; case XML_ROLE_COMMENT: @@ -4565,8 +4756,16 @@ doProlog(XML_Parser parser, if (handleDefault && defaultHandler) reportDefault(parser, enc, s, next); - s = next; - tok = XmlPrologTok(enc, s, end, &next); + switch (parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: + s = next; + tok = XmlPrologTok(enc, s, end, &next); + } } /* not reached */ } @@ -4587,15 +4786,14 @@ epilogProcessor(XML_Parser parser, /* report partial linebreak - it might be the last token */ case -XML_TOK_PROLOG_S: if (defaultHandler) { - eventEndPtr = next; reportDefault(parser, encoding, s, next); + if (parsing == XML_FINISHED) + return XML_ERROR_ABORTED; } - if (nextPtr) - *nextPtr = next; + *nextPtr = next; return XML_ERROR_NONE; case XML_TOK_NONE: - if (nextPtr) - *nextPtr = s; + *nextPtr = s; return XML_ERROR_NONE; case XML_TOK_PROLOG_S: if (defaultHandler) @@ -4613,13 +4811,13 @@ epilogProcessor(XML_Parser parser, eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: - if (nextPtr) { + if (!finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { + if (!finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } @@ -4628,34 +4826,134 @@ epilogProcessor(XML_Parser parser, return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; } eventPtr = s = next; + switch (parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: ; + } } } -#ifdef XML_DTD - static enum XML_Error -processInternalParamEntity(XML_Parser parser, ENTITY *entity) +processInternalEntity(XML_Parser parser, ENTITY *entity, + XML_Bool betweenDecl) { - const char *s, *end, *next; - int tok; + const char *textStart, *textEnd; + const char *next; enum XML_Error result; - OPEN_INTERNAL_ENTITY openEntity; + OPEN_INTERNAL_ENTITY *openEntity; + + if (freeInternalEntities) { + openEntity = freeInternalEntities; + freeInternalEntities = openEntity->next; + } + else { + openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY)); + if (!openEntity) + return XML_ERROR_NO_MEMORY; + } entity->open = XML_TRUE; - openEntity.next = openInternalEntities; - openInternalEntities = &openEntity; - openEntity.entity = entity; - openEntity.internalEventPtr = NULL; - openEntity.internalEventEndPtr = NULL; - s = (char *)entity->textPtr; - end = (char *)(entity->textPtr + entity->textLen); - tok = XmlPrologTok(internalEncoding, s, end, &next); - result = doProlog(parser, internalEncoding, s, end, tok, next, 0); - entity->open = XML_FALSE; - openInternalEntities = openEntity.next; + entity->processed = 0; + openEntity->next = openInternalEntities; + openInternalEntities = openEntity; + openEntity->entity = entity; + openEntity->startTagLevel = tagLevel; + openEntity->betweenDecl = betweenDecl; + openEntity->internalEventPtr = NULL; + openEntity->internalEventEndPtr = NULL; + textStart = (char *)entity->textPtr; + textEnd = (char *)(entity->textPtr + entity->textLen); + +#ifdef XML_DTD + if (entity->is_param) { + int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, internalEncoding, textStart, textEnd, tok, + next, &next, XML_FALSE); + } + else +#endif /* XML_DTD */ + result = doContent(parser, tagLevel, internalEncoding, textStart, + textEnd, &next, XML_FALSE); + + if (result == XML_ERROR_NONE) { + if (textEnd != next && parsing == XML_SUSPENDED) { + entity->processed = next - textStart; + processor = internalEntityProcessor; + } + else { + entity->open = XML_FALSE; + openInternalEntities = openEntity->next; + /* put openEntity back in list of free instances */ + openEntity->next = freeInternalEntities; + freeInternalEntities = openEntity; + } + } return result; } +static enum XML_Error PTRCALL +internalEntityProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + ENTITY *entity; + const char *textStart, *textEnd; + const char *next; + enum XML_Error result; + OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; + if (!openEntity) + return XML_ERROR_UNEXPECTED_STATE; + + entity = openEntity->entity; + textStart = ((char *)entity->textPtr) + entity->processed; + textEnd = (char *)(entity->textPtr + entity->textLen); + +#ifdef XML_DTD + if (entity->is_param) { + int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); + 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); + + if (result != XML_ERROR_NONE) + return result; + else if (textEnd != next && parsing == XML_SUSPENDED) { + entity->processed = next - (char *)entity->textPtr; + return result; + } + else { + entity->open = XML_FALSE; + openInternalEntities = openEntity->next; + /* put openEntity back in list of free instances */ + openEntity->next = freeInternalEntities; + freeInternalEntities = openEntity; + } + +#ifdef XML_DTD + if (entity->is_param) { + int tok; + processor = prologProcessor; + tok = XmlPrologTok(encoding, s, end, &next); + return doProlog(parser, encoding, s, end, tok, next, nextPtr, + (XML_Bool)!finalBuffer); + } + else +#endif /* XML_DTD */ + { + processor = contentProcessor; + /* see externalEntityContentProcessor vs contentProcessor */ + return doContent(parser, parentParser ? 1 : 0, encoding, s, end, + nextPtr, (XML_Bool)!finalBuffer); + } +} static enum XML_Error PTRCALL errorProcessor(XML_Parser parser, @@ -4925,8 +5223,8 @@ storeEntityValue(XML_Parser parser, break; } #endif /* XML_DTD */ - /* in the internal subset, PE references are not legal - within markup declarations, e.g entity values in this case */ + /* In the internal subset, PE references are not legal + within markup declarations, e.g entity values in this case. */ eventPtr = entityTextPtr; result = XML_ERROR_PARAM_ENTITY_REF; goto endEntityValue; @@ -5051,11 +5349,6 @@ reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, normalizeLines(data); processingInstructionHandler(handlerArg, target, data); poolClear(&tempPool); -/* BEGIN MOZILLA CHANGE (Blocking parser) */ - if (blocked) { - return 0; - } -/* END MOZILLA CHANGE */ return 1; } @@ -5359,7 +5652,7 @@ setContext(XML_Parser parser, const XML_Char *context) return XML_FALSE; if (!poolAppendChar(&tempPool, XML_T('\0'))) return XML_FALSE; - if (addBinding(parser, prefix, 0, poolStart(&tempPool), + if (addBinding(parser, prefix, NULL, poolStart(&tempPool), &inheritedBindings) != XML_ERROR_NONE) return XML_FALSE; poolDiscard(&tempPool); @@ -5405,9 +5698,7 @@ dtdCreate(const XML_Memory_Handling_Suite *ms) if (p == NULL) return p; poolInit(&(p->pool), ms); -#ifdef XML_DTD poolInit(&(p->entityValuePool), ms); -#endif /* XML_DTD */ hashTableInit(&(p->generalEntities), ms); hashTableInit(&(p->elementTypes), ms); hashTableInit(&(p->attributeIds), ms); @@ -5454,9 +5745,7 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) hashTableClear(&(p->attributeIds)); hashTableClear(&(p->prefixes)); poolClear(&(p->pool)); -#ifdef XML_DTD poolClear(&(p->entityValuePool)); -#endif /* XML_DTD */ p->defaultPrefix.name = NULL; p->defaultPrefix.binding = NULL; @@ -5497,9 +5786,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) hashTableDestroy(&(p->attributeIds)); hashTableDestroy(&(p->prefixes)); poolDestroy(&(p->pool)); -#ifdef XML_DTD poolDestroy(&(p->entityValuePool)); -#endif /* XML_DTD */ if (isDocEntity) { ms->free_fcn(p->scaffIndex); ms->free_fcn(p->scaffold); @@ -5739,8 +6026,10 @@ lookup(HASH_TABLE *table, KEY name, size_t createSize) table->size = (size_t)1 << INIT_POWER; tsize = table->size * sizeof(NAMED *); table->v = (NAMED **)table->mem->malloc_fcn(tsize); - if (!table->v) + if (!table->v) { + table->size = 0; return NULL; + } memset(table->v, 0, tsize); i = hash(name) & ((unsigned long)table->size - 1); } diff --git a/mozilla/parser/expat/lib/xmlrole.c b/mozilla/parser/expat/lib/xmlrole.c index 83c0d71f28e..1924fcb4dbe 100644 --- a/mozilla/parser/expat/lib/xmlrole.c +++ b/mozilla/parser/expat/lib/xmlrole.c @@ -2,6 +2,8 @@ See the file COPYING for copying permission. */ +#include + #ifdef COMPILED_FROM_DSP #include "winconfig.h" #elif defined(MACOS_CLASSIC) @@ -12,6 +14,7 @@ #endif #endif /* ndef COMPILED_FROM_DSP */ +#include "expat_external.h" #include "internal.h" #include "xmlrole.h" #include "ascii.h" @@ -370,6 +373,8 @@ internalSubset(PROLOG_STATE *state, case XML_TOK_CLOSE_BRACKET: state->handler = doctype5; return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_NONE: + return XML_ROLE_NONE; } return common(state, tok); } diff --git a/mozilla/parser/expat/lib/xmltok.c b/mozilla/parser/expat/lib/xmltok.c index 6cb18483694..0fcfbe16d62 100644 --- a/mozilla/parser/expat/lib/xmltok.c +++ b/mozilla/parser/expat/lib/xmltok.c @@ -2,6 +2,8 @@ See the file COPYING for copying permission. */ +#include + #ifdef COMPILED_FROM_DSP #include "winconfig.h" #elif defined(MACOS_CLASSIC) @@ -12,6 +14,7 @@ #endif #endif /* ndef COMPILED_FROM_DSP */ +#include "expat_external.h" #include "internal.h" #include "xmltok.h" #include "nametab.h" @@ -1246,7 +1249,7 @@ XmlUtf16Encode(int charNum, unsigned short *buf) struct unknown_encoding { struct normal_encoding normal; - int (*convert)(void *userData, const char *p); + CONVERTER convert; void *userData; unsigned short utf16[256]; char utf8[256][4]; diff --git a/mozilla/parser/expat/lib/xmltok.h b/mozilla/parser/expat/lib/xmltok.h index 3d776be71fc..1ecd05f8862 100644 --- a/mozilla/parser/expat/lib/xmltok.h +++ b/mozilla/parser/expat/lib/xmltok.h @@ -281,7 +281,8 @@ int FASTCALL XmlUtf8Encode(int charNumber, char *buf); int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); int XmlSizeOfUnknownEncoding(void); -typedef int (*CONVERTER)(void *userData, const char *p); + +typedef int (XMLCALL *CONVERTER) (void *userData, const char *p); ENCODING * XmlInitUnknownEncoding(void *mem, diff --git a/mozilla/parser/htmlparser/src/nsExpatDriver.cpp b/mozilla/parser/htmlparser/src/nsExpatDriver.cpp index 35a706843da..b9971ddb25a 100644 --- a/mozilla/parser/htmlparser/src/nsExpatDriver.cpp +++ b/mozilla/parser/htmlparser/src/nsExpatDriver.cpp @@ -386,7 +386,7 @@ nsExpatDriver::HandleEndElement(const PRUnichar *aValue) if (mSink && mSink->HandleEndElement(aValue) == NS_ERROR_HTMLPARSER_BLOCK) { mInternalState = NS_ERROR_HTMLPARSER_BLOCK; - MOZ_XML_StopParser(mExpatParser, XML_TRUE); + XML_StopParser(mExpatParser, XML_TRUE); } return NS_OK; @@ -453,7 +453,7 @@ nsExpatDriver::HandleProcessingInstruction(const PRUnichar *aTarget, mSink->HandleProcessingInstruction(aTarget, aData) == NS_ERROR_HTMLPARSER_BLOCK) { mInternalState = NS_ERROR_HTMLPARSER_BLOCK; - MOZ_XML_StopParser(mExpatParser, XML_TRUE); + XML_StopParser(mExpatParser, XML_TRUE); } return NS_OK; @@ -573,10 +573,9 @@ ExternalDTDStreamReaderFunc(nsIUnicharInputStream* aIn, PRUint32 aCount, PRUint32 *aWriteCount) { - // Pass the buffer to expat for parsing. XML_Parse returns 0 for - // fatal errors. + // Pass the buffer to expat for parsing. if (XML_Parse((XML_Parser)aClosure, (const char *)aFromSegment, - aCount * sizeof(PRUnichar), 0)) { + aCount * sizeof(PRUnichar), 0) == XML_STATUS_OK) { *aWriteCount = aCount; return NS_OK; @@ -848,8 +847,16 @@ nsExpatDriver::ParseBuffer(const char* aBuffer, XML_GetCurrentByteIndex(mExpatParser) % sizeof(PRUnichar) == 0, "Consumed part of a PRUnichar?"); - if (mExpatParser && mInternalState == NS_OK) { - XML_Bool parsedAll = XML_Parse(mExpatParser, aBuffer, aLength, aIsFinal); + if (mExpatParser && (mInternalState == NS_OK || + mInternalState == NS_ERROR_HTMLPARSER_BLOCK)) { + XML_Status status; + if (mInternalState == NS_ERROR_HTMLPARSER_BLOCK) { + mInternalState = NS_OK; // Resume in case we're blocked. + status = XML_ResumeParser(mExpatParser); + } + else { + status = XML_Parse(mExpatParser, aBuffer, aLength, aIsFinal); + } PRInt32 parserBytesConsumed = XML_GetCurrentByteIndex(mExpatParser); @@ -863,8 +870,10 @@ nsExpatDriver::ParseBuffer(const char* aBuffer, const PRUnichar* const buffer = NS_REINTERPRET_CAST(const PRUnichar*, aBuffer); PRUint32 startOffset; - // we assume that if expat failed to consume some bytes last time it won't - // consume them this time without also consuming some bytes from aBuffer. + // If expat failed to consume some bytes last time it won't consume them + // this time without also consuming some bytes from aBuffer. Note that when + // resuming after suspending the parser, aBuffer will contain the data that + // Expat also has in its internal buffer. // Note that if expat consumed everything we passed it, it will have nulled // out all its internal pointers to data, so parserBytesConsumed will come // out -1 in that case. @@ -905,46 +914,44 @@ nsExpatDriver::ParseBuffer(const char* aBuffer, } } - if (!parsedAll) { - if (mInternalState == NS_ERROR_HTMLPARSER_BLOCK || - mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING) { - NS_ASSERTION((PRUint32)parserBytesConsumed >= mBytesParsed, - "How'd this happen?"); - mBytePosition = parserBytesConsumed - mBytesParsed; - mBytesParsed = parserBytesConsumed; - if (buffer) { - PRUint32 endOffset = mBytePosition / sizeof(PRUnichar); - NS_ASSERTION(startOffset <= endOffset, - "Something is confused about what we've consumed"); - // Only append the data we actually parsed. The rest will come - // through this method again. - mLastLine.Append(Substring(buffer + startOffset, - buffer + endOffset)); - } - } - else { - // An error occured, look for the next newline after the last one we - // consumed. - PRUint32 length = aLength / sizeof(PRUnichar); - if (buffer) { - PRUint32 endOffset = startOffset; - while (endOffset < length && buffer[endOffset] != '\n' && - buffer[endOffset] != '\r') { - ++endOffset; - } - mLastLine.Append(Substring(buffer + startOffset, - buffer + endOffset)); - } - HandleError(); - mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING; + if (status == XML_STATUS_SUSPENDED) { + NS_ASSERTION(mInternalState == NS_ERROR_HTMLPARSER_BLOCK, + "mInternalState out of sync!"); + NS_ASSERTION((PRUint32)parserBytesConsumed >= mBytesParsed, + "How'd this happen?"); + mBytePosition = parserBytesConsumed - mBytesParsed; + mBytesParsed = parserBytesConsumed; + if (buffer) { + PRUint32 endOffset = mBytePosition / sizeof(PRUnichar); + NS_ASSERTION(startOffset <= endOffset, + "Something is confused about what we've consumed"); + // Only append the data we actually parsed. The rest will come + // through this method again. + mLastLine.Append(Substring(buffer + startOffset, buffer + endOffset)); } return mInternalState; } + PRUint32 length = aLength / sizeof(PRUnichar); + if (status == XML_STATUS_ERROR) { + // Look for the next newline after the last one we consumed + if (buffer) { + PRUint32 endOffset = startOffset; + while (endOffset < length && buffer[endOffset] != '\n' && + buffer[endOffset] != '\r') { + ++endOffset; + } + mLastLine.Append(Substring(buffer + startOffset, buffer + endOffset)); + } + HandleError(); + mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING; + + return mInternalState; + } + if (!aIsFinal && buffer) { - mLastLine.Append(Substring(buffer + startOffset, - buffer + aLength / sizeof(PRUnichar))); + mLastLine.Append(Substring(buffer + startOffset, buffer + length)); } mBytesParsed += aLength; mBytePosition = 0; @@ -966,9 +973,6 @@ nsExpatDriver::ConsumeToken(nsScanner& aScanner, // Ask the scanner to send us all the data it has // scanned and pass that data to expat. - mInternalState = NS_OK; // Resume in case we're blocked. - MOZ_XML_ResumeParser(mExpatParser); - nsScannerIterator start, end; aScanner.CurrentPosition(start); aScanner.EndReading(end); @@ -978,7 +982,7 @@ nsExpatDriver::ConsumeToken(nsScanner& aScanner, mInternalState = ParseBuffer((const char*)start.get(), fragLength * sizeof(PRUnichar), - aFlushTokens); + PR_FALSE); if (NS_FAILED(mInternalState)) { if (mInternalState == NS_ERROR_HTMLPARSER_BLOCK) { @@ -1128,7 +1132,8 @@ nsExpatDriver::WillInterruptParse(nsIContentSink* aSink) NS_IMETHODIMP nsExpatDriver::DidTokenize(PRBool aIsFinalChunk) { - return ParseBuffer(nsnull, 0, aIsFinalChunk); + return mInternalState == NS_OK ? ParseBuffer(nsnull, 0, aIsFinalChunk) : + NS_OK; } NS_IMETHODIMP_(const nsIID&) @@ -1142,7 +1147,7 @@ nsExpatDriver::Terminate() { // XXX - not sure what happens to the unparsed data. if (mExpatParser) { - MOZ_XML_StopParser(mExpatParser, XML_FALSE); + XML_StopParser(mExpatParser, XML_FALSE); } mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING; }