From fa7df411830343230d3e5c59520cf67676335c42 Mon Sep 17 00:00:00 2001 From: "tao%netscape.com" Date: Fri, 2 Jul 1999 02:32:56 +0000 Subject: [PATCH] Merge James Clark's DTD patch. "ifdefed by XML_DTD". git-svn-id: svn://10.0.0.236/trunk@37938 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/expat/xmlparse/hashtable.c | 14 +- mozilla/expat/xmlparse/hashtable.h | 26 +- mozilla/expat/xmlparse/xmlparse.c | 1034 +++++++++++++++++------- mozilla/expat/xmlparse/xmlparse.h | 88 +- mozilla/expat/xmltok/xmlrole.c | 305 +++++-- mozilla/expat/xmltok/xmlrole.h | 31 +- mozilla/expat/xmltok/xmltok.c | 65 +- mozilla/expat/xmltok/xmltok.h | 53 +- mozilla/expat/xmltok/xmltok_impl.c | 107 ++- mozilla/expat/xmltok/xmltok_ns.c | 10 +- mozilla/parser/expat/lib/hashtable.c | 14 +- mozilla/parser/expat/lib/hashtable.h | 26 +- mozilla/parser/expat/lib/xmlparse.c | 1034 +++++++++++++++++------- mozilla/parser/expat/lib/xmlparse.h | 88 +- mozilla/parser/expat/lib/xmlrole.c | 305 +++++-- mozilla/parser/expat/lib/xmlrole.h | 31 +- mozilla/parser/expat/lib/xmltok.c | 65 +- mozilla/parser/expat/lib/xmltok.h | 53 +- mozilla/parser/expat/lib/xmltok_impl.c | 107 ++- mozilla/parser/expat/lib/xmltok_ns.c | 10 +- 20 files changed, 2508 insertions(+), 958 deletions(-) diff --git a/mozilla/expat/xmlparse/hashtable.c b/mozilla/expat/xmlparse/hashtable.c index e39f82ad10f..780a0610414 100644 --- a/mozilla/expat/xmlparse/hashtable.c +++ b/mozilla/expat/xmlparse/hashtable.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in csompliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" diff --git a/mozilla/expat/xmlparse/hashtable.h b/mozilla/expat/xmlparse/hashtable.h index 63478a0812c..df8ab8a4c83 100644 --- a/mozilla/expat/xmlparse/hashtable.h +++ b/mozilla/expat/xmlparse/hashtable.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,24 +12,38 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include #ifdef XML_UNICODE + #ifdef XML_UNICODE_WCHAR_T typedef const wchar_t *KEY; -#else +#else /* not XML_UNICODE_WCHAR_T */ typedef const unsigned short *KEY; -#endif -#else +#endif /* not XML_UNICODE_WCHAR_T */ + +#else /* not XML_UNICODE */ + typedef const char *KEY; -#endif + +#endif /* not XML_UNICODE */ typedef struct { KEY name; diff --git a/mozilla/expat/xmlparse/xmlparse.c b/mozilla/expat/xmlparse/xmlparse.c index 4eaf7e98c1a..9d629403bc4 100644 --- a/mozilla/expat/xmlparse/xmlparse.c +++ b/mozilla/expat/xmlparse/xmlparse.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" @@ -50,7 +60,6 @@ typedef char ICHAR; #endif - #ifdef XML_UNICODE_WCHAR_T #define XML_T(x) L ## x #else @@ -159,10 +168,9 @@ typedef struct { STRING_POOL pool; int complete; int standalone; - const XML_Char *base; -#ifdef EXTERNAL_ENTITY_SUPPORT - const XML_Char *systemId; -#endif +#ifdef XML_DTD + HASH_TABLE paramEntities; +#endif /* XML_DTD */ PREFIX defaultPrefix; } DTD; @@ -182,6 +190,9 @@ static Processor prologProcessor; static Processor prologInitProcessor; static Processor contentProcessor; static Processor cdataSectionProcessor; +#ifdef XML_DTD +static Processor ignoreSectionProcessor; +#endif /* XML_DTD */ static Processor epilogProcessor; static Processor errorProcessor; static Processor externalEntityInitProcessor; @@ -196,10 +207,19 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const c 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); +static enum XML_Error +processInternalParamEntity(XML_Parser parser, ENTITY *entity); +static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *start, const char *end, const char **endPtr); static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); +#ifdef XML_DTD +static enum XML_Error +doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); +#endif /* XML_DTD */ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); static @@ -216,7 +236,7 @@ static ATTRIBUTE_ID * getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); static enum XML_Error -storeEntityValue(XML_Parser parser, const char *start, const char *end); +storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int @@ -230,6 +250,10 @@ static void normalizePublicId(XML_Char *s); static int dtdInit(DTD *); static void dtdDestroy(DTD *); static int dtdCopy(DTD *newDtd, const DTD *oldDtd); +static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); +#ifdef XML_DTD +static void dtdSwap(DTD *, DTD *); +#endif /* XML_DTD */ static void poolInit(STRING_POOL *); static void poolClear(STRING_POOL *); static void poolDestroy(STRING_POOL *); @@ -255,142 +279,152 @@ static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int typedef struct { /* The first member must be userData so that the XML_GetUserData macro works. */ - void *userData; - void *handlerArg; - char *buffer; + void *m_userData; + void *m_handlerArg; + char *m_buffer; /* first character to be parsed */ - const char *bufferPtr; + const char *m_bufferPtr; /* past last character to be parsed */ - char *bufferEnd; + char *m_bufferEnd; /* allocated end of buffer */ - const char *bufferLim; - long parseEndByteIndex; - const char *parseEndPtr; - XML_Char *dataBuf; - XML_Char *dataBufEnd; - XML_StartElementHandler startElementHandler; - XML_EndElementHandler endElementHandler; - XML_CharacterDataHandler characterDataHandler; - XML_ProcessingInstructionHandler processingInstructionHandler; - XML_CommentHandler commentHandler; -#ifdef EXTERNAL_ENTITY_SUPPORT - XML_ExternalDTDLoader externalDTDLoader; + const char *m_bufferLim; + long m_parseEndByteIndex; + const char *m_parseEndPtr; + XML_Char *m_dataBuf; + XML_Char *m_dataBufEnd; + XML_StartElementHandler m_startElementHandler; + XML_EndElementHandler m_endElementHandler; + XML_CharacterDataHandler m_characterDataHandler; + XML_ProcessingInstructionHandler m_processingInstructionHandler; + XML_CommentHandler m_commentHandler; + XML_StartCdataSectionHandler m_startCdataSectionHandler; + XML_EndCdataSectionHandler m_endCdataSectionHandler; + XML_DefaultHandler m_defaultHandler; + XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; + XML_NotationDeclHandler m_notationDeclHandler; + XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; + XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; + XML_NotStandaloneHandler m_notStandaloneHandler; + XML_ExternalEntityRefHandler m_externalEntityRefHandler; + void *m_externalEntityRefHandlerArg; + XML_UnknownEncodingHandler m_unknownEncodingHandler; + const ENCODING *m_encoding; + INIT_ENCODING m_initEncoding; + const ENCODING *m_internalEncoding; + const XML_Char *m_protocolEncodingName; + int m_ns; + void *m_unknownEncodingMem; + void *m_unknownEncodingData; + void *m_unknownEncodingHandlerData; + void (*m_unknownEncodingRelease)(void *); + PROLOG_STATE m_prologState; + Processor *m_processor; + enum XML_Error m_errorCode; + const char *m_eventPtr; + const char *m_eventEndPtr; + const char *m_positionPtr; + OPEN_INTERNAL_ENTITY *m_openInternalEntities; + int m_defaultExpandInternalEntities; + int m_tagLevel; + ENTITY *m_declEntity; + const XML_Char *m_declNotationName; + const XML_Char *m_declNotationPublicId; + ELEMENT_TYPE *m_declElementType; + ATTRIBUTE_ID *m_declAttributeId; + char m_declAttributeIsCdata; + DTD m_dtd; + const XML_Char *m_curBase; + TAG *m_tagStack; + TAG *m_freeTagList; + BINDING *m_inheritedBindings; + BINDING *m_freeBindingList; + int m_attsSize; + int m_nSpecifiedAtts; + ATTRIBUTE *m_atts; + POSITION m_position; + STRING_POOL m_tempPool; + STRING_POOL m_temp2Pool; + char *m_groupConnector; + unsigned m_groupSize; + int m_hadExternalDoctype; + XML_Char m_namespaceSeparator; +#ifdef XML_DTD + enum XML_ParamEntityParsing m_paramEntityParsing; + XML_Parser m_parentParser; #endif - XML_StartCdataSectionHandler startCdataSectionHandler; - XML_EndCdataSectionHandler endCdataSectionHandler; - XML_DefaultHandler defaultHandler; - XML_UnparsedEntityDeclHandler unparsedEntityDeclHandler; - XML_NotationDeclHandler notationDeclHandler; - XML_StartNamespaceDeclHandler startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler endNamespaceDeclHandler; - XML_ExternalEntityRefHandler externalEntityRefHandler; - void *externalEntityRefHandlerArg; - XML_UnknownEncodingHandler unknownEncodingHandler; - const ENCODING *parserEncoding; - INIT_ENCODING initEncoding; - const XML_Char *protocolEncodingName; - int ns; - void *unknownEncodingMem; - void *unknownEncodingData; - void *unknownEncodingHandlerData; - void (*unknownEncodingRelease)(void *); - PROLOG_STATE prologState; - Processor *processor; - enum XML_Error errorCode; - const char *eventPtr; - const char *eventEndPtr; - const char *positionPtr; - OPEN_INTERNAL_ENTITY *openInternalEntities; - int defaultExpandInternalEntities; - int tagLevel; - ENTITY *declEntity; - const XML_Char *declNotationName; - const XML_Char *declNotationPublicId; - ELEMENT_TYPE *declElementType; - ATTRIBUTE_ID *declAttributeId; - char declAttributeIsCdata; - DTD dtd; - TAG *tagStack; - TAG *freeTagList; - BINDING *inheritedBindings; - BINDING *freeBindingList; - int attsSize; - ATTRIBUTE *atts; - POSITION position; - STRING_POOL tempPool; - STRING_POOL temp2Pool; - char *groupConnector; - unsigned groupSize; - int hadExternalDoctype; - XML_Char namespaceSeparator; } Parser; -#define userData (((Parser *)parser)->userData) -#define handlerArg (((Parser *)parser)->handlerArg) -#define startElementHandler (((Parser *)parser)->startElementHandler) -#define endElementHandler (((Parser *)parser)->endElementHandler) -#define characterDataHandler (((Parser *)parser)->characterDataHandler) -#define processingInstructionHandler (((Parser *)parser)->processingInstructionHandler) -#define commentHandler (((Parser *)parser)->commentHandler) -#ifdef EXTERNAL_ENTITY_SUPPORT -#define externalDTDLoader (((Parser *)parser)->externalDTDLoader) -#endif -#define startCdataSectionHandler (((Parser *)parser)->startCdataSectionHandler) -#define endCdataSectionHandler (((Parser *)parser)->endCdataSectionHandler) -#define defaultHandler (((Parser *)parser)->defaultHandler) -#define unparsedEntityDeclHandler (((Parser *)parser)->unparsedEntityDeclHandler) -#define notationDeclHandler (((Parser *)parser)->notationDeclHandler) -#define startNamespaceDeclHandler (((Parser *)parser)->startNamespaceDeclHandler) -#define endNamespaceDeclHandler (((Parser *)parser)->endNamespaceDeclHandler) -#define externalEntityRefHandler (((Parser *)parser)->externalEntityRefHandler) -#define externalEntityRefHandlerArg (((Parser *)parser)->externalEntityRefHandlerArg) -#define unknownEncodingHandler (((Parser *)parser)->unknownEncodingHandler) -#define encoding (((Parser *)parser)->parserEncoding) -#define initEncoding (((Parser *)parser)->initEncoding) -#define unknownEncodingMem (((Parser *)parser)->unknownEncodingMem) -#define unknownEncodingData (((Parser *)parser)->unknownEncodingData) +#define userData (((Parser *)parser)->m_userData) +#define handlerArg (((Parser *)parser)->m_handlerArg) +#define startElementHandler (((Parser *)parser)->m_startElementHandler) +#define endElementHandler (((Parser *)parser)->m_endElementHandler) +#define characterDataHandler (((Parser *)parser)->m_characterDataHandler) +#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler) +#define commentHandler (((Parser *)parser)->m_commentHandler) +#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler) +#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler) +#define defaultHandler (((Parser *)parser)->m_defaultHandler) +#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler) +#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler) +#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler) +#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler) +#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler) +#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler) +#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg) +#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler) +#define encoding (((Parser *)parser)->m_encoding) +#define initEncoding (((Parser *)parser)->m_initEncoding) +#define internalEncoding (((Parser *)parser)->m_internalEncoding) +#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem) +#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData) #define unknownEncodingHandlerData \ - (((Parser *)parser)->unknownEncodingHandlerData) -#define unknownEncodingRelease (((Parser *)parser)->unknownEncodingRelease) -#define protocolEncodingName (((Parser *)parser)->protocolEncodingName) -#define ns (((Parser *)parser)->ns) -#define prologState (((Parser *)parser)->prologState) -#define processor (((Parser *)parser)->processor) -#define errorCode (((Parser *)parser)->errorCode) -#define eventPtr (((Parser *)parser)->eventPtr) -#define eventEndPtr (((Parser *)parser)->eventEndPtr) -#define positionPtr (((Parser *)parser)->positionPtr) -#define position (((Parser *)parser)->position) -#define openInternalEntities (((Parser *)parser)->openInternalEntities) -#define defaultExpandInternalEntities (((Parser *)parser)->defaultExpandInternalEntities) -#define tagLevel (((Parser *)parser)->tagLevel) -#define buffer (((Parser *)parser)->buffer) -#define bufferPtr (((Parser *)parser)->bufferPtr) -#define bufferEnd (((Parser *)parser)->bufferEnd) -#define parseEndByteIndex (((Parser *)parser)->parseEndByteIndex) -#define parseEndPtr (((Parser *)parser)->parseEndPtr) -#define bufferLim (((Parser *)parser)->bufferLim) -#define dataBuf (((Parser *)parser)->dataBuf) -#define dataBufEnd (((Parser *)parser)->dataBufEnd) -#define dtd (((Parser *)parser)->dtd) -#define declEntity (((Parser *)parser)->declEntity) -#define declNotationName (((Parser *)parser)->declNotationName) -#define declNotationPublicId (((Parser *)parser)->declNotationPublicId) -#define declElementType (((Parser *)parser)->declElementType) -#define declAttributeId (((Parser *)parser)->declAttributeId) -#define declAttributeIsCdata (((Parser *)parser)->declAttributeIsCdata) -#define freeTagList (((Parser *)parser)->freeTagList) -#define freeBindingList (((Parser *)parser)->freeBindingList) -#define inheritedBindings (((Parser *)parser)->inheritedBindings) -#define tagStack (((Parser *)parser)->tagStack) -#define atts (((Parser *)parser)->atts) -#define attsSize (((Parser *)parser)->attsSize) -#define tempPool (((Parser *)parser)->tempPool) -#define temp2Pool (((Parser *)parser)->temp2Pool) -#define groupConnector (((Parser *)parser)->groupConnector) -#define groupSize (((Parser *)parser)->groupSize) -#define hadExternalDoctype (((Parser *)parser)->hadExternalDoctype) -#define namespaceSeparator (((Parser *)parser)->namespaceSeparator) + (((Parser *)parser)->m_unknownEncodingHandlerData) +#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease) +#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName) +#define ns (((Parser *)parser)->m_ns) +#define prologState (((Parser *)parser)->m_prologState) +#define processor (((Parser *)parser)->m_processor) +#define errorCode (((Parser *)parser)->m_errorCode) +#define eventPtr (((Parser *)parser)->m_eventPtr) +#define eventEndPtr (((Parser *)parser)->m_eventEndPtr) +#define positionPtr (((Parser *)parser)->m_positionPtr) +#define position (((Parser *)parser)->m_position) +#define openInternalEntities (((Parser *)parser)->m_openInternalEntities) +#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities) +#define tagLevel (((Parser *)parser)->m_tagLevel) +#define buffer (((Parser *)parser)->m_buffer) +#define bufferPtr (((Parser *)parser)->m_bufferPtr) +#define bufferEnd (((Parser *)parser)->m_bufferEnd) +#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex) +#define parseEndPtr (((Parser *)parser)->m_parseEndPtr) +#define bufferLim (((Parser *)parser)->m_bufferLim) +#define dataBuf (((Parser *)parser)->m_dataBuf) +#define dataBufEnd (((Parser *)parser)->m_dataBufEnd) +#define dtd (((Parser *)parser)->m_dtd) +#define curBase (((Parser *)parser)->m_curBase) +#define declEntity (((Parser *)parser)->m_declEntity) +#define declNotationName (((Parser *)parser)->m_declNotationName) +#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId) +#define declElementType (((Parser *)parser)->m_declElementType) +#define declAttributeId (((Parser *)parser)->m_declAttributeId) +#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata) +#define freeTagList (((Parser *)parser)->m_freeTagList) +#define freeBindingList (((Parser *)parser)->m_freeBindingList) +#define inheritedBindings (((Parser *)parser)->m_inheritedBindings) +#define tagStack (((Parser *)parser)->m_tagStack) +#define atts (((Parser *)parser)->m_atts) +#define attsSize (((Parser *)parser)->m_attsSize) +#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts) +#define tempPool (((Parser *)parser)->m_tempPool) +#define temp2Pool (((Parser *)parser)->m_temp2Pool) +#define groupConnector (((Parser *)parser)->m_groupConnector) +#define groupSize (((Parser *)parser)->m_groupSize) +#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype) +#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator) +#ifdef XML_DTD +#define parentParser (((Parser *)parser)->m_parentParser) +#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing) +#endif /* XML_DTD */ #ifdef _MSC_VER #ifdef _DEBUG @@ -415,9 +449,6 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) characterDataHandler = 0; processingInstructionHandler = 0; commentHandler = 0; -#ifdef EXTERNAL_ENTITY_SUPPORT - externalDTDLoader = 0; -#endif startCdataSectionHandler = 0; endCdataSectionHandler = 0; defaultHandler = 0; @@ -425,6 +456,7 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) notationDeclHandler = 0; startNamespaceDeclHandler = 0; endNamespaceDeclHandler = 0; + notStandaloneHandler = 0; externalEntityRefHandler = 0; externalEntityRefHandlerArg = parser; unknownEncodingHandler = 0; @@ -452,6 +484,7 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) inheritedBindings = 0; attsSize = INIT_ATTS_SIZE; atts = malloc(attsSize * sizeof(ATTRIBUTE)); + nSpecifiedAtts = 0; dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); groupSize = 0; groupConnector = 0; @@ -461,10 +494,14 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) unknownEncodingData = 0; unknownEncodingHandlerData = 0; namespaceSeparator = '!'; +#ifdef XML_DTD + parentParser = 0; +#endif ns = 0; poolInit(&tempPool); poolInit(&temp2Pool); protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0; + curBase = 0; if (!dtdInit(&dtd) || !atts || !dataBuf || (encodingName && !protocolEncodingName)) { XML_ParserFree(parser); @@ -472,6 +509,7 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) } dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; XmlInitEncoding(&initEncoding, &encoding, 0); + internalEncoding = XmlGetInternalEncoding(); return parser; } @@ -495,6 +533,7 @@ XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) if (parser) { XmlInitEncodingNS(&initEncoding, &encoding, 0); ns = 1; + internalEncoding = XmlGetInternalEncodingNS(); namespaceSeparator = nsSep; } if (!setContext(parser, implicitContext)) { @@ -527,21 +566,21 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler; XML_CommentHandler oldCommentHandler = commentHandler; -#ifdef EXTERNAL_ENTITY_SUPPORT - XML_ExternalDTDLoader oldExternalDTDLoader = externalDTDLoader; -#endif XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler; XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler; XML_DefaultHandler oldDefaultHandler = defaultHandler; XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler; XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler; + XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler; XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler; void *oldUserData = userData; void *oldHandlerArg = handlerArg; int oldDefaultExpandInternalEntities = defaultExpandInternalEntities; void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; - +#ifdef XML_DTD + int oldParamEntityParsing = paramEntityParsing; +#endif parser = (ns ? XML_ParserCreateNS(encodingName, namespaceSeparator) : XML_ParserCreate(encodingName)); @@ -552,14 +591,12 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, characterDataHandler = oldCharacterDataHandler; processingInstructionHandler = oldProcessingInstructionHandler; commentHandler = oldCommentHandler; -#ifdef EXTERNAL_ENTITY_SUPPORT - externalDTDLoader = oldExternalDTDLoader; -#endif startCdataSectionHandler = oldStartCdataSectionHandler; endCdataSectionHandler = oldEndCdataSectionHandler; defaultHandler = oldDefaultHandler; startNamespaceDeclHandler = oldStartNamespaceDeclHandler; endNamespaceDeclHandler = oldEndNamespaceDeclHandler; + notStandaloneHandler = oldNotStandaloneHandler; externalEntityRefHandler = oldExternalEntityRefHandler; unknownEncodingHandler = oldUnknownEncodingHandler; userData = oldUserData; @@ -570,11 +607,25 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, if (oldExternalEntityRefHandlerArg != oldParser) externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) { - XML_ParserFree(parser); - return 0; +#ifdef XML_DTD + paramEntityParsing = oldParamEntityParsing; + if (context) { +#endif /* XML_DTD */ + if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) { + XML_ParserFree(parser); + return 0; + } + processor = externalEntityInitProcessor; +#ifdef XML_DTD } - processor = externalEntityInitProcessor; + else { + dtdSwap(&dtd, oldDtd); + parentParser = oldParser; + XmlPrologStateInitExternalEntity(&prologState); + dtd.complete = 1; + hadExternalDoctype = 1; + } +#endif /* XML_DTD */ return parser; } @@ -611,6 +662,13 @@ void XML_ParserFree(XML_Parser parser) destroyBindings(inheritedBindings); poolDestroy(&tempPool); poolDestroy(&temp2Pool); +#ifdef XML_DTD + if (parentParser) { + if (hadExternalDoctype) + dtd.complete = 0; + dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd); + } +#endif /* XML_DTD */ dtdDestroy(&dtd); free((void *)atts); free(groupConnector); @@ -641,16 +699,21 @@ int XML_SetBase(XML_Parser parser, const XML_Char *p) p = poolCopyString(&dtd.pool, p); if (!p) return 0; - dtd.base = p; + curBase = p; } else - dtd.base = 0; + curBase = 0; return 1; } const XML_Char *XML_GetBase(XML_Parser parser) { - return dtd.base; + return curBase; +} + +int XML_GetSpecifiedAttributeCount(XML_Parser parser) +{ + return nSpecifiedAtts; } void XML_SetElementHandler(XML_Parser parser, @@ -679,14 +742,6 @@ void XML_SetCommentHandler(XML_Parser parser, commentHandler = handler; } -#ifdef EXTERNAL_ENTITY_SUPPORT -void XML_SetExternalDTDLoader(XML_Parser parser, - XML_ExternalDTDLoader loader) -{ - externalDTDLoader = loader; -} -#endif - void XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end) @@ -729,6 +784,12 @@ void XML_SetNamespaceDeclHandler(XML_Parser parser, endNamespaceDeclHandler = end; } +void XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler) +{ + notStandaloneHandler = handler; +} + void XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { @@ -751,15 +812,28 @@ void XML_SetUnknownEncodingHandler(XML_Parser parser, unknownEncodingHandlerData = data; } +int XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing) +{ +#ifdef XML_DTD + paramEntityParsing = parsing; + return 1; +#else + return parsing == XML_PARAM_ENTITY_PARSING_NEVER; +#endif +} + int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { if (len == 0) { if (!isFinal) return 1; + positionPtr = bufferPtr; errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); if (errorCode == XML_ERROR_NONE) return 1; eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } else if (bufferPtr == bufferEnd) { @@ -772,11 +846,13 @@ int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) if (errorCode == XML_ERROR_NONE) return 1; eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } errorCode = processor(parser, s, parseEndPtr = s + len, &end); if (errorCode != XML_ERROR_NONE) { eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } XmlUpdatePosition(encoding, positionPtr, end, &position); @@ -785,9 +861,11 @@ int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) if (buffer == 0 || nLeftOver > bufferLim - buffer) { /* FIXME avoid integer overflow */ buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2); + /* FIXME storage leak if realloc fails */ if (!buffer) { errorCode = XML_ERROR_NO_MEMORY; eventPtr = eventEndPtr = 0; + processor = errorProcessor; return 0; } bufferLim = buffer + len * 2; @@ -819,6 +897,7 @@ int XML_ParseBuffer(XML_Parser parser, int len, int isFinal) } else { eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } } @@ -870,6 +949,13 @@ long XML_GetCurrentByteIndex(XML_Parser parser) return -1; } +int XML_GetCurrentByteCount(XML_Parser parser) +{ + if (eventEndPtr && eventPtr) + return eventEndPtr - eventPtr; + return 0; +} + int XML_GetCurrentLineNumber(XML_Parser parser) { if (eventPtr) { @@ -893,7 +979,7 @@ void XML_DefaultCurrent(XML_Parser parser) if (defaultHandler) { if (openInternalEntities) reportDefault(parser, - ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(), + internalEncoding, openInternalEntities->internalEventPtr, openInternalEntities->internalEventEndPtr); else @@ -925,7 +1011,8 @@ const XML_LChar *XML_ErrorString(int code) XML_T("unknown encoding"), XML_T("encoding specified in XML declaration is incorrect"), XML_T("unclosed CDATA section"), - XML_T("error in processing external entity reference") + XML_T("error in processing external entity reference"), + XML_T("document is not standalone") }; if (code > 0 && code < sizeof(message)/sizeof(message[0])) return message[code]; @@ -1039,7 +1126,6 @@ doContent(XML_Parser parser, const char *end, const char **nextPtr) { - const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); const char **eventPP; const char **eventEndPP; if (enc == encoding) { @@ -1052,7 +1138,7 @@ doContent(XML_Parser parser, } *eventPP = s; for (;;) { - const char *next; + const char *next = s; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { @@ -1147,7 +1233,7 @@ doContent(XML_Parser parser, openEntity.internalEventEndPtr = 0; result = doContent(parser, tagLevel, - internalEnc, + internalEncoding, (char *)entity->textPtr, (char *)(entity->textPtr + entity->textLen), 0); @@ -1165,7 +1251,7 @@ doContent(XML_Parser parser, return XML_ERROR_NO_MEMORY; if (!externalEntityRefHandler(externalEntityRefHandlerArg, context, - dtd.base, + entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; @@ -1206,8 +1292,8 @@ doContent(XML_Parser parser, tag->rawName = s + enc->minBytesPerChar; tag->rawNameLength = XmlNameLength(enc, tag->rawName); if (nextPtr) { - /* Need to guarantee that: */ - /* tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */ + /* Need to guarantee that: + tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */ if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) { int bufSize = tag->rawNameLength * 4; bufSize = ROUND_UP(bufSize, sizeof(XML_Char)); @@ -1468,7 +1554,7 @@ doContent(XML_Parser parser, otherwise just check the attributes for well-formedness. */ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, - const char *s, TAG_NAME *tagNamePtr, + const char *attStr, TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { ELEMENT_TYPE *elementType = 0; @@ -1495,7 +1581,7 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, } nDefaultAtts = elementType->nDefaultAtts; } - n = XmlGetAttributes(enc, s, attsSize, atts); + n = XmlGetAttributes(enc, attStr, attsSize, atts); if (n + nDefaultAtts > attsSize) { int oldAttsSize = attsSize; attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; @@ -1503,7 +1589,7 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, if (!atts) return XML_ERROR_NO_MEMORY; if (n > oldAttsSize) - XmlGetAttributes(enc, s, n, atts); + XmlGetAttributes(enc, attStr, n, atts); } appAtts = (const XML_Char **)atts; for (i = 0; i < n; i++) { @@ -1566,6 +1652,7 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, else attIndex++; } + nSpecifiedAtts = attIndex; if (tagNamePtr) { int j; for (j = 0; j < nDefaultAtts; j++) { @@ -1818,6 +1905,83 @@ enum XML_Error doCdataSection(XML_Parser parser, /* not reached */ } +#ifdef XML_DTD + +/* The idea here is to avoid using stack for each IGNORE section when +the whole file is parsed with one call. */ + +static +enum XML_Error ignoreSectionProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr); + if (start) { + processor = prologProcessor; + return prologProcessor(parser, start, end, endPtr); + } + return result; +} + +/* startPtr gets set to non-null is the section is closed, and to null if +the section is not yet closed. */ + +static +enum XML_Error doIgnoreSection(XML_Parser parser, + const ENCODING *enc, + const char **startPtr, + const char *end, + const char **nextPtr) +{ + const char *next; + int tok; + const char *s = *startPtr; + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + *eventPP = s; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } + *eventPP = s; + *startPtr = 0; + tok = XmlIgnoreSectionTok(enc, s, end, &next); + *eventEndPP = next; + switch (tok) { + case XML_TOK_IGNORE_SECT: + if (defaultHandler) + reportDefault(parser, enc, s, next); + *startPtr = next; + return XML_ERROR_NONE; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ + default: + abort(); + } + /* not reached */ +} + +#endif /* XML_DTD */ + static enum XML_Error initializeEncoding(XML_Parser parser) { @@ -1868,8 +2032,13 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, &newEncoding, &standalone)) return XML_ERROR_SYNTAX; - if (!isGeneralTextEntity && standalone == 1) + if (!isGeneralTextEntity && standalone == 1) { dtd.standalone = 1; +#ifdef XML_DTD + if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) + paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif /* XML_DTD */ + } if (defaultHandler) reportDefault(parser, encoding, s, next); if (!protocolEncodingName) { @@ -1956,15 +2125,38 @@ prologProcessor(XML_Parser parser, const char *end, const char **nextPtr) { -#ifdef EXTERNAL_ENTITY_SUPPORT - char * dtdData; - char * dtdNext; - int dtdLen; -#endif + const char *next; + int tok = XmlPrologTok(encoding, s, end, &next); + return doProlog(parser, encoding, s, end, tok, next, nextPtr); +} +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) +{ +#ifdef XML_DTD + static const XML_Char externalSubsetName[] = { '#' , '\0' }; +#endif /* XML_DTD */ + + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } for (;;) { - const char *next; - int tok = XmlPrologTok(encoding, s, end, &next); + int role; + *eventPP = s; + *eventEndPP = next; if (tok <= 0) { if (nextPtr != 0 && tok != XML_TOK_INVALID) { *nextPtr = s; @@ -1972,22 +2164,33 @@ prologProcessor(XML_Parser parser, } switch (tok) { case XML_TOK_INVALID: - eventPtr = next; + *eventPP = next; return XML_ERROR_INVALID_TOKEN; - case XML_TOK_NONE: - return XML_ERROR_NO_ELEMENTS; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_TRAILING_CR: - eventPtr = s + encoding->minBytesPerChar; + case XML_TOK_NONE: +#ifdef XML_DTD + if (enc != encoding) + return XML_ERROR_NONE; + if (parentParser) { + if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) + == XML_ROLE_ERROR) + return XML_ERROR_SYNTAX; + hadExternalDoctype = 0; + return XML_ERROR_NONE; + } +#endif /* XML_DTD */ return XML_ERROR_NO_ELEMENTS; default: - abort(); + tok = -tok; + next = end; + break; } } - switch (XmlTokenRole(&prologState, tok, s, next, encoding)) { + role = XmlTokenRole(&prologState, tok, s, next, enc); + switch (role) { case XML_ROLE_XML_DECL: { enum XML_Error result = processXmlDecl(parser, 0, s, next); @@ -1995,46 +2198,32 @@ prologProcessor(XML_Parser parser, return result; } break; - case XML_ROLE_DOCTYPE_SYSTEM_ID: -#ifdef EXTERNAL_ENTITY_SUPPORT - dtd.systemId = poolStoreString(&dtd.pool, encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); - if (!dtd.systemId) - return XML_ERROR_NO_MEMORY; - poolFinish(&dtd.pool); -#endif - hadExternalDoctype = 1; - break; -#ifdef EXTERNAL_ENTITY_SUPPORT - case XML_ROLE_DOCTYPE_CLOSE: - if (hadExternalDoctype == 1) { - // if no loader specified, just default (non-hacked) processing - if (externalDTDLoader) { - XmlPrologStateHack(&prologState); - hadExternalDoctype = 0; - - dtdLen = externalDTDLoader(dtd.base, dtd.systemId, &dtdData); - if (dtdLen < 0) { - return XML_ERROR_NO_MEMORY; - } - // XXX better error processing - dtdNext = dtdData + dtdLen; - prologProcessor(parser, dtdData, dtdNext, &dtdNext); - // XXX better error processing - } +#ifdef XML_DTD + case XML_ROLE_TEXT_DECL: + { + enum XML_Error result = processXmlDecl(parser, 1, s, next); + if (result != XML_ERROR_NONE) + return result; } break; -#endif +#endif /* XML_DTD */ case XML_ROLE_DOCTYPE_PUBLIC_ID: +#ifdef XML_DTD + declEntity = (ENTITY *)lookup(&dtd.paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; +#endif /* XML_DTD */ + /* fall through */ case XML_ROLE_ENTITY_PUBLIC_ID: - if (!XmlIsPublicId(encoding, s, next, &eventPtr)) + if (!XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_SYNTAX; if (declEntity) { XML_Char *tem = poolStoreString(&dtd.pool, - encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); @@ -2042,14 +2231,35 @@ prologProcessor(XML_Parser parser, poolFinish(&dtd.pool); } break; + case XML_ROLE_DOCTYPE_CLOSE: + if (dtd.complete && hadExternalDoctype) { + dtd.complete = 0; +#ifdef XML_DTD + if (paramEntityParsing && externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities, + externalSubsetName, + 0); + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + } +#endif /* XML_DTD */ + if (!dtd.complete + && !dtd.standalone + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; + } + break; case XML_ROLE_INSTANCE_START: processor = contentProcessor; - if (hadExternalDoctype) - dtd.complete = 0; return contentProcessor(parser, s, end, nextPtr); case XML_ROLE_ATTLIST_ELEMENT_NAME: { - const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next); + const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); if (!name) return XML_ERROR_NO_MEMORY; declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); @@ -2065,7 +2275,7 @@ prologProcessor(XML_Parser parser, break; } case XML_ROLE_ATTRIBUTE_NAME: - declAttributeId = getAttributeId(parser, encoding, s, next); + declAttributeId = getAttributeId(parser, enc, s, next); if (!declAttributeId) return XML_ERROR_NO_MEMORY; declAttributeIsCdata = 0; @@ -2084,9 +2294,9 @@ prologProcessor(XML_Parser parser, { const XML_Char *attVal; enum XML_Error result - = storeAttributeValue(parser, encoding, declAttributeIsCdata, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar, + = storeAttributeValue(parser, enc, declAttributeIsCdata, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar, &dtd.pool); if (result) return result; @@ -2099,30 +2309,60 @@ prologProcessor(XML_Parser parser, } case XML_ROLE_ENTITY_VALUE: { - enum XML_Error result = storeEntityValue(parser, s, next); + enum XML_Error result = storeEntityValue(parser, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (declEntity) { + declEntity->textPtr = poolStart(&dtd.pool); + declEntity->textLen = poolLength(&dtd.pool); + poolFinish(&dtd.pool); + } + else + poolDiscard(&dtd.pool); if (result != XML_ERROR_NONE) return result; } break; + case XML_ROLE_DOCTYPE_SYSTEM_ID: + if (!dtd.standalone +#ifdef XML_DTD + && !paramEntityParsing +#endif /* XML_DTD */ + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; + hadExternalDoctype = 1; +#ifndef XML_DTD + break; +#else /* XML_DTD */ + if (!declEntity) { + declEntity = (ENTITY *)lookup(&dtd.paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + } + /* fall through */ +#endif /* XML_DTD */ case XML_ROLE_ENTITY_SYSTEM_ID: if (declEntity) { - declEntity->systemId = poolStoreString(&dtd.pool, encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + declEntity->systemId = poolStoreString(&dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!declEntity->systemId) return XML_ERROR_NO_MEMORY; - declEntity->base = dtd.base; + declEntity->base = curBase; poolFinish(&dtd.pool); } break; case XML_ROLE_ENTITY_NOTATION_NAME: if (declEntity) { - declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next); + declEntity->notation = poolStoreString(&dtd.pool, enc, s, next); if (!declEntity->notation) return XML_ERROR_NO_MEMORY; poolFinish(&dtd.pool); if (unparsedEntityDeclHandler) { - eventPtr = eventEndPtr = s; + *eventEndPP = s; unparsedEntityDeclHandler(handlerArg, declEntity->name, declEntity->base, @@ -2136,11 +2376,11 @@ prologProcessor(XML_Parser parser, case XML_ROLE_GENERAL_ENTITY_NAME: { const XML_Char *name; - if (XmlPredefinedEntityName(encoding, s, next)) { + if (XmlPredefinedEntityName(enc, s, next)) { declEntity = 0; break; } - name = poolStoreString(&dtd.pool, encoding, s, next); + name = poolStoreString(&dtd.pool, enc, s, next); if (!name) return XML_ERROR_NO_MEMORY; if (dtd.complete) { @@ -2161,26 +2401,43 @@ prologProcessor(XML_Parser parser, } break; case XML_ROLE_PARAM_ENTITY_NAME: +#ifdef XML_DTD + if (dtd.complete) { + const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); + if (!name) + return XML_ERROR_NO_MEMORY; + declEntity = (ENTITY *)lookup(&dtd.paramEntities, name, sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + if (declEntity->name != name) { + poolDiscard(&dtd.pool); + declEntity = 0; + } + else + poolFinish(&dtd.pool); + } +#else /* not XML_DTD */ declEntity = 0; +#endif /* not XML_DTD */ break; case XML_ROLE_NOTATION_NAME: declNotationPublicId = 0; declNotationName = 0; if (notationDeclHandler) { - declNotationName = poolStoreString(&tempPool, encoding, s, next); + declNotationName = poolStoreString(&tempPool, enc, s, next); if (!declNotationName) return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); } break; case XML_ROLE_NOTATION_PUBLIC_ID: - if (!XmlIsPublicId(encoding, s, next, &eventPtr)) + if (!XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_SYNTAX; if (declNotationName) { XML_Char *tem = poolStoreString(&tempPool, - encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); @@ -2191,15 +2448,15 @@ prologProcessor(XML_Parser parser, case XML_ROLE_NOTATION_SYSTEM_ID: if (declNotationName && notationDeclHandler) { const XML_Char *systemId - = poolStoreString(&tempPool, encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + = poolStoreString(&tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!systemId) return XML_ERROR_NO_MEMORY; - eventPtr = eventEndPtr = s; + *eventEndPP = s; notationDeclHandler(handlerArg, declNotationName, - dtd.base, + curBase, systemId, declNotationPublicId); } @@ -2207,17 +2464,16 @@ prologProcessor(XML_Parser parser, break; case XML_ROLE_NOTATION_NO_SYSTEM_ID: if (declNotationPublicId && notationDeclHandler) { - eventPtr = eventEndPtr = s; + *eventEndPP = s; notationDeclHandler(handlerArg, declNotationName, - dtd.base, + curBase, 0, declNotationPublicId); } poolClear(&tempPool); break; case XML_ROLE_ERROR: - eventPtr = s; switch (tok) { case XML_TOK_PARAM_ENTITY_REF: return XML_ERROR_PARAM_ENTITY_REF; @@ -2226,6 +2482,20 @@ prologProcessor(XML_Parser parser, default: return XML_ERROR_SYNTAX; } +#ifdef XML_DTD + case XML_ROLE_IGNORE_SECT: + { + enum XML_Error result; + if (defaultHandler) + reportDefault(parser, enc, s, next); + result = doIgnoreSection(parser, enc, &next, end, nextPtr); + if (!next) { + processor = ignoreSectionProcessor; + return result; + } + } + break; +#endif /* XML_DTD */ case XML_ROLE_GROUP_OPEN: if (prologState.level >= groupSize) { if (groupSize) @@ -2238,34 +2508,77 @@ prologProcessor(XML_Parser parser, groupConnector[prologState.level] = 0; break; case XML_ROLE_GROUP_SEQUENCE: - if (groupConnector[prologState.level] == '|') { - eventPtr = s; + if (groupConnector[prologState.level] == '|') return XML_ERROR_SYNTAX; - } groupConnector[prologState.level] = ','; break; case XML_ROLE_GROUP_CHOICE: - if (groupConnector[prologState.level] == ',') { - eventPtr = s; + if (groupConnector[prologState.level] == ',') return XML_ERROR_SYNTAX; - } groupConnector[prologState.level] = '|'; break; case XML_ROLE_PARAM_ENTITY_REF: +#ifdef XML_DTD + case XML_ROLE_INNER_PARAM_ENTITY_REF: + if (paramEntityParsing + && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) { + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); + poolDiscard(&dtd.pool); + if (!entity) { + /* FIXME what to do if !dtd.complete? */ + return XML_ERROR_UNDEFINED_ENTITY; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->textPtr) { + enum XML_Error result; + result = processInternalParamEntity(parser, entity); + if (result != XML_ERROR_NONE) + return result; + break; + } + if (role == XML_ROLE_INNER_PARAM_ENTITY_REF) + return XML_ERROR_PARAM_ENTITY_REF; + if (externalEntityRefHandler) { + dtd.complete = 0; + entity->open = 1; + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) { + entity->open = 0; + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + } + entity->open = 0; + if (dtd.complete) + break; + } + } +#endif /* XML_DTD */ + if (!dtd.standalone + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; dtd.complete = 0; + if (defaultHandler) + reportDefault(parser, enc, s, next); break; case XML_ROLE_NONE: switch (tok) { case XML_TOK_PI: - eventPtr = s; - eventEndPtr = next; - if (!reportProcessingInstruction(parser, encoding, s, next)) + if (!reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: - eventPtr = s; - eventEndPtr = next; - if (!reportComment(parser, encoding, s, next)) + if (!reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; } @@ -2277,14 +2590,15 @@ prologProcessor(XML_Parser parser, case XML_TOK_COMMENT: case XML_TOK_BOM: case XML_TOK_XML_DECL: + case XML_TOK_IGNORE_SECT: + case XML_TOK_PARAM_ENTITY_REF: break; default: - eventPtr = s; - eventEndPtr = next; - reportDefault(parser, encoding, s, next); + reportDefault(parser, enc, s, next); } } s = next; + tok = XmlPrologTok(enc, s, end, &next); } /* not reached */ } @@ -2302,7 +2616,7 @@ enum XML_Error epilogProcessor(XML_Parser parser, int tok = XmlPrologTok(encoding, s, end, &next); eventEndPtr = next; switch (tok) { - case XML_TOK_TRAILING_CR: + case -XML_TOK_PROLOG_S: if (defaultHandler) { eventEndPtr = end; reportDefault(parser, encoding, s, end); @@ -2346,6 +2660,32 @@ enum XML_Error epilogProcessor(XML_Parser parser, } } +#ifdef XML_DTD + +static enum XML_Error +processInternalParamEntity(XML_Parser parser, ENTITY *entity) +{ + const char *s, *end, *next; + int tok; + enum XML_Error result; + OPEN_INTERNAL_ENTITY openEntity; + entity->open = 1; + openEntity.next = openInternalEntities; + openInternalEntities = &openEntity; + openEntity.entity = entity; + openEntity.internalEventPtr = 0; + openEntity.internalEventEndPtr = 0; + 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 = 0; + openInternalEntities = openEntity.next; + return result; +} + +#endif /* XML_DTD */ + static enum XML_Error errorProcessor(XML_Parser parser, const char *s, @@ -2375,7 +2715,6 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, const char *ptr, const char *end, STRING_POOL *pool) { - const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); for (;;) { const char *next; int tok = XmlAttributeValueTok(enc, ptr, end, &next); @@ -2476,7 +2815,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, enum XML_Error result; const XML_Char *textEnd = entity->textPtr + entity->textLen; entity->open = 1; - result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); + result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); entity->open = 0; if (result) return result; @@ -2493,36 +2832,65 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, static enum XML_Error storeEntityValue(XML_Parser parser, + const ENCODING *enc, const char *entityTextPtr, const char *entityTextEnd) { - const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); STRING_POOL *pool = &(dtd.pool); - entityTextPtr += encoding->minBytesPerChar; - entityTextEnd -= encoding->minBytesPerChar; for (;;) { const char *next; - int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next); + int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); switch (tok) { case XML_TOK_PARAM_ENTITY_REF: +#ifdef XML_DTD + if (parentParser || enc != encoding) { + enum XML_Error result; + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&tempPool, enc, + entityTextPtr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); + poolDiscard(&tempPool); + if (!entity) { + if (enc == encoding) + eventPtr = entityTextPtr; + return XML_ERROR_UNDEFINED_ENTITY; + } + if (entity->open) { + if (enc == encoding) + eventPtr = entityTextPtr; + return XML_ERROR_RECURSIVE_ENTITY_REF; + } + if (entity->systemId) { + if (enc == encoding) + eventPtr = entityTextPtr; + return XML_ERROR_PARAM_ENTITY_REF; + } + entity->open = 1; + result = storeEntityValue(parser, + internalEncoding, + (char *)entity->textPtr, + (char *)(entity->textPtr + entity->textLen)); + entity->open = 0; + if (result) + return result; + break; + } +#endif /* XML_DTD */ eventPtr = entityTextPtr; return XML_ERROR_SYNTAX; case XML_TOK_NONE: - if (declEntity) { - declEntity->textPtr = pool->start; - declEntity->textLen = pool->ptr - pool->start; - poolFinish(pool); - } - else - poolDiscard(pool); return XML_ERROR_NONE; case XML_TOK_ENTITY_REF: case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, encoding, entityTextPtr, next)) + if (!poolAppend(pool, enc, entityTextPtr, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_TRAILING_CR: - next = entityTextPtr + encoding->minBytesPerChar; + next = entityTextPtr + enc->minBytesPerChar; /* fall through */ case XML_TOK_DATA_NEWLINE: if (pool->end == pool->ptr && !poolGrow(pool)) @@ -2533,14 +2901,16 @@ enum XML_Error storeEntityValue(XML_Parser parser, { XML_Char buf[XML_ENCODE_MAX]; int i; - int n = XmlCharRefNumber(encoding, entityTextPtr); + int n = XmlCharRefNumber(enc, entityTextPtr); if (n < 0) { - eventPtr = entityTextPtr; + if (enc == encoding) + eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } n = XmlEncode(n, (ICHAR *)buf); if (!n) { - eventPtr = entityTextPtr; + if (enc == encoding) + eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } for (i = 0; i < n; i++) { @@ -2551,10 +2921,12 @@ enum XML_Error storeEntityValue(XML_Parser parser, } break; case XML_TOK_PARTIAL: - eventPtr = entityTextPtr; + if (enc == encoding) + eventPtr = entityTextPtr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_INVALID: - eventPtr = next; + if (enc == encoding) + eventPtr = next; return XML_ERROR_INVALID_TOKEN; default: abort(); @@ -2667,6 +3039,14 @@ static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value) { DEFAULT_ATTRIBUTE *att; + if (value) { + /* The handling of default attributes gets messed up if we have + a default which duplicates a non-default. */ + int i; + for (i = 0; i < type->nDefaultAtts; i++) + if (attId == type->defaultAtts[i].id) + return 1; + } if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; @@ -2929,12 +3309,26 @@ static int dtdInit(DTD *p) hashTableInit(&(p->prefixes)); p->complete = 1; p->standalone = 0; - p->base = 0; +#ifdef XML_DTD + hashTableInit(&(p->paramEntities)); +#endif /* XML_DTD */ p->defaultPrefix.name = 0; p->defaultPrefix.binding = 0; return 1; } +#ifdef XML_DTD + +static void dtdSwap(DTD *p1, DTD *p2) +{ + DTD tem; + memcpy(&tem, p1, sizeof(DTD)); + memcpy(p1, p2, sizeof(DTD)); + memcpy(p2, &tem, sizeof(DTD)); +} + +#endif /* XML_DTD */ + static void dtdDestroy(DTD *p) { HASH_TABLE_ITER iter; @@ -2947,6 +3341,9 @@ static void dtdDestroy(DTD *p) free(e->defaultAtts); } hashTableDestroy(&(p->generalEntities)); +#ifdef XML_DTD + hashTableDestroy(&(p->paramEntities)); +#endif /* XML_DTD */ hashTableDestroy(&(p->elementTypes)); hashTableDestroy(&(p->attributeIds)); hashTableDestroy(&(p->prefixes)); @@ -2960,13 +3357,6 @@ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) { HASH_TABLE_ITER iter; - if (oldDtd->base) { - const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base); - if (!tem) - return 0; - newDtd->base = tem; - } - /* Copy the prefix table. */ hashTableIterInit(&iter, &(oldDtd->prefixes)); @@ -3051,9 +3441,33 @@ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) } } - /* Copy the entity table. */ + /* Copy the entity tables. */ + if (!copyEntityTable(&(newDtd->generalEntities), + &(newDtd->pool), + &(oldDtd->generalEntities))) + return 0; - hashTableIterInit(&iter, &(oldDtd->generalEntities)); +#ifdef XML_DTD + if (!copyEntityTable(&(newDtd->paramEntities), + &(newDtd->pool), + &(oldDtd->paramEntities))) + return 0; +#endif /* XML_DTD */ + + newDtd->complete = oldDtd->complete; + newDtd->standalone = oldDtd->standalone; + return 1; +} + +static int copyEntityTable(HASH_TABLE *newTable, + STRING_POOL *newPool, + const HASH_TABLE *oldTable) +{ + HASH_TABLE_ITER iter; + const XML_Char *cachedOldBase = 0; + const XML_Char *cachedNewBase = 0; + + hashTableIterInit(&iter, oldTable); for (;;) { ENTITY *newE; @@ -3061,43 +3475,43 @@ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); if (!oldE) break; - name = poolCopyString(&(newDtd->pool), oldE->name); + name = poolCopyString(newPool, oldE->name); if (!name) return 0; - newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY)); + newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); if (!newE) return 0; if (oldE->systemId) { - const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId); + const XML_Char *tem = poolCopyString(newPool, oldE->systemId); if (!tem) return 0; newE->systemId = tem; if (oldE->base) { - if (oldE->base == oldDtd->base) - newE->base = newDtd->base; - tem = poolCopyString(&(newDtd->pool), oldE->base); - if (!tem) - return 0; - newE->base = tem; + if (oldE->base == cachedOldBase) + newE->base = cachedNewBase; + else { + cachedOldBase = oldE->base; + tem = poolCopyString(newPool, cachedOldBase); + if (!tem) + return 0; + cachedNewBase = newE->base = tem; + } } } else { - const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen); + const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); if (!tem) return 0; newE->textPtr = tem; newE->textLen = oldE->textLen; } if (oldE->notation) { - const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation); + const XML_Char *tem = poolCopyString(newPool, oldE->notation); if (!tem) return 0; newE->notation = tem; } } - - newDtd->complete = oldDtd->complete; - newDtd->standalone = oldDtd->standalone; return 1; } diff --git a/mozilla/expat/xmlparse/xmlparse.h b/mozilla/expat/xmlparse/xmlparse.h index b34617aab82..8c1d95d0a3d 100644 --- a/mozilla/expat/xmlparse/xmlparse.h +++ b/mozilla/expat/xmlparse/xmlparse.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef XmlParse_INCLUDED @@ -107,13 +117,6 @@ typedef void (*XML_ProcessingInstructionHandler)(void *userData, /* data is 0 terminated */ typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); -/* #define EXTERNAL_ENTITY_SUPPORT */ -#ifdef EXTERNAL_ENTITY_SUPPORT -typedef int (*XML_ExternalDTDLoader)(const XML_Char * base, - const XML_Char * systemId, - char ** data); -#endif - typedef void (*XML_StartCdataSectionHandler)(void *userData); typedef void (*XML_EndCdataSectionHandler)(void *userData); @@ -169,6 +172,14 @@ typedef void (*XML_StartNamespaceDeclHandler)(void *userData, typedef void (*XML_EndNamespaceDeclHandler)(void *userData, const XML_Char *prefix); +/* This is called if the document is not standalone (it has an +external subset or a reference to a parameter entity, but does not +have standalone="yes"). If this handler returns 0, then processing +will not continue, and the parser will return a +XML_ERROR_NOT_STANDALONE error. */ + +typedef int (*XML_NotStandaloneHandler)(void *userData); + /* This is called for a reference to an external parsed general entity. The referenced entity is not automatically parsed. The application can parse it immediately or later using @@ -278,13 +289,6 @@ void XMLPARSEAPI XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); - -#ifdef EXTERNAL_ENTITY_SUPPORT -void XMLPARSEAPI -XML_SetExternalDTDLoader(XML_Parser parser, - XML_ExternalDTDLoader loader); -#endif - void XMLPARSEAPI XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, @@ -317,6 +321,10 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end); +void XMLPARSEAPI +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + void XMLPARSEAPI XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler); @@ -371,6 +379,12 @@ XML_SetBase(XML_Parser parser, const XML_Char *base); const XML_Char XMLPARSEAPI * XML_GetBase(XML_Parser parser); +/* Returns the number of the attributes passed in last call to the +XML_StartElementHandler that were specified in the start-tag rather +than defaulted. */ + +int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser); + /* Parses some input. Returns 0 if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other). */ @@ -396,11 +410,45 @@ so longer as the parser has not yet been freed. The new parser is completely independent and may safely be used in a separate thread. The handlers and userData are initialized from the parser argument. Returns 0 if out of memory. Otherwise returns a new XML_Parser object. */ + +#if 0 +#define XML_DTD +#endif /* 0 */ + XML_Parser XMLPARSEAPI XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, const XML_Char *encoding); +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD +subset). If parsing of parameter entities is enabled, then references +to external parameter entities (including the external DTD subset) +will be passed to the handler set with +XML_SetExternalEntityRefHandler. The context passed will be 0. +Unlike external general entities, external parameter entities can only +be parsed synchronously. If the external parameter entity is to be +parsed, it must be parsed during the call to the external entity ref +handler: the complete sequence of XML_ExternalEntityParserCreate, +XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during +this call. After XML_ExternalEntityParserCreate has been called to +create the parser for the external parameter entity (context must be 0 +for this call), it is illegal to make any calls on the old parser +until XML_ParserFree has been called on the newly created parser. If +the library has been compiled without support for parameter entity +parsing (ie without XML_DTD being defined), then +XML_SetParamEntityParsing will return 0 if parsing of parameter +entities is requested; otherwise it will return non-zero. */ + +int XMLPARSEAPI +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + enum XML_Error { XML_ERROR_NONE, XML_ERROR_NO_MEMORY, @@ -423,7 +471,8 @@ enum XML_Error { XML_ERROR_UNKNOWN_ENCODING, XML_ERROR_INCORRECT_ENCODING, XML_ERROR_UNCLOSED_CDATA_SECTION, - XML_ERROR_EXTERNAL_ENTITY_HANDLING + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE }; /* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode @@ -443,6 +492,11 @@ int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser); int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser); long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser); +/* Return the number of bytes in the current event. +Returns 0 if the event is in an internal entity. */ + +int XMLPARSEAPI XML_GetCurrentByteCount(XML_Parser parser); + /* For backwards compatibility with previous versions. */ #define XML_GetErrorLineNumber XML_GetCurrentLineNumber #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber diff --git a/mozilla/expat/xmltok/xmlrole.c b/mozilla/expat/xmltok/xmlrole.c index e07be718066..a8fdda78da2 100644 --- a/mozilla/expat/xmltok/xmlrole.c +++ b/mozilla/expat/xmltok/xmlrole.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" @@ -32,7 +42,16 @@ Contributor(s): #define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) #endif -typedef int PROLOG_HANDLER(struct prolog_state *state, +#ifdef XML_DTD +#define setTopLevel(state) \ + ((state)->handler = ((state)->documentEntity \ + ? internalSubset \ + : externalSubset1)) +#else /* not XML_DTD */ +#define setTopLevel(state) ((state)->handler = internalSubset) +#endif /* not XML_DTD */ + +typedef int PROLOG_HANDLER(PROLOG_STATE *state, int tok, const char *ptr, const char *end, @@ -49,11 +68,15 @@ static PROLOG_HANDLER attlist7, attlist8, attlist9, element0, element1, element2, element3, element4, element5, element6, element7, +#ifdef XML_DTD + externalSubset0, externalSubset1, + condSect0, condSect1, condSect2, +#endif /* XML_DTD */ declClose, error; static -int syntaxError(PROLOG_STATE *); +int common(PROLOG_STATE *state, int tok); static int prolog0(PROLOG_STATE *state, @@ -79,6 +102,7 @@ int prolog0(PROLOG_STATE *state, case XML_TOK_DECL_OPEN: if (!XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "DOCTYPE")) break; state->handler = doctype0; @@ -87,7 +111,7 @@ int prolog0(PROLOG_STATE *state, state->handler = error; return XML_ROLE_INSTANCE_START; } - return syntaxError(state); + return common(state, tok); } static @@ -107,6 +131,7 @@ int prolog1(PROLOG_STATE *state, case XML_TOK_DECL_OPEN: if (!XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "DOCTYPE")) break; state->handler = doctype0; @@ -115,7 +140,7 @@ int prolog1(PROLOG_STATE *state, state->handler = error; return XML_ROLE_INSTANCE_START; } - return syntaxError(state); + return common(state, tok); } static @@ -135,7 +160,7 @@ int prolog2(PROLOG_STATE *state, state->handler = error; return XML_ROLE_INSTANCE_START; } - return syntaxError(state); + return common(state, tok); } static @@ -153,7 +178,7 @@ int doctype0(PROLOG_STATE *state, state->handler = doctype1; return XML_ROLE_DOCTYPE_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -173,17 +198,17 @@ int doctype1(PROLOG_STATE *state, state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = doctype3; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = doctype2; return XML_ROLE_NONE; } break; } - return syntaxError(state); + return common(state, tok); } static @@ -200,7 +225,7 @@ int doctype2(PROLOG_STATE *state, state->handler = doctype3; return XML_ROLE_DOCTYPE_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -217,7 +242,7 @@ int doctype3(PROLOG_STATE *state, state->handler = doctype4; return XML_ROLE_DOCTYPE_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -237,7 +262,7 @@ int doctype4(PROLOG_STATE *state, state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } - return syntaxError(state); + return common(state, tok); } static @@ -254,7 +279,7 @@ int doctype5(PROLOG_STATE *state, state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } - return syntaxError(state); + return common(state, tok); } static @@ -270,24 +295,28 @@ int internalSubset(PROLOG_STATE *state, case XML_TOK_DECL_OPEN: if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "ENTITY")) { state->handler = entity0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "ATTLIST")) { state->handler = attlist0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "ELEMENT")) { state->handler = element0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "NOTATION")) { state->handler = notation0; return XML_ROLE_NONE; @@ -302,9 +331,56 @@ int internalSubset(PROLOG_STATE *state, state->handler = doctype5; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } +#ifdef XML_DTD + +static +int externalSubset0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + state->handler = externalSubset1; + if (tok == XML_TOK_XML_DECL) + return XML_ROLE_TEXT_DECL; + return externalSubset1(state, tok, ptr, end, enc); +} + +static +int externalSubset1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_COND_SECT_OPEN: + state->handler = condSect0; + return XML_ROLE_NONE; + case XML_TOK_COND_SECT_CLOSE: + if (state->includeLevel == 0) + break; + state->includeLevel -= 1; + return XML_ROLE_NONE; + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_BRACKET: + break; + case XML_TOK_NONE: + if (state->includeLevel) + break; + return XML_ROLE_NONE; + default: + return internalSubset(state, tok, ptr, end, enc); + } + return common(state, tok); +} + +#endif /* XML_DTD */ + static int entity0(PROLOG_STATE *state, int tok, @@ -322,7 +398,7 @@ int entity0(PROLOG_STATE *state, state->handler = entity2; return XML_ROLE_GENERAL_ENTITY_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -339,7 +415,7 @@ int entity1(PROLOG_STATE *state, state->handler = entity7; return XML_ROLE_PARAM_ENTITY_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -353,11 +429,11 @@ int entity2(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = entity4; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = entity3; return XML_ROLE_NONE; } @@ -366,7 +442,7 @@ int entity2(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -383,7 +459,7 @@ int entity3(PROLOG_STATE *state, state->handler = entity4; return XML_ROLE_ENTITY_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } @@ -401,7 +477,7 @@ int entity4(PROLOG_STATE *state, state->handler = entity5; return XML_ROLE_ENTITY_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -415,16 +491,16 @@ int entity5(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "NDATA")) { + if (XmlNameMatchesAscii(enc, ptr, end, "NDATA")) { state->handler = entity6; return XML_ROLE_NONE; } break; } - return syntaxError(state); + return common(state, tok); } static @@ -441,7 +517,7 @@ int entity6(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_NOTATION_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -455,11 +531,11 @@ int entity7(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = entity9; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = entity8; return XML_ROLE_NONE; } @@ -468,7 +544,7 @@ int entity7(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -485,7 +561,7 @@ int entity8(PROLOG_STATE *state, state->handler = entity9; return XML_ROLE_ENTITY_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -502,7 +578,7 @@ int entity9(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -519,7 +595,7 @@ int notation0(PROLOG_STATE *state, state->handler = notation1; return XML_ROLE_NOTATION_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -533,17 +609,17 @@ int notation1(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = notation3; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = notation2; return XML_ROLE_NONE; } break; } - return syntaxError(state); + return common(state, tok); } static @@ -560,7 +636,7 @@ int notation2(PROLOG_STATE *state, state->handler = notation4; return XML_ROLE_NOTATION_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -577,7 +653,7 @@ int notation3(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_NOTATION_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -594,10 +670,10 @@ int notation4(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_NOTATION_SYSTEM_ID; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NOTATION_NO_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -615,7 +691,7 @@ int attlist0(PROLOG_STATE *state, state->handler = attlist1; return XML_ROLE_ATTLIST_ELEMENT_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -629,14 +705,14 @@ int attlist1(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist2; return XML_ROLE_ATTRIBUTE_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -663,12 +739,12 @@ int attlist2(PROLOG_STATE *state, }; int i; for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) - if (XmlNameMatchesAscii(enc, ptr, types[i])) { + if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { state->handler = attlist8; return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; } } - if (XmlNameMatchesAscii(enc, ptr, "NOTATION")) { + if (XmlNameMatchesAscii(enc, ptr, end, "NOTATION")) { state->handler = attlist5; return XML_ROLE_NONE; } @@ -677,7 +753,7 @@ int attlist2(PROLOG_STATE *state, state->handler = attlist3; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -696,7 +772,7 @@ int attlist3(PROLOG_STATE *state, state->handler = attlist4; return XML_ROLE_ATTRIBUTE_ENUM_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -716,7 +792,7 @@ int attlist4(PROLOG_STATE *state, state->handler = attlist3; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -733,7 +809,7 @@ int attlist5(PROLOG_STATE *state, state->handler = attlist6; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } @@ -751,7 +827,7 @@ int attlist6(PROLOG_STATE *state, state->handler = attlist7; return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -771,7 +847,7 @@ int attlist7(PROLOG_STATE *state, state->handler = attlist6; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } /* default value */ @@ -788,18 +864,21 @@ int attlist8(PROLOG_STATE *state, case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "IMPLIED")) { state->handler = attlist1; return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "REQUIRED")) { state->handler = attlist1; return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "FIXED")) { state->handler = attlist9; return XML_ROLE_NONE; @@ -809,7 +888,7 @@ int attlist8(PROLOG_STATE *state, state->handler = attlist1; return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -826,7 +905,7 @@ int attlist9(PROLOG_STATE *state, state->handler = attlist1; return XML_ROLE_FIXED_ATTRIBUTE_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -844,7 +923,7 @@ int element0(PROLOG_STATE *state, state->handler = element1; return XML_ROLE_ELEMENT_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -858,11 +937,11 @@ int element1(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "EMPTY")) { + if (XmlNameMatchesAscii(enc, ptr, end, "EMPTY")) { state->handler = declClose; return XML_ROLE_CONTENT_EMPTY; } - if (XmlNameMatchesAscii(enc, ptr, "ANY")) { + if (XmlNameMatchesAscii(enc, ptr, end, "ANY")) { state->handler = declClose; return XML_ROLE_CONTENT_ANY; } @@ -872,7 +951,7 @@ int element1(PROLOG_STATE *state, state->level = 1; return XML_ROLE_GROUP_OPEN; } - return syntaxError(state); + return common(state, tok); } static @@ -888,6 +967,7 @@ int element2(PROLOG_STATE *state, case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "PCDATA")) { state->handler = element3; return XML_ROLE_CONTENT_PCDATA; @@ -911,7 +991,7 @@ int element2(PROLOG_STATE *state, state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } - return syntaxError(state); + return common(state, tok); } static @@ -932,7 +1012,7 @@ int element3(PROLOG_STATE *state, state->handler = element4; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -950,7 +1030,7 @@ int element4(PROLOG_STATE *state, state->handler = element5; return XML_ROLE_CONTENT_ELEMENT; } - return syntaxError(state); + return common(state, tok); } static @@ -970,7 +1050,7 @@ int element5(PROLOG_STATE *state, state->handler = element4; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -1000,7 +1080,7 @@ int element6(PROLOG_STATE *state, state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } - return syntaxError(state); + return common(state, tok); } static @@ -1040,9 +1120,72 @@ int element7(PROLOG_STATE *state, state->handler = element6; return XML_ROLE_GROUP_CHOICE; } - return syntaxError(state); + return common(state, tok); } +#ifdef XML_DTD + +static +int condSect0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, "INCLUDE")) { + state->handler = condSect1; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, "IGNORE")) { + state->handler = condSect2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static +int condSect1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + state->includeLevel += 1; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static +int condSect2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + return XML_ROLE_IGNORE_SECT; + } + return common(state, tok); +} + +#endif /* XML_DTD */ + static int declClose(PROLOG_STATE *state, int tok, @@ -1054,10 +1197,10 @@ int declClose(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } #if 0 @@ -1076,23 +1219,27 @@ int ignore(PROLOG_STATE *state, default: return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } #endif static int error(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) { return XML_ROLE_NONE; } static -int syntaxError(PROLOG_STATE *state) +int common(PROLOG_STATE *state, int tok) { +#ifdef XML_DTD + if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) + return XML_ROLE_INNER_PARAM_ENTITY_REF; +#endif state->handler = error; return XML_ROLE_ERROR; } @@ -1100,11 +1247,19 @@ int syntaxError(PROLOG_STATE *state) void XmlPrologStateInit(PROLOG_STATE *state) { state->handler = prolog0; +#ifdef XML_DTD + state->documentEntity = 1; + state->includeLevel = 0; +#endif /* XML_DTD */ } -#ifdef EXTERNAL_ENTITY_SUPPORT -void XmlPrologStateHack(PROLOG_STATE *state) +#ifdef XML_DTD + +void XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { - state->handler = prolog1; + state->handler = externalSubset0; + state->documentEntity = 0; + state->includeLevel = 0; } -#endif + +#endif /* XML_DTD */ diff --git a/mozilla/expat/xmltok/xmlrole.h b/mozilla/expat/xmltok/xmlrole.h index 28b245698f6..3e780e7f6e0 100644 --- a/mozilla/expat/xmltok/xmlrole.h +++ b/mozilla/expat/xmltok/xmlrole.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef XmlRole_INCLUDED @@ -77,6 +87,11 @@ enum { XML_ROLE_CONTENT_ELEMENT_REP, XML_ROLE_CONTENT_ELEMENT_OPT, XML_ROLE_CONTENT_ELEMENT_PLUS, +#ifdef XML_DTD + XML_ROLE_TEXT_DECL, + XML_ROLE_IGNORE_SECT, + XML_ROLE_INNER_PARAM_ENTITY_REF, +#endif /* XML_DTD */ XML_ROLE_PARAM_ENTITY_REF }; @@ -87,14 +102,16 @@ typedef struct prolog_state { const char *end, const ENCODING *enc); unsigned level; +#ifdef XML_DTD + unsigned includeLevel; + int documentEntity; +#endif /* XML_DTD */ } PROLOG_STATE; void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *); - -/* #define EXTERNAL_ENTITY_SUPPORT */ -#ifdef EXTERNAL_ENTITY_SUPPORT -void XMLTOKAPI XmlPrologStateHack(PROLOG_STATE *); -#endif +#ifdef XML_DTD +void XMLTOKAPI XmlPrologStateInitExternalEntity(PROLOG_STATE *); +#endif /* XML_DTD */ #define XmlTokenRole(state, tok, ptr, end, enc) \ (((state)->handler)(state, tok, ptr, end, enc)) diff --git a/mozilla/expat/xmltok/xmltok.c b/mozilla/expat/xmltok/xmltok.c index cd96f00d9dc..7e50a00a8ab 100644 --- a/mozilla/expat/xmltok/xmltok.c +++ b/mozilla/expat/xmltok/xmltok.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,18 +12,35 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" #include "xmltok.h" #include "nametab.h" +#ifdef XML_DTD +#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) +#else +#define IGNORE_SECTION_TOK_VTABLE /* as nothing */ +#endif + #define VTABLE1 \ - { PREFIX(prologTok), PREFIX(contentTok), PREFIX(cdataSectionTok) }, \ + { PREFIX(prologTok), PREFIX(contentTok), \ + PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ PREFIX(sameName), \ PREFIX(nameMatchesAscii), \ @@ -658,7 +675,7 @@ int little2_isNmstrtMin(const ENCODING *enc, const char *p) static const struct normal_encoding little2_encoding_ns = { { VTABLE, 2, 0, -#if BYTE_ORDER == 12 +#if XML_BYTE_ORDER == 12 1 #else 0 @@ -675,7 +692,7 @@ static const struct normal_encoding little2_encoding_ns = { static const struct normal_encoding little2_encoding = { { VTABLE, 2, 0, -#if BYTE_ORDER == 12 +#if XML_BYTE_ORDER == 12 1 #else 0 @@ -690,7 +707,7 @@ static const struct normal_encoding little2_encoding = { STANDARD_VTABLE(little2_) }; -#if BYTE_ORDER != 21 +#if XML_BYTE_ORDER != 21 #ifdef XML_NS @@ -797,7 +814,7 @@ int big2_isNmstrtMin(const ENCODING *enc, const char *p) static const struct normal_encoding big2_encoding_ns = { { VTABLE, 2, 0, -#if BYTE_ORDER == 21 +#if XML_BYTE_ORDER == 21 1 #else 0 @@ -814,7 +831,7 @@ static const struct normal_encoding big2_encoding_ns = { static const struct normal_encoding big2_encoding = { { VTABLE, 2, 0, -#if BYTE_ORDER == 21 +#if XML_BYTE_ORDER == 21 1 #else 0 @@ -829,7 +846,7 @@ static const struct normal_encoding big2_encoding = { STANDARD_VTABLE(big2_) }; -#if BYTE_ORDER != 12 +#if XML_BYTE_ORDER != 12 #ifdef XML_NS @@ -916,6 +933,7 @@ int parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, const char **namePtr, + const char **nameEndPtr, const char **valPtr, const char **nextTokPtr) { @@ -943,9 +961,12 @@ int parsePseudoAttribute(const ENCODING *enc, *nextTokPtr = ptr; return 0; } - if (c == '=') + if (c == '=') { + *nameEndPtr = ptr; break; + } if (isSpace(c)) { + *nameEndPtr = ptr; do { ptr += enc->minBytesPerChar; } while (isSpace(c = toAscii(enc, ptr, end))); @@ -1008,13 +1029,14 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, { const char *val = 0; const char *name = 0; + const char *nameEnd = 0; ptr += 5 * enc->minBytesPerChar; end -= 2 * enc->minBytesPerChar; - if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr) || !name) { + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) { *badPtr = ptr; return 0; } - if (!XmlNameMatchesAscii(enc, name, "version")) { + if (!XmlNameMatchesAscii(enc, name, nameEnd, "version")) { if (!isGeneralTextEntity) { *badPtr = name; return 0; @@ -1023,7 +1045,7 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, else { if (versionPtr) *versionPtr = val; - if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } @@ -1036,7 +1058,7 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, return 1; } } - if (XmlNameMatchesAscii(enc, name, "encoding")) { + if (XmlNameMatchesAscii(enc, name, nameEnd, "encoding")) { int c = toAscii(enc, val, end); if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) { *badPtr = val; @@ -1046,22 +1068,22 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, *encodingName = val; if (encoding) *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); - if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } if (!name) return 1; } - if (!XmlNameMatchesAscii(enc, name, "standalone") || isGeneralTextEntity) { + if (!XmlNameMatchesAscii(enc, name, nameEnd, "standalone") || isGeneralTextEntity) { *badPtr = name; return 0; } - if (XmlNameMatchesAscii(enc, val, "yes")) { + if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, "yes")) { if (standalone) *standalone = 1; } - else if (XmlNameMatchesAscii(enc, val, "no")) { + else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, "no")) { if (standalone) *standalone = 0; } @@ -1158,7 +1180,7 @@ struct unknown_encoding { char utf8[256][4]; }; -int XmlSizeOfUnknownEncoding() +int XmlSizeOfUnknownEncoding(void) { return sizeof(struct unknown_encoding); } @@ -1361,7 +1383,8 @@ int getEncodingIndex(const char *name) /* For binary compatibility, we store the index of the encoding specified at initialization in the isUtf16 member. */ -#define INIT_ENC_INDEX(enc) ((enc)->initEnc.isUtf16) +#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) +#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) /* This is what detects the encoding. encodingTable maps from encoding indices to encodings; @@ -1386,9 +1409,11 @@ int initScan(const ENCODING **encodingTable, encPtr = enc->encPtr; if (ptr + 1 == end) { /* only a single byte available for auto-detection */ +#ifndef XML_DTD /* FIXME */ /* a well-formed document entity must have more than one byte */ if (state != XML_CONTENT_STATE) return XML_TOK_PARTIAL; +#endif /* so we're parsing an external text entity... */ /* if UTF-16 was externally specified, then we need at least 2 bytes */ switch (INIT_ENC_INDEX(enc)) { diff --git a/mozilla/expat/xmltok/xmltok.h b/mozilla/expat/xmltok/xmltok.h index dc0364a5031..abf682ade57 100644 --- a/mozilla/expat/xmltok/xmltok.h +++ b/mozilla/expat/xmltok/xmltok.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef XmlTok_INCLUDED @@ -98,10 +108,26 @@ extern "C" { for a name with a colon. */ #define XML_TOK_PREFIXED_NAME 41 +#if 0 +#define XML_DTD +#endif /* 0 */ + +#ifdef XML_DTD +#define XML_TOK_IGNORE_SECT 42 +#endif /* XML_DTD */ + +#ifdef XML_DTD +#define XML_N_STATES 4 +#else /* not XML_DTD */ #define XML_N_STATES 3 +#endif /* not XML_DTD */ + #define XML_PROLOG_STATE 0 #define XML_CONTENT_STATE 1 #define XML_CDATA_SECTION_STATE 2 +#ifdef XML_DTD +#define XML_IGNORE_SECTION_STATE 3 +#endif /* XML_DTD */ #define XML_N_LITERAL_TYPES 2 #define XML_ATTRIBUTE_VALUE_LITERAL 0 @@ -140,7 +166,7 @@ struct encoding { int (*sameName)(const ENCODING *, const char *, const char *); int (*nameMatchesAscii)(const ENCODING *, - const char *, const char *); + const char *, const char *, const char *); int (*nameLength)(const ENCODING *, const char *); const char *(*skipS)(const ENCODING *, const char *); int (*getAtts)(const ENCODING *enc, const char *ptr, @@ -201,6 +227,13 @@ literals, comments and processing instructions. #define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) +#ifdef XML_DTD + +#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) + +#endif /* XML_DTD */ + /* This is used for performing a 2nd-level tokenization on the content of a literal that has already been returned by XmlTok. */ @@ -215,8 +248,8 @@ the content of a literal that has already been returned by XmlTok. */ #define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) -#define XmlNameMatchesAscii(enc, ptr1, ptr2) \ - (((enc)->nameMatchesAscii)(enc, ptr1, ptr2)) +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ + (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) #define XmlNameLength(enc, ptr) \ (((enc)->nameLength)(enc, ptr)) @@ -261,16 +294,16 @@ int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity, int *standalonePtr); int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); -const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(); -const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(); +const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(void); +const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(void); int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf); int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf); -int XMLTOKAPI XmlSizeOfUnknownEncoding(); +int XMLTOKAPI XmlSizeOfUnknownEncoding(void); ENCODING XMLTOKAPI * XmlInitUnknownEncoding(void *mem, int *table, - int (*convert)(void *userData, const char *p), + int (*conv)(void *userData, const char *p), void *userData); int XMLTOKAPI XmlParseXmlDeclNS(int isGeneralTextEntity, @@ -288,7 +321,7 @@ const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncodingNS(); ENCODING XMLTOKAPI * XmlInitUnknownEncodingNS(void *mem, int *table, - int (*convert)(void *userData, const char *p), + int (*conv)(void *userData, const char *p), void *userData); #ifdef __cplusplus } diff --git a/mozilla/expat/xmltok/xmltok_impl.c b/mozilla/expat/xmltok/xmltok_impl.c index f35938128ad..b3d358dd2d0 100644 --- a/mozilla/expat/xmltok/xmltok_impl.c +++ b/mozilla/expat/xmltok/xmltok_impl.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef IS_INVALID_CHAR @@ -943,7 +953,7 @@ int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_INVALID; } } - return XML_TOK_PARTIAL; + return -XML_TOK_POUND_NAME; } static @@ -961,7 +971,7 @@ int PREFIX(scanLit)(int open, const ENCODING *enc, if (t != open) break; if (ptr == end) - return XML_TOK_PARTIAL; + return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: @@ -1023,7 +1033,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, } case BT_CR: if (ptr + MINBPC(enc) == end) - return XML_TOK_TRAILING_CR; + return -XML_TOK_PROLOG_S; /* fall through */ case BT_S: case BT_LF: for (;;) { @@ -1056,7 +1066,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_RSQB: ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ']')) { if (ptr + MINBPC(enc) == end) return XML_TOK_PARTIAL; @@ -1073,7 +1083,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_RPAR: ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return -XML_TOK_CLOSE_PAREN; switch (BYTE_TYPE(enc, ptr)) { case BT_AST: *nextTokPtr = ptr + MINBPC(enc); @@ -1203,7 +1213,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_INVALID; } } - return XML_TOK_PARTIAL; + return -tok; } static @@ -1316,6 +1326,61 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end return XML_TOK_DATA_CHARS; } +#ifdef XML_DTD + +static +int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + int level = 0; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + end = ptr + n; + } + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + INVALID_CASES(ptr, nextTokPtr) + case BT_LT: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, '!')) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, '[')) { + ++level; + ptr += MINBPC(enc); + } + } + break; + case BT_RSQB: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ']')) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, '>')) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } + } + break; + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +#endif /* XML_DTD */ + static int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr) @@ -1381,7 +1446,8 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, { enum { other, inName, inValue } state = inName; int nAtts = 0; - int open; + int open = 0; /* defined when state == inValue; + initialization just to shut up compilers */ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { @@ -1625,29 +1691,16 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) } static -int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *ptr2) +int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, + const char *end1, const char *ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { + if (ptr1 == end1) + return 0; if (!CHAR_MATCHES(enc, ptr1, *ptr2)) return 0; } - switch (BYTE_TYPE(enc, ptr1)) { - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - return 0; - default: - return 1; - } + return ptr1 == end1; } static diff --git a/mozilla/expat/xmltok/xmltok_ns.c b/mozilla/expat/xmltok/xmltok_ns.c index 435ad7808f8..77d0e739df0 100644 --- a/mozilla/expat/xmltok/xmltok_ns.c +++ b/mozilla/expat/xmltok/xmltok_ns.c @@ -1,13 +1,13 @@ -const ENCODING *NS(XmlGetUtf8InternalEncoding)() +const ENCODING *NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } -const ENCODING *NS(XmlGetUtf16InternalEncoding)() +const ENCODING *NS(XmlGetUtf16InternalEncoding)(void) { -#if BYTE_ORDER == 12 +#if XML_BYTE_ORDER == 12 return &ns(internal_little2_encoding).enc; -#elif BYTE_ORDER == 21 +#elif XML_BYTE_ORDER == 21 return &ns(internal_big2_encoding).enc; #else const short n = 1; @@ -45,7 +45,7 @@ int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *n int i = getEncodingIndex(name); if (i == UNKNOWN_ENC) return 0; - INIT_ENC_INDEX(p) = (char)i; + SET_INIT_ENC_INDEX(p, i); p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); p->initEnc.updatePosition = initUpdatePosition; diff --git a/mozilla/parser/expat/lib/hashtable.c b/mozilla/parser/expat/lib/hashtable.c index e39f82ad10f..780a0610414 100644 --- a/mozilla/parser/expat/lib/hashtable.c +++ b/mozilla/parser/expat/lib/hashtable.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in csompliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" diff --git a/mozilla/parser/expat/lib/hashtable.h b/mozilla/parser/expat/lib/hashtable.h index 63478a0812c..df8ab8a4c83 100644 --- a/mozilla/parser/expat/lib/hashtable.h +++ b/mozilla/parser/expat/lib/hashtable.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,24 +12,38 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include #ifdef XML_UNICODE + #ifdef XML_UNICODE_WCHAR_T typedef const wchar_t *KEY; -#else +#else /* not XML_UNICODE_WCHAR_T */ typedef const unsigned short *KEY; -#endif -#else +#endif /* not XML_UNICODE_WCHAR_T */ + +#else /* not XML_UNICODE */ + typedef const char *KEY; -#endif + +#endif /* not XML_UNICODE */ typedef struct { KEY name; diff --git a/mozilla/parser/expat/lib/xmlparse.c b/mozilla/parser/expat/lib/xmlparse.c index 4eaf7e98c1a..9d629403bc4 100644 --- a/mozilla/parser/expat/lib/xmlparse.c +++ b/mozilla/parser/expat/lib/xmlparse.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" @@ -50,7 +60,6 @@ typedef char ICHAR; #endif - #ifdef XML_UNICODE_WCHAR_T #define XML_T(x) L ## x #else @@ -159,10 +168,9 @@ typedef struct { STRING_POOL pool; int complete; int standalone; - const XML_Char *base; -#ifdef EXTERNAL_ENTITY_SUPPORT - const XML_Char *systemId; -#endif +#ifdef XML_DTD + HASH_TABLE paramEntities; +#endif /* XML_DTD */ PREFIX defaultPrefix; } DTD; @@ -182,6 +190,9 @@ static Processor prologProcessor; static Processor prologInitProcessor; static Processor contentProcessor; static Processor cdataSectionProcessor; +#ifdef XML_DTD +static Processor ignoreSectionProcessor; +#endif /* XML_DTD */ static Processor epilogProcessor; static Processor errorProcessor; static Processor externalEntityInitProcessor; @@ -196,10 +207,19 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const c 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); +static enum XML_Error +processInternalParamEntity(XML_Parser parser, ENTITY *entity); +static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *start, const char *end, const char **endPtr); static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); +#ifdef XML_DTD +static enum XML_Error +doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); +#endif /* XML_DTD */ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); static @@ -216,7 +236,7 @@ static ATTRIBUTE_ID * getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); static enum XML_Error -storeEntityValue(XML_Parser parser, const char *start, const char *end); +storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int @@ -230,6 +250,10 @@ static void normalizePublicId(XML_Char *s); static int dtdInit(DTD *); static void dtdDestroy(DTD *); static int dtdCopy(DTD *newDtd, const DTD *oldDtd); +static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); +#ifdef XML_DTD +static void dtdSwap(DTD *, DTD *); +#endif /* XML_DTD */ static void poolInit(STRING_POOL *); static void poolClear(STRING_POOL *); static void poolDestroy(STRING_POOL *); @@ -255,142 +279,152 @@ static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int typedef struct { /* The first member must be userData so that the XML_GetUserData macro works. */ - void *userData; - void *handlerArg; - char *buffer; + void *m_userData; + void *m_handlerArg; + char *m_buffer; /* first character to be parsed */ - const char *bufferPtr; + const char *m_bufferPtr; /* past last character to be parsed */ - char *bufferEnd; + char *m_bufferEnd; /* allocated end of buffer */ - const char *bufferLim; - long parseEndByteIndex; - const char *parseEndPtr; - XML_Char *dataBuf; - XML_Char *dataBufEnd; - XML_StartElementHandler startElementHandler; - XML_EndElementHandler endElementHandler; - XML_CharacterDataHandler characterDataHandler; - XML_ProcessingInstructionHandler processingInstructionHandler; - XML_CommentHandler commentHandler; -#ifdef EXTERNAL_ENTITY_SUPPORT - XML_ExternalDTDLoader externalDTDLoader; + const char *m_bufferLim; + long m_parseEndByteIndex; + const char *m_parseEndPtr; + XML_Char *m_dataBuf; + XML_Char *m_dataBufEnd; + XML_StartElementHandler m_startElementHandler; + XML_EndElementHandler m_endElementHandler; + XML_CharacterDataHandler m_characterDataHandler; + XML_ProcessingInstructionHandler m_processingInstructionHandler; + XML_CommentHandler m_commentHandler; + XML_StartCdataSectionHandler m_startCdataSectionHandler; + XML_EndCdataSectionHandler m_endCdataSectionHandler; + XML_DefaultHandler m_defaultHandler; + XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; + XML_NotationDeclHandler m_notationDeclHandler; + XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; + XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; + XML_NotStandaloneHandler m_notStandaloneHandler; + XML_ExternalEntityRefHandler m_externalEntityRefHandler; + void *m_externalEntityRefHandlerArg; + XML_UnknownEncodingHandler m_unknownEncodingHandler; + const ENCODING *m_encoding; + INIT_ENCODING m_initEncoding; + const ENCODING *m_internalEncoding; + const XML_Char *m_protocolEncodingName; + int m_ns; + void *m_unknownEncodingMem; + void *m_unknownEncodingData; + void *m_unknownEncodingHandlerData; + void (*m_unknownEncodingRelease)(void *); + PROLOG_STATE m_prologState; + Processor *m_processor; + enum XML_Error m_errorCode; + const char *m_eventPtr; + const char *m_eventEndPtr; + const char *m_positionPtr; + OPEN_INTERNAL_ENTITY *m_openInternalEntities; + int m_defaultExpandInternalEntities; + int m_tagLevel; + ENTITY *m_declEntity; + const XML_Char *m_declNotationName; + const XML_Char *m_declNotationPublicId; + ELEMENT_TYPE *m_declElementType; + ATTRIBUTE_ID *m_declAttributeId; + char m_declAttributeIsCdata; + DTD m_dtd; + const XML_Char *m_curBase; + TAG *m_tagStack; + TAG *m_freeTagList; + BINDING *m_inheritedBindings; + BINDING *m_freeBindingList; + int m_attsSize; + int m_nSpecifiedAtts; + ATTRIBUTE *m_atts; + POSITION m_position; + STRING_POOL m_tempPool; + STRING_POOL m_temp2Pool; + char *m_groupConnector; + unsigned m_groupSize; + int m_hadExternalDoctype; + XML_Char m_namespaceSeparator; +#ifdef XML_DTD + enum XML_ParamEntityParsing m_paramEntityParsing; + XML_Parser m_parentParser; #endif - XML_StartCdataSectionHandler startCdataSectionHandler; - XML_EndCdataSectionHandler endCdataSectionHandler; - XML_DefaultHandler defaultHandler; - XML_UnparsedEntityDeclHandler unparsedEntityDeclHandler; - XML_NotationDeclHandler notationDeclHandler; - XML_StartNamespaceDeclHandler startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler endNamespaceDeclHandler; - XML_ExternalEntityRefHandler externalEntityRefHandler; - void *externalEntityRefHandlerArg; - XML_UnknownEncodingHandler unknownEncodingHandler; - const ENCODING *parserEncoding; - INIT_ENCODING initEncoding; - const XML_Char *protocolEncodingName; - int ns; - void *unknownEncodingMem; - void *unknownEncodingData; - void *unknownEncodingHandlerData; - void (*unknownEncodingRelease)(void *); - PROLOG_STATE prologState; - Processor *processor; - enum XML_Error errorCode; - const char *eventPtr; - const char *eventEndPtr; - const char *positionPtr; - OPEN_INTERNAL_ENTITY *openInternalEntities; - int defaultExpandInternalEntities; - int tagLevel; - ENTITY *declEntity; - const XML_Char *declNotationName; - const XML_Char *declNotationPublicId; - ELEMENT_TYPE *declElementType; - ATTRIBUTE_ID *declAttributeId; - char declAttributeIsCdata; - DTD dtd; - TAG *tagStack; - TAG *freeTagList; - BINDING *inheritedBindings; - BINDING *freeBindingList; - int attsSize; - ATTRIBUTE *atts; - POSITION position; - STRING_POOL tempPool; - STRING_POOL temp2Pool; - char *groupConnector; - unsigned groupSize; - int hadExternalDoctype; - XML_Char namespaceSeparator; } Parser; -#define userData (((Parser *)parser)->userData) -#define handlerArg (((Parser *)parser)->handlerArg) -#define startElementHandler (((Parser *)parser)->startElementHandler) -#define endElementHandler (((Parser *)parser)->endElementHandler) -#define characterDataHandler (((Parser *)parser)->characterDataHandler) -#define processingInstructionHandler (((Parser *)parser)->processingInstructionHandler) -#define commentHandler (((Parser *)parser)->commentHandler) -#ifdef EXTERNAL_ENTITY_SUPPORT -#define externalDTDLoader (((Parser *)parser)->externalDTDLoader) -#endif -#define startCdataSectionHandler (((Parser *)parser)->startCdataSectionHandler) -#define endCdataSectionHandler (((Parser *)parser)->endCdataSectionHandler) -#define defaultHandler (((Parser *)parser)->defaultHandler) -#define unparsedEntityDeclHandler (((Parser *)parser)->unparsedEntityDeclHandler) -#define notationDeclHandler (((Parser *)parser)->notationDeclHandler) -#define startNamespaceDeclHandler (((Parser *)parser)->startNamespaceDeclHandler) -#define endNamespaceDeclHandler (((Parser *)parser)->endNamespaceDeclHandler) -#define externalEntityRefHandler (((Parser *)parser)->externalEntityRefHandler) -#define externalEntityRefHandlerArg (((Parser *)parser)->externalEntityRefHandlerArg) -#define unknownEncodingHandler (((Parser *)parser)->unknownEncodingHandler) -#define encoding (((Parser *)parser)->parserEncoding) -#define initEncoding (((Parser *)parser)->initEncoding) -#define unknownEncodingMem (((Parser *)parser)->unknownEncodingMem) -#define unknownEncodingData (((Parser *)parser)->unknownEncodingData) +#define userData (((Parser *)parser)->m_userData) +#define handlerArg (((Parser *)parser)->m_handlerArg) +#define startElementHandler (((Parser *)parser)->m_startElementHandler) +#define endElementHandler (((Parser *)parser)->m_endElementHandler) +#define characterDataHandler (((Parser *)parser)->m_characterDataHandler) +#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler) +#define commentHandler (((Parser *)parser)->m_commentHandler) +#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler) +#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler) +#define defaultHandler (((Parser *)parser)->m_defaultHandler) +#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler) +#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler) +#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler) +#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler) +#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler) +#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler) +#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg) +#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler) +#define encoding (((Parser *)parser)->m_encoding) +#define initEncoding (((Parser *)parser)->m_initEncoding) +#define internalEncoding (((Parser *)parser)->m_internalEncoding) +#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem) +#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData) #define unknownEncodingHandlerData \ - (((Parser *)parser)->unknownEncodingHandlerData) -#define unknownEncodingRelease (((Parser *)parser)->unknownEncodingRelease) -#define protocolEncodingName (((Parser *)parser)->protocolEncodingName) -#define ns (((Parser *)parser)->ns) -#define prologState (((Parser *)parser)->prologState) -#define processor (((Parser *)parser)->processor) -#define errorCode (((Parser *)parser)->errorCode) -#define eventPtr (((Parser *)parser)->eventPtr) -#define eventEndPtr (((Parser *)parser)->eventEndPtr) -#define positionPtr (((Parser *)parser)->positionPtr) -#define position (((Parser *)parser)->position) -#define openInternalEntities (((Parser *)parser)->openInternalEntities) -#define defaultExpandInternalEntities (((Parser *)parser)->defaultExpandInternalEntities) -#define tagLevel (((Parser *)parser)->tagLevel) -#define buffer (((Parser *)parser)->buffer) -#define bufferPtr (((Parser *)parser)->bufferPtr) -#define bufferEnd (((Parser *)parser)->bufferEnd) -#define parseEndByteIndex (((Parser *)parser)->parseEndByteIndex) -#define parseEndPtr (((Parser *)parser)->parseEndPtr) -#define bufferLim (((Parser *)parser)->bufferLim) -#define dataBuf (((Parser *)parser)->dataBuf) -#define dataBufEnd (((Parser *)parser)->dataBufEnd) -#define dtd (((Parser *)parser)->dtd) -#define declEntity (((Parser *)parser)->declEntity) -#define declNotationName (((Parser *)parser)->declNotationName) -#define declNotationPublicId (((Parser *)parser)->declNotationPublicId) -#define declElementType (((Parser *)parser)->declElementType) -#define declAttributeId (((Parser *)parser)->declAttributeId) -#define declAttributeIsCdata (((Parser *)parser)->declAttributeIsCdata) -#define freeTagList (((Parser *)parser)->freeTagList) -#define freeBindingList (((Parser *)parser)->freeBindingList) -#define inheritedBindings (((Parser *)parser)->inheritedBindings) -#define tagStack (((Parser *)parser)->tagStack) -#define atts (((Parser *)parser)->atts) -#define attsSize (((Parser *)parser)->attsSize) -#define tempPool (((Parser *)parser)->tempPool) -#define temp2Pool (((Parser *)parser)->temp2Pool) -#define groupConnector (((Parser *)parser)->groupConnector) -#define groupSize (((Parser *)parser)->groupSize) -#define hadExternalDoctype (((Parser *)parser)->hadExternalDoctype) -#define namespaceSeparator (((Parser *)parser)->namespaceSeparator) + (((Parser *)parser)->m_unknownEncodingHandlerData) +#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease) +#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName) +#define ns (((Parser *)parser)->m_ns) +#define prologState (((Parser *)parser)->m_prologState) +#define processor (((Parser *)parser)->m_processor) +#define errorCode (((Parser *)parser)->m_errorCode) +#define eventPtr (((Parser *)parser)->m_eventPtr) +#define eventEndPtr (((Parser *)parser)->m_eventEndPtr) +#define positionPtr (((Parser *)parser)->m_positionPtr) +#define position (((Parser *)parser)->m_position) +#define openInternalEntities (((Parser *)parser)->m_openInternalEntities) +#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities) +#define tagLevel (((Parser *)parser)->m_tagLevel) +#define buffer (((Parser *)parser)->m_buffer) +#define bufferPtr (((Parser *)parser)->m_bufferPtr) +#define bufferEnd (((Parser *)parser)->m_bufferEnd) +#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex) +#define parseEndPtr (((Parser *)parser)->m_parseEndPtr) +#define bufferLim (((Parser *)parser)->m_bufferLim) +#define dataBuf (((Parser *)parser)->m_dataBuf) +#define dataBufEnd (((Parser *)parser)->m_dataBufEnd) +#define dtd (((Parser *)parser)->m_dtd) +#define curBase (((Parser *)parser)->m_curBase) +#define declEntity (((Parser *)parser)->m_declEntity) +#define declNotationName (((Parser *)parser)->m_declNotationName) +#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId) +#define declElementType (((Parser *)parser)->m_declElementType) +#define declAttributeId (((Parser *)parser)->m_declAttributeId) +#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata) +#define freeTagList (((Parser *)parser)->m_freeTagList) +#define freeBindingList (((Parser *)parser)->m_freeBindingList) +#define inheritedBindings (((Parser *)parser)->m_inheritedBindings) +#define tagStack (((Parser *)parser)->m_tagStack) +#define atts (((Parser *)parser)->m_atts) +#define attsSize (((Parser *)parser)->m_attsSize) +#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts) +#define tempPool (((Parser *)parser)->m_tempPool) +#define temp2Pool (((Parser *)parser)->m_temp2Pool) +#define groupConnector (((Parser *)parser)->m_groupConnector) +#define groupSize (((Parser *)parser)->m_groupSize) +#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype) +#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator) +#ifdef XML_DTD +#define parentParser (((Parser *)parser)->m_parentParser) +#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing) +#endif /* XML_DTD */ #ifdef _MSC_VER #ifdef _DEBUG @@ -415,9 +449,6 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) characterDataHandler = 0; processingInstructionHandler = 0; commentHandler = 0; -#ifdef EXTERNAL_ENTITY_SUPPORT - externalDTDLoader = 0; -#endif startCdataSectionHandler = 0; endCdataSectionHandler = 0; defaultHandler = 0; @@ -425,6 +456,7 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) notationDeclHandler = 0; startNamespaceDeclHandler = 0; endNamespaceDeclHandler = 0; + notStandaloneHandler = 0; externalEntityRefHandler = 0; externalEntityRefHandlerArg = parser; unknownEncodingHandler = 0; @@ -452,6 +484,7 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) inheritedBindings = 0; attsSize = INIT_ATTS_SIZE; atts = malloc(attsSize * sizeof(ATTRIBUTE)); + nSpecifiedAtts = 0; dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); groupSize = 0; groupConnector = 0; @@ -461,10 +494,14 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) unknownEncodingData = 0; unknownEncodingHandlerData = 0; namespaceSeparator = '!'; +#ifdef XML_DTD + parentParser = 0; +#endif ns = 0; poolInit(&tempPool); poolInit(&temp2Pool); protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0; + curBase = 0; if (!dtdInit(&dtd) || !atts || !dataBuf || (encodingName && !protocolEncodingName)) { XML_ParserFree(parser); @@ -472,6 +509,7 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName) } dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; XmlInitEncoding(&initEncoding, &encoding, 0); + internalEncoding = XmlGetInternalEncoding(); return parser; } @@ -495,6 +533,7 @@ XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) if (parser) { XmlInitEncodingNS(&initEncoding, &encoding, 0); ns = 1; + internalEncoding = XmlGetInternalEncodingNS(); namespaceSeparator = nsSep; } if (!setContext(parser, implicitContext)) { @@ -527,21 +566,21 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler; XML_CommentHandler oldCommentHandler = commentHandler; -#ifdef EXTERNAL_ENTITY_SUPPORT - XML_ExternalDTDLoader oldExternalDTDLoader = externalDTDLoader; -#endif XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler; XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler; XML_DefaultHandler oldDefaultHandler = defaultHandler; XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler; XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler; + XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler; XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler; void *oldUserData = userData; void *oldHandlerArg = handlerArg; int oldDefaultExpandInternalEntities = defaultExpandInternalEntities; void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; - +#ifdef XML_DTD + int oldParamEntityParsing = paramEntityParsing; +#endif parser = (ns ? XML_ParserCreateNS(encodingName, namespaceSeparator) : XML_ParserCreate(encodingName)); @@ -552,14 +591,12 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, characterDataHandler = oldCharacterDataHandler; processingInstructionHandler = oldProcessingInstructionHandler; commentHandler = oldCommentHandler; -#ifdef EXTERNAL_ENTITY_SUPPORT - externalDTDLoader = oldExternalDTDLoader; -#endif startCdataSectionHandler = oldStartCdataSectionHandler; endCdataSectionHandler = oldEndCdataSectionHandler; defaultHandler = oldDefaultHandler; startNamespaceDeclHandler = oldStartNamespaceDeclHandler; endNamespaceDeclHandler = oldEndNamespaceDeclHandler; + notStandaloneHandler = oldNotStandaloneHandler; externalEntityRefHandler = oldExternalEntityRefHandler; unknownEncodingHandler = oldUnknownEncodingHandler; userData = oldUserData; @@ -570,11 +607,25 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, if (oldExternalEntityRefHandlerArg != oldParser) externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) { - XML_ParserFree(parser); - return 0; +#ifdef XML_DTD + paramEntityParsing = oldParamEntityParsing; + if (context) { +#endif /* XML_DTD */ + if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) { + XML_ParserFree(parser); + return 0; + } + processor = externalEntityInitProcessor; +#ifdef XML_DTD } - processor = externalEntityInitProcessor; + else { + dtdSwap(&dtd, oldDtd); + parentParser = oldParser; + XmlPrologStateInitExternalEntity(&prologState); + dtd.complete = 1; + hadExternalDoctype = 1; + } +#endif /* XML_DTD */ return parser; } @@ -611,6 +662,13 @@ void XML_ParserFree(XML_Parser parser) destroyBindings(inheritedBindings); poolDestroy(&tempPool); poolDestroy(&temp2Pool); +#ifdef XML_DTD + if (parentParser) { + if (hadExternalDoctype) + dtd.complete = 0; + dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd); + } +#endif /* XML_DTD */ dtdDestroy(&dtd); free((void *)atts); free(groupConnector); @@ -641,16 +699,21 @@ int XML_SetBase(XML_Parser parser, const XML_Char *p) p = poolCopyString(&dtd.pool, p); if (!p) return 0; - dtd.base = p; + curBase = p; } else - dtd.base = 0; + curBase = 0; return 1; } const XML_Char *XML_GetBase(XML_Parser parser) { - return dtd.base; + return curBase; +} + +int XML_GetSpecifiedAttributeCount(XML_Parser parser) +{ + return nSpecifiedAtts; } void XML_SetElementHandler(XML_Parser parser, @@ -679,14 +742,6 @@ void XML_SetCommentHandler(XML_Parser parser, commentHandler = handler; } -#ifdef EXTERNAL_ENTITY_SUPPORT -void XML_SetExternalDTDLoader(XML_Parser parser, - XML_ExternalDTDLoader loader) -{ - externalDTDLoader = loader; -} -#endif - void XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end) @@ -729,6 +784,12 @@ void XML_SetNamespaceDeclHandler(XML_Parser parser, endNamespaceDeclHandler = end; } +void XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler) +{ + notStandaloneHandler = handler; +} + void XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { @@ -751,15 +812,28 @@ void XML_SetUnknownEncodingHandler(XML_Parser parser, unknownEncodingHandlerData = data; } +int XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing) +{ +#ifdef XML_DTD + paramEntityParsing = parsing; + return 1; +#else + return parsing == XML_PARAM_ENTITY_PARSING_NEVER; +#endif +} + int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { if (len == 0) { if (!isFinal) return 1; + positionPtr = bufferPtr; errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); if (errorCode == XML_ERROR_NONE) return 1; eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } else if (bufferPtr == bufferEnd) { @@ -772,11 +846,13 @@ int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) if (errorCode == XML_ERROR_NONE) return 1; eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } errorCode = processor(parser, s, parseEndPtr = s + len, &end); if (errorCode != XML_ERROR_NONE) { eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } XmlUpdatePosition(encoding, positionPtr, end, &position); @@ -785,9 +861,11 @@ int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) if (buffer == 0 || nLeftOver > bufferLim - buffer) { /* FIXME avoid integer overflow */ buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2); + /* FIXME storage leak if realloc fails */ if (!buffer) { errorCode = XML_ERROR_NO_MEMORY; eventPtr = eventEndPtr = 0; + processor = errorProcessor; return 0; } bufferLim = buffer + len * 2; @@ -819,6 +897,7 @@ int XML_ParseBuffer(XML_Parser parser, int len, int isFinal) } else { eventEndPtr = eventPtr; + processor = errorProcessor; return 0; } } @@ -870,6 +949,13 @@ long XML_GetCurrentByteIndex(XML_Parser parser) return -1; } +int XML_GetCurrentByteCount(XML_Parser parser) +{ + if (eventEndPtr && eventPtr) + return eventEndPtr - eventPtr; + return 0; +} + int XML_GetCurrentLineNumber(XML_Parser parser) { if (eventPtr) { @@ -893,7 +979,7 @@ void XML_DefaultCurrent(XML_Parser parser) if (defaultHandler) { if (openInternalEntities) reportDefault(parser, - ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(), + internalEncoding, openInternalEntities->internalEventPtr, openInternalEntities->internalEventEndPtr); else @@ -925,7 +1011,8 @@ const XML_LChar *XML_ErrorString(int code) XML_T("unknown encoding"), XML_T("encoding specified in XML declaration is incorrect"), XML_T("unclosed CDATA section"), - XML_T("error in processing external entity reference") + XML_T("error in processing external entity reference"), + XML_T("document is not standalone") }; if (code > 0 && code < sizeof(message)/sizeof(message[0])) return message[code]; @@ -1039,7 +1126,6 @@ doContent(XML_Parser parser, const char *end, const char **nextPtr) { - const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); const char **eventPP; const char **eventEndPP; if (enc == encoding) { @@ -1052,7 +1138,7 @@ doContent(XML_Parser parser, } *eventPP = s; for (;;) { - const char *next; + const char *next = s; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { @@ -1147,7 +1233,7 @@ doContent(XML_Parser parser, openEntity.internalEventEndPtr = 0; result = doContent(parser, tagLevel, - internalEnc, + internalEncoding, (char *)entity->textPtr, (char *)(entity->textPtr + entity->textLen), 0); @@ -1165,7 +1251,7 @@ doContent(XML_Parser parser, return XML_ERROR_NO_MEMORY; if (!externalEntityRefHandler(externalEntityRefHandlerArg, context, - dtd.base, + entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; @@ -1206,8 +1292,8 @@ doContent(XML_Parser parser, tag->rawName = s + enc->minBytesPerChar; tag->rawNameLength = XmlNameLength(enc, tag->rawName); if (nextPtr) { - /* Need to guarantee that: */ - /* tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */ + /* Need to guarantee that: + tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */ if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) { int bufSize = tag->rawNameLength * 4; bufSize = ROUND_UP(bufSize, sizeof(XML_Char)); @@ -1468,7 +1554,7 @@ doContent(XML_Parser parser, otherwise just check the attributes for well-formedness. */ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, - const char *s, TAG_NAME *tagNamePtr, + const char *attStr, TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { ELEMENT_TYPE *elementType = 0; @@ -1495,7 +1581,7 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, } nDefaultAtts = elementType->nDefaultAtts; } - n = XmlGetAttributes(enc, s, attsSize, atts); + n = XmlGetAttributes(enc, attStr, attsSize, atts); if (n + nDefaultAtts > attsSize) { int oldAttsSize = attsSize; attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; @@ -1503,7 +1589,7 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, if (!atts) return XML_ERROR_NO_MEMORY; if (n > oldAttsSize) - XmlGetAttributes(enc, s, n, atts); + XmlGetAttributes(enc, attStr, n, atts); } appAtts = (const XML_Char **)atts; for (i = 0; i < n; i++) { @@ -1566,6 +1652,7 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, else attIndex++; } + nSpecifiedAtts = attIndex; if (tagNamePtr) { int j; for (j = 0; j < nDefaultAtts; j++) { @@ -1818,6 +1905,83 @@ enum XML_Error doCdataSection(XML_Parser parser, /* not reached */ } +#ifdef XML_DTD + +/* The idea here is to avoid using stack for each IGNORE section when +the whole file is parsed with one call. */ + +static +enum XML_Error ignoreSectionProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr); + if (start) { + processor = prologProcessor; + return prologProcessor(parser, start, end, endPtr); + } + return result; +} + +/* startPtr gets set to non-null is the section is closed, and to null if +the section is not yet closed. */ + +static +enum XML_Error doIgnoreSection(XML_Parser parser, + const ENCODING *enc, + const char **startPtr, + const char *end, + const char **nextPtr) +{ + const char *next; + int tok; + const char *s = *startPtr; + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + *eventPP = s; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } + *eventPP = s; + *startPtr = 0; + tok = XmlIgnoreSectionTok(enc, s, end, &next); + *eventEndPP = next; + switch (tok) { + case XML_TOK_IGNORE_SECT: + if (defaultHandler) + reportDefault(parser, enc, s, next); + *startPtr = next; + return XML_ERROR_NONE; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ + default: + abort(); + } + /* not reached */ +} + +#endif /* XML_DTD */ + static enum XML_Error initializeEncoding(XML_Parser parser) { @@ -1868,8 +2032,13 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, &newEncoding, &standalone)) return XML_ERROR_SYNTAX; - if (!isGeneralTextEntity && standalone == 1) + if (!isGeneralTextEntity && standalone == 1) { dtd.standalone = 1; +#ifdef XML_DTD + if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) + paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif /* XML_DTD */ + } if (defaultHandler) reportDefault(parser, encoding, s, next); if (!protocolEncodingName) { @@ -1956,15 +2125,38 @@ prologProcessor(XML_Parser parser, const char *end, const char **nextPtr) { -#ifdef EXTERNAL_ENTITY_SUPPORT - char * dtdData; - char * dtdNext; - int dtdLen; -#endif + const char *next; + int tok = XmlPrologTok(encoding, s, end, &next); + return doProlog(parser, encoding, s, end, tok, next, nextPtr); +} +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) +{ +#ifdef XML_DTD + static const XML_Char externalSubsetName[] = { '#' , '\0' }; +#endif /* XML_DTD */ + + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } for (;;) { - const char *next; - int tok = XmlPrologTok(encoding, s, end, &next); + int role; + *eventPP = s; + *eventEndPP = next; if (tok <= 0) { if (nextPtr != 0 && tok != XML_TOK_INVALID) { *nextPtr = s; @@ -1972,22 +2164,33 @@ prologProcessor(XML_Parser parser, } switch (tok) { case XML_TOK_INVALID: - eventPtr = next; + *eventPP = next; return XML_ERROR_INVALID_TOKEN; - case XML_TOK_NONE: - return XML_ERROR_NO_ELEMENTS; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_TRAILING_CR: - eventPtr = s + encoding->minBytesPerChar; + case XML_TOK_NONE: +#ifdef XML_DTD + if (enc != encoding) + return XML_ERROR_NONE; + if (parentParser) { + if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) + == XML_ROLE_ERROR) + return XML_ERROR_SYNTAX; + hadExternalDoctype = 0; + return XML_ERROR_NONE; + } +#endif /* XML_DTD */ return XML_ERROR_NO_ELEMENTS; default: - abort(); + tok = -tok; + next = end; + break; } } - switch (XmlTokenRole(&prologState, tok, s, next, encoding)) { + role = XmlTokenRole(&prologState, tok, s, next, enc); + switch (role) { case XML_ROLE_XML_DECL: { enum XML_Error result = processXmlDecl(parser, 0, s, next); @@ -1995,46 +2198,32 @@ prologProcessor(XML_Parser parser, return result; } break; - case XML_ROLE_DOCTYPE_SYSTEM_ID: -#ifdef EXTERNAL_ENTITY_SUPPORT - dtd.systemId = poolStoreString(&dtd.pool, encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); - if (!dtd.systemId) - return XML_ERROR_NO_MEMORY; - poolFinish(&dtd.pool); -#endif - hadExternalDoctype = 1; - break; -#ifdef EXTERNAL_ENTITY_SUPPORT - case XML_ROLE_DOCTYPE_CLOSE: - if (hadExternalDoctype == 1) { - // if no loader specified, just default (non-hacked) processing - if (externalDTDLoader) { - XmlPrologStateHack(&prologState); - hadExternalDoctype = 0; - - dtdLen = externalDTDLoader(dtd.base, dtd.systemId, &dtdData); - if (dtdLen < 0) { - return XML_ERROR_NO_MEMORY; - } - // XXX better error processing - dtdNext = dtdData + dtdLen; - prologProcessor(parser, dtdData, dtdNext, &dtdNext); - // XXX better error processing - } +#ifdef XML_DTD + case XML_ROLE_TEXT_DECL: + { + enum XML_Error result = processXmlDecl(parser, 1, s, next); + if (result != XML_ERROR_NONE) + return result; } break; -#endif +#endif /* XML_DTD */ case XML_ROLE_DOCTYPE_PUBLIC_ID: +#ifdef XML_DTD + declEntity = (ENTITY *)lookup(&dtd.paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; +#endif /* XML_DTD */ + /* fall through */ case XML_ROLE_ENTITY_PUBLIC_ID: - if (!XmlIsPublicId(encoding, s, next, &eventPtr)) + if (!XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_SYNTAX; if (declEntity) { XML_Char *tem = poolStoreString(&dtd.pool, - encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); @@ -2042,14 +2231,35 @@ prologProcessor(XML_Parser parser, poolFinish(&dtd.pool); } break; + case XML_ROLE_DOCTYPE_CLOSE: + if (dtd.complete && hadExternalDoctype) { + dtd.complete = 0; +#ifdef XML_DTD + if (paramEntityParsing && externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities, + externalSubsetName, + 0); + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + } +#endif /* XML_DTD */ + if (!dtd.complete + && !dtd.standalone + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; + } + break; case XML_ROLE_INSTANCE_START: processor = contentProcessor; - if (hadExternalDoctype) - dtd.complete = 0; return contentProcessor(parser, s, end, nextPtr); case XML_ROLE_ATTLIST_ELEMENT_NAME: { - const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next); + const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); if (!name) return XML_ERROR_NO_MEMORY; declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); @@ -2065,7 +2275,7 @@ prologProcessor(XML_Parser parser, break; } case XML_ROLE_ATTRIBUTE_NAME: - declAttributeId = getAttributeId(parser, encoding, s, next); + declAttributeId = getAttributeId(parser, enc, s, next); if (!declAttributeId) return XML_ERROR_NO_MEMORY; declAttributeIsCdata = 0; @@ -2084,9 +2294,9 @@ prologProcessor(XML_Parser parser, { const XML_Char *attVal; enum XML_Error result - = storeAttributeValue(parser, encoding, declAttributeIsCdata, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar, + = storeAttributeValue(parser, enc, declAttributeIsCdata, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar, &dtd.pool); if (result) return result; @@ -2099,30 +2309,60 @@ prologProcessor(XML_Parser parser, } case XML_ROLE_ENTITY_VALUE: { - enum XML_Error result = storeEntityValue(parser, s, next); + enum XML_Error result = storeEntityValue(parser, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (declEntity) { + declEntity->textPtr = poolStart(&dtd.pool); + declEntity->textLen = poolLength(&dtd.pool); + poolFinish(&dtd.pool); + } + else + poolDiscard(&dtd.pool); if (result != XML_ERROR_NONE) return result; } break; + case XML_ROLE_DOCTYPE_SYSTEM_ID: + if (!dtd.standalone +#ifdef XML_DTD + && !paramEntityParsing +#endif /* XML_DTD */ + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; + hadExternalDoctype = 1; +#ifndef XML_DTD + break; +#else /* XML_DTD */ + if (!declEntity) { + declEntity = (ENTITY *)lookup(&dtd.paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + } + /* fall through */ +#endif /* XML_DTD */ case XML_ROLE_ENTITY_SYSTEM_ID: if (declEntity) { - declEntity->systemId = poolStoreString(&dtd.pool, encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + declEntity->systemId = poolStoreString(&dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!declEntity->systemId) return XML_ERROR_NO_MEMORY; - declEntity->base = dtd.base; + declEntity->base = curBase; poolFinish(&dtd.pool); } break; case XML_ROLE_ENTITY_NOTATION_NAME: if (declEntity) { - declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next); + declEntity->notation = poolStoreString(&dtd.pool, enc, s, next); if (!declEntity->notation) return XML_ERROR_NO_MEMORY; poolFinish(&dtd.pool); if (unparsedEntityDeclHandler) { - eventPtr = eventEndPtr = s; + *eventEndPP = s; unparsedEntityDeclHandler(handlerArg, declEntity->name, declEntity->base, @@ -2136,11 +2376,11 @@ prologProcessor(XML_Parser parser, case XML_ROLE_GENERAL_ENTITY_NAME: { const XML_Char *name; - if (XmlPredefinedEntityName(encoding, s, next)) { + if (XmlPredefinedEntityName(enc, s, next)) { declEntity = 0; break; } - name = poolStoreString(&dtd.pool, encoding, s, next); + name = poolStoreString(&dtd.pool, enc, s, next); if (!name) return XML_ERROR_NO_MEMORY; if (dtd.complete) { @@ -2161,26 +2401,43 @@ prologProcessor(XML_Parser parser, } break; case XML_ROLE_PARAM_ENTITY_NAME: +#ifdef XML_DTD + if (dtd.complete) { + const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); + if (!name) + return XML_ERROR_NO_MEMORY; + declEntity = (ENTITY *)lookup(&dtd.paramEntities, name, sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + if (declEntity->name != name) { + poolDiscard(&dtd.pool); + declEntity = 0; + } + else + poolFinish(&dtd.pool); + } +#else /* not XML_DTD */ declEntity = 0; +#endif /* not XML_DTD */ break; case XML_ROLE_NOTATION_NAME: declNotationPublicId = 0; declNotationName = 0; if (notationDeclHandler) { - declNotationName = poolStoreString(&tempPool, encoding, s, next); + declNotationName = poolStoreString(&tempPool, enc, s, next); if (!declNotationName) return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); } break; case XML_ROLE_NOTATION_PUBLIC_ID: - if (!XmlIsPublicId(encoding, s, next, &eventPtr)) + if (!XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_SYNTAX; if (declNotationName) { XML_Char *tem = poolStoreString(&tempPool, - encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); @@ -2191,15 +2448,15 @@ prologProcessor(XML_Parser parser, case XML_ROLE_NOTATION_SYSTEM_ID: if (declNotationName && notationDeclHandler) { const XML_Char *systemId - = poolStoreString(&tempPool, encoding, - s + encoding->minBytesPerChar, - next - encoding->minBytesPerChar); + = poolStoreString(&tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); if (!systemId) return XML_ERROR_NO_MEMORY; - eventPtr = eventEndPtr = s; + *eventEndPP = s; notationDeclHandler(handlerArg, declNotationName, - dtd.base, + curBase, systemId, declNotationPublicId); } @@ -2207,17 +2464,16 @@ prologProcessor(XML_Parser parser, break; case XML_ROLE_NOTATION_NO_SYSTEM_ID: if (declNotationPublicId && notationDeclHandler) { - eventPtr = eventEndPtr = s; + *eventEndPP = s; notationDeclHandler(handlerArg, declNotationName, - dtd.base, + curBase, 0, declNotationPublicId); } poolClear(&tempPool); break; case XML_ROLE_ERROR: - eventPtr = s; switch (tok) { case XML_TOK_PARAM_ENTITY_REF: return XML_ERROR_PARAM_ENTITY_REF; @@ -2226,6 +2482,20 @@ prologProcessor(XML_Parser parser, default: return XML_ERROR_SYNTAX; } +#ifdef XML_DTD + case XML_ROLE_IGNORE_SECT: + { + enum XML_Error result; + if (defaultHandler) + reportDefault(parser, enc, s, next); + result = doIgnoreSection(parser, enc, &next, end, nextPtr); + if (!next) { + processor = ignoreSectionProcessor; + return result; + } + } + break; +#endif /* XML_DTD */ case XML_ROLE_GROUP_OPEN: if (prologState.level >= groupSize) { if (groupSize) @@ -2238,34 +2508,77 @@ prologProcessor(XML_Parser parser, groupConnector[prologState.level] = 0; break; case XML_ROLE_GROUP_SEQUENCE: - if (groupConnector[prologState.level] == '|') { - eventPtr = s; + if (groupConnector[prologState.level] == '|') return XML_ERROR_SYNTAX; - } groupConnector[prologState.level] = ','; break; case XML_ROLE_GROUP_CHOICE: - if (groupConnector[prologState.level] == ',') { - eventPtr = s; + if (groupConnector[prologState.level] == ',') return XML_ERROR_SYNTAX; - } groupConnector[prologState.level] = '|'; break; case XML_ROLE_PARAM_ENTITY_REF: +#ifdef XML_DTD + case XML_ROLE_INNER_PARAM_ENTITY_REF: + if (paramEntityParsing + && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) { + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); + poolDiscard(&dtd.pool); + if (!entity) { + /* FIXME what to do if !dtd.complete? */ + return XML_ERROR_UNDEFINED_ENTITY; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->textPtr) { + enum XML_Error result; + result = processInternalParamEntity(parser, entity); + if (result != XML_ERROR_NONE) + return result; + break; + } + if (role == XML_ROLE_INNER_PARAM_ENTITY_REF) + return XML_ERROR_PARAM_ENTITY_REF; + if (externalEntityRefHandler) { + dtd.complete = 0; + entity->open = 1; + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) { + entity->open = 0; + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + } + entity->open = 0; + if (dtd.complete) + break; + } + } +#endif /* XML_DTD */ + if (!dtd.standalone + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; dtd.complete = 0; + if (defaultHandler) + reportDefault(parser, enc, s, next); break; case XML_ROLE_NONE: switch (tok) { case XML_TOK_PI: - eventPtr = s; - eventEndPtr = next; - if (!reportProcessingInstruction(parser, encoding, s, next)) + if (!reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: - eventPtr = s; - eventEndPtr = next; - if (!reportComment(parser, encoding, s, next)) + if (!reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; } @@ -2277,14 +2590,15 @@ prologProcessor(XML_Parser parser, case XML_TOK_COMMENT: case XML_TOK_BOM: case XML_TOK_XML_DECL: + case XML_TOK_IGNORE_SECT: + case XML_TOK_PARAM_ENTITY_REF: break; default: - eventPtr = s; - eventEndPtr = next; - reportDefault(parser, encoding, s, next); + reportDefault(parser, enc, s, next); } } s = next; + tok = XmlPrologTok(enc, s, end, &next); } /* not reached */ } @@ -2302,7 +2616,7 @@ enum XML_Error epilogProcessor(XML_Parser parser, int tok = XmlPrologTok(encoding, s, end, &next); eventEndPtr = next; switch (tok) { - case XML_TOK_TRAILING_CR: + case -XML_TOK_PROLOG_S: if (defaultHandler) { eventEndPtr = end; reportDefault(parser, encoding, s, end); @@ -2346,6 +2660,32 @@ enum XML_Error epilogProcessor(XML_Parser parser, } } +#ifdef XML_DTD + +static enum XML_Error +processInternalParamEntity(XML_Parser parser, ENTITY *entity) +{ + const char *s, *end, *next; + int tok; + enum XML_Error result; + OPEN_INTERNAL_ENTITY openEntity; + entity->open = 1; + openEntity.next = openInternalEntities; + openInternalEntities = &openEntity; + openEntity.entity = entity; + openEntity.internalEventPtr = 0; + openEntity.internalEventEndPtr = 0; + 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 = 0; + openInternalEntities = openEntity.next; + return result; +} + +#endif /* XML_DTD */ + static enum XML_Error errorProcessor(XML_Parser parser, const char *s, @@ -2375,7 +2715,6 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, const char *ptr, const char *end, STRING_POOL *pool) { - const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); for (;;) { const char *next; int tok = XmlAttributeValueTok(enc, ptr, end, &next); @@ -2476,7 +2815,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, enum XML_Error result; const XML_Char *textEnd = entity->textPtr + entity->textLen; entity->open = 1; - result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); + result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); entity->open = 0; if (result) return result; @@ -2493,36 +2832,65 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, static enum XML_Error storeEntityValue(XML_Parser parser, + const ENCODING *enc, const char *entityTextPtr, const char *entityTextEnd) { - const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); STRING_POOL *pool = &(dtd.pool); - entityTextPtr += encoding->minBytesPerChar; - entityTextEnd -= encoding->minBytesPerChar; for (;;) { const char *next; - int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next); + int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); switch (tok) { case XML_TOK_PARAM_ENTITY_REF: +#ifdef XML_DTD + if (parentParser || enc != encoding) { + enum XML_Error result; + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&tempPool, enc, + entityTextPtr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); + poolDiscard(&tempPool); + if (!entity) { + if (enc == encoding) + eventPtr = entityTextPtr; + return XML_ERROR_UNDEFINED_ENTITY; + } + if (entity->open) { + if (enc == encoding) + eventPtr = entityTextPtr; + return XML_ERROR_RECURSIVE_ENTITY_REF; + } + if (entity->systemId) { + if (enc == encoding) + eventPtr = entityTextPtr; + return XML_ERROR_PARAM_ENTITY_REF; + } + entity->open = 1; + result = storeEntityValue(parser, + internalEncoding, + (char *)entity->textPtr, + (char *)(entity->textPtr + entity->textLen)); + entity->open = 0; + if (result) + return result; + break; + } +#endif /* XML_DTD */ eventPtr = entityTextPtr; return XML_ERROR_SYNTAX; case XML_TOK_NONE: - if (declEntity) { - declEntity->textPtr = pool->start; - declEntity->textLen = pool->ptr - pool->start; - poolFinish(pool); - } - else - poolDiscard(pool); return XML_ERROR_NONE; case XML_TOK_ENTITY_REF: case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, encoding, entityTextPtr, next)) + if (!poolAppend(pool, enc, entityTextPtr, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_TRAILING_CR: - next = entityTextPtr + encoding->minBytesPerChar; + next = entityTextPtr + enc->minBytesPerChar; /* fall through */ case XML_TOK_DATA_NEWLINE: if (pool->end == pool->ptr && !poolGrow(pool)) @@ -2533,14 +2901,16 @@ enum XML_Error storeEntityValue(XML_Parser parser, { XML_Char buf[XML_ENCODE_MAX]; int i; - int n = XmlCharRefNumber(encoding, entityTextPtr); + int n = XmlCharRefNumber(enc, entityTextPtr); if (n < 0) { - eventPtr = entityTextPtr; + if (enc == encoding) + eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } n = XmlEncode(n, (ICHAR *)buf); if (!n) { - eventPtr = entityTextPtr; + if (enc == encoding) + eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } for (i = 0; i < n; i++) { @@ -2551,10 +2921,12 @@ enum XML_Error storeEntityValue(XML_Parser parser, } break; case XML_TOK_PARTIAL: - eventPtr = entityTextPtr; + if (enc == encoding) + eventPtr = entityTextPtr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_INVALID: - eventPtr = next; + if (enc == encoding) + eventPtr = next; return XML_ERROR_INVALID_TOKEN; default: abort(); @@ -2667,6 +3039,14 @@ static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value) { DEFAULT_ATTRIBUTE *att; + if (value) { + /* The handling of default attributes gets messed up if we have + a default which duplicates a non-default. */ + int i; + for (i = 0; i < type->nDefaultAtts; i++) + if (attId == type->defaultAtts[i].id) + return 1; + } if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; @@ -2929,12 +3309,26 @@ static int dtdInit(DTD *p) hashTableInit(&(p->prefixes)); p->complete = 1; p->standalone = 0; - p->base = 0; +#ifdef XML_DTD + hashTableInit(&(p->paramEntities)); +#endif /* XML_DTD */ p->defaultPrefix.name = 0; p->defaultPrefix.binding = 0; return 1; } +#ifdef XML_DTD + +static void dtdSwap(DTD *p1, DTD *p2) +{ + DTD tem; + memcpy(&tem, p1, sizeof(DTD)); + memcpy(p1, p2, sizeof(DTD)); + memcpy(p2, &tem, sizeof(DTD)); +} + +#endif /* XML_DTD */ + static void dtdDestroy(DTD *p) { HASH_TABLE_ITER iter; @@ -2947,6 +3341,9 @@ static void dtdDestroy(DTD *p) free(e->defaultAtts); } hashTableDestroy(&(p->generalEntities)); +#ifdef XML_DTD + hashTableDestroy(&(p->paramEntities)); +#endif /* XML_DTD */ hashTableDestroy(&(p->elementTypes)); hashTableDestroy(&(p->attributeIds)); hashTableDestroy(&(p->prefixes)); @@ -2960,13 +3357,6 @@ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) { HASH_TABLE_ITER iter; - if (oldDtd->base) { - const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base); - if (!tem) - return 0; - newDtd->base = tem; - } - /* Copy the prefix table. */ hashTableIterInit(&iter, &(oldDtd->prefixes)); @@ -3051,9 +3441,33 @@ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) } } - /* Copy the entity table. */ + /* Copy the entity tables. */ + if (!copyEntityTable(&(newDtd->generalEntities), + &(newDtd->pool), + &(oldDtd->generalEntities))) + return 0; - hashTableIterInit(&iter, &(oldDtd->generalEntities)); +#ifdef XML_DTD + if (!copyEntityTable(&(newDtd->paramEntities), + &(newDtd->pool), + &(oldDtd->paramEntities))) + return 0; +#endif /* XML_DTD */ + + newDtd->complete = oldDtd->complete; + newDtd->standalone = oldDtd->standalone; + return 1; +} + +static int copyEntityTable(HASH_TABLE *newTable, + STRING_POOL *newPool, + const HASH_TABLE *oldTable) +{ + HASH_TABLE_ITER iter; + const XML_Char *cachedOldBase = 0; + const XML_Char *cachedNewBase = 0; + + hashTableIterInit(&iter, oldTable); for (;;) { ENTITY *newE; @@ -3061,43 +3475,43 @@ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); if (!oldE) break; - name = poolCopyString(&(newDtd->pool), oldE->name); + name = poolCopyString(newPool, oldE->name); if (!name) return 0; - newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY)); + newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); if (!newE) return 0; if (oldE->systemId) { - const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId); + const XML_Char *tem = poolCopyString(newPool, oldE->systemId); if (!tem) return 0; newE->systemId = tem; if (oldE->base) { - if (oldE->base == oldDtd->base) - newE->base = newDtd->base; - tem = poolCopyString(&(newDtd->pool), oldE->base); - if (!tem) - return 0; - newE->base = tem; + if (oldE->base == cachedOldBase) + newE->base = cachedNewBase; + else { + cachedOldBase = oldE->base; + tem = poolCopyString(newPool, cachedOldBase); + if (!tem) + return 0; + cachedNewBase = newE->base = tem; + } } } else { - const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen); + const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); if (!tem) return 0; newE->textPtr = tem; newE->textLen = oldE->textLen; } if (oldE->notation) { - const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation); + const XML_Char *tem = poolCopyString(newPool, oldE->notation); if (!tem) return 0; newE->notation = tem; } } - - newDtd->complete = oldDtd->complete; - newDtd->standalone = oldDtd->standalone; return 1; } diff --git a/mozilla/parser/expat/lib/xmlparse.h b/mozilla/parser/expat/lib/xmlparse.h index b34617aab82..8c1d95d0a3d 100644 --- a/mozilla/parser/expat/lib/xmlparse.h +++ b/mozilla/parser/expat/lib/xmlparse.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef XmlParse_INCLUDED @@ -107,13 +117,6 @@ typedef void (*XML_ProcessingInstructionHandler)(void *userData, /* data is 0 terminated */ typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); -/* #define EXTERNAL_ENTITY_SUPPORT */ -#ifdef EXTERNAL_ENTITY_SUPPORT -typedef int (*XML_ExternalDTDLoader)(const XML_Char * base, - const XML_Char * systemId, - char ** data); -#endif - typedef void (*XML_StartCdataSectionHandler)(void *userData); typedef void (*XML_EndCdataSectionHandler)(void *userData); @@ -169,6 +172,14 @@ typedef void (*XML_StartNamespaceDeclHandler)(void *userData, typedef void (*XML_EndNamespaceDeclHandler)(void *userData, const XML_Char *prefix); +/* This is called if the document is not standalone (it has an +external subset or a reference to a parameter entity, but does not +have standalone="yes"). If this handler returns 0, then processing +will not continue, and the parser will return a +XML_ERROR_NOT_STANDALONE error. */ + +typedef int (*XML_NotStandaloneHandler)(void *userData); + /* This is called for a reference to an external parsed general entity. The referenced entity is not automatically parsed. The application can parse it immediately or later using @@ -278,13 +289,6 @@ void XMLPARSEAPI XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); - -#ifdef EXTERNAL_ENTITY_SUPPORT -void XMLPARSEAPI -XML_SetExternalDTDLoader(XML_Parser parser, - XML_ExternalDTDLoader loader); -#endif - void XMLPARSEAPI XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, @@ -317,6 +321,10 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end); +void XMLPARSEAPI +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + void XMLPARSEAPI XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler); @@ -371,6 +379,12 @@ XML_SetBase(XML_Parser parser, const XML_Char *base); const XML_Char XMLPARSEAPI * XML_GetBase(XML_Parser parser); +/* Returns the number of the attributes passed in last call to the +XML_StartElementHandler that were specified in the start-tag rather +than defaulted. */ + +int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser); + /* Parses some input. Returns 0 if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other). */ @@ -396,11 +410,45 @@ so longer as the parser has not yet been freed. The new parser is completely independent and may safely be used in a separate thread. The handlers and userData are initialized from the parser argument. Returns 0 if out of memory. Otherwise returns a new XML_Parser object. */ + +#if 0 +#define XML_DTD +#endif /* 0 */ + XML_Parser XMLPARSEAPI XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, const XML_Char *encoding); +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD +subset). If parsing of parameter entities is enabled, then references +to external parameter entities (including the external DTD subset) +will be passed to the handler set with +XML_SetExternalEntityRefHandler. The context passed will be 0. +Unlike external general entities, external parameter entities can only +be parsed synchronously. If the external parameter entity is to be +parsed, it must be parsed during the call to the external entity ref +handler: the complete sequence of XML_ExternalEntityParserCreate, +XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during +this call. After XML_ExternalEntityParserCreate has been called to +create the parser for the external parameter entity (context must be 0 +for this call), it is illegal to make any calls on the old parser +until XML_ParserFree has been called on the newly created parser. If +the library has been compiled without support for parameter entity +parsing (ie without XML_DTD being defined), then +XML_SetParamEntityParsing will return 0 if parsing of parameter +entities is requested; otherwise it will return non-zero. */ + +int XMLPARSEAPI +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + enum XML_Error { XML_ERROR_NONE, XML_ERROR_NO_MEMORY, @@ -423,7 +471,8 @@ enum XML_Error { XML_ERROR_UNKNOWN_ENCODING, XML_ERROR_INCORRECT_ENCODING, XML_ERROR_UNCLOSED_CDATA_SECTION, - XML_ERROR_EXTERNAL_ENTITY_HANDLING + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE }; /* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode @@ -443,6 +492,11 @@ int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser); int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser); long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser); +/* Return the number of bytes in the current event. +Returns 0 if the event is in an internal entity. */ + +int XMLPARSEAPI XML_GetCurrentByteCount(XML_Parser parser); + /* For backwards compatibility with previous versions. */ #define XML_GetErrorLineNumber XML_GetCurrentLineNumber #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber diff --git a/mozilla/parser/expat/lib/xmlrole.c b/mozilla/parser/expat/lib/xmlrole.c index e07be718066..a8fdda78da2 100644 --- a/mozilla/parser/expat/lib/xmlrole.c +++ b/mozilla/parser/expat/lib/xmlrole.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" @@ -32,7 +42,16 @@ Contributor(s): #define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) #endif -typedef int PROLOG_HANDLER(struct prolog_state *state, +#ifdef XML_DTD +#define setTopLevel(state) \ + ((state)->handler = ((state)->documentEntity \ + ? internalSubset \ + : externalSubset1)) +#else /* not XML_DTD */ +#define setTopLevel(state) ((state)->handler = internalSubset) +#endif /* not XML_DTD */ + +typedef int PROLOG_HANDLER(PROLOG_STATE *state, int tok, const char *ptr, const char *end, @@ -49,11 +68,15 @@ static PROLOG_HANDLER attlist7, attlist8, attlist9, element0, element1, element2, element3, element4, element5, element6, element7, +#ifdef XML_DTD + externalSubset0, externalSubset1, + condSect0, condSect1, condSect2, +#endif /* XML_DTD */ declClose, error; static -int syntaxError(PROLOG_STATE *); +int common(PROLOG_STATE *state, int tok); static int prolog0(PROLOG_STATE *state, @@ -79,6 +102,7 @@ int prolog0(PROLOG_STATE *state, case XML_TOK_DECL_OPEN: if (!XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "DOCTYPE")) break; state->handler = doctype0; @@ -87,7 +111,7 @@ int prolog0(PROLOG_STATE *state, state->handler = error; return XML_ROLE_INSTANCE_START; } - return syntaxError(state); + return common(state, tok); } static @@ -107,6 +131,7 @@ int prolog1(PROLOG_STATE *state, case XML_TOK_DECL_OPEN: if (!XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "DOCTYPE")) break; state->handler = doctype0; @@ -115,7 +140,7 @@ int prolog1(PROLOG_STATE *state, state->handler = error; return XML_ROLE_INSTANCE_START; } - return syntaxError(state); + return common(state, tok); } static @@ -135,7 +160,7 @@ int prolog2(PROLOG_STATE *state, state->handler = error; return XML_ROLE_INSTANCE_START; } - return syntaxError(state); + return common(state, tok); } static @@ -153,7 +178,7 @@ int doctype0(PROLOG_STATE *state, state->handler = doctype1; return XML_ROLE_DOCTYPE_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -173,17 +198,17 @@ int doctype1(PROLOG_STATE *state, state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = doctype3; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = doctype2; return XML_ROLE_NONE; } break; } - return syntaxError(state); + return common(state, tok); } static @@ -200,7 +225,7 @@ int doctype2(PROLOG_STATE *state, state->handler = doctype3; return XML_ROLE_DOCTYPE_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -217,7 +242,7 @@ int doctype3(PROLOG_STATE *state, state->handler = doctype4; return XML_ROLE_DOCTYPE_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -237,7 +262,7 @@ int doctype4(PROLOG_STATE *state, state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } - return syntaxError(state); + return common(state, tok); } static @@ -254,7 +279,7 @@ int doctype5(PROLOG_STATE *state, state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } - return syntaxError(state); + return common(state, tok); } static @@ -270,24 +295,28 @@ int internalSubset(PROLOG_STATE *state, case XML_TOK_DECL_OPEN: if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "ENTITY")) { state->handler = entity0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "ATTLIST")) { state->handler = attlist0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "ELEMENT")) { state->handler = element0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, "NOTATION")) { state->handler = notation0; return XML_ROLE_NONE; @@ -302,9 +331,56 @@ int internalSubset(PROLOG_STATE *state, state->handler = doctype5; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } +#ifdef XML_DTD + +static +int externalSubset0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + state->handler = externalSubset1; + if (tok == XML_TOK_XML_DECL) + return XML_ROLE_TEXT_DECL; + return externalSubset1(state, tok, ptr, end, enc); +} + +static +int externalSubset1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_COND_SECT_OPEN: + state->handler = condSect0; + return XML_ROLE_NONE; + case XML_TOK_COND_SECT_CLOSE: + if (state->includeLevel == 0) + break; + state->includeLevel -= 1; + return XML_ROLE_NONE; + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_BRACKET: + break; + case XML_TOK_NONE: + if (state->includeLevel) + break; + return XML_ROLE_NONE; + default: + return internalSubset(state, tok, ptr, end, enc); + } + return common(state, tok); +} + +#endif /* XML_DTD */ + static int entity0(PROLOG_STATE *state, int tok, @@ -322,7 +398,7 @@ int entity0(PROLOG_STATE *state, state->handler = entity2; return XML_ROLE_GENERAL_ENTITY_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -339,7 +415,7 @@ int entity1(PROLOG_STATE *state, state->handler = entity7; return XML_ROLE_PARAM_ENTITY_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -353,11 +429,11 @@ int entity2(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = entity4; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = entity3; return XML_ROLE_NONE; } @@ -366,7 +442,7 @@ int entity2(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -383,7 +459,7 @@ int entity3(PROLOG_STATE *state, state->handler = entity4; return XML_ROLE_ENTITY_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } @@ -401,7 +477,7 @@ int entity4(PROLOG_STATE *state, state->handler = entity5; return XML_ROLE_ENTITY_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -415,16 +491,16 @@ int entity5(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "NDATA")) { + if (XmlNameMatchesAscii(enc, ptr, end, "NDATA")) { state->handler = entity6; return XML_ROLE_NONE; } break; } - return syntaxError(state); + return common(state, tok); } static @@ -441,7 +517,7 @@ int entity6(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_NOTATION_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -455,11 +531,11 @@ int entity7(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = entity9; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = entity8; return XML_ROLE_NONE; } @@ -468,7 +544,7 @@ int entity7(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -485,7 +561,7 @@ int entity8(PROLOG_STATE *state, state->handler = entity9; return XML_ROLE_ENTITY_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -502,7 +578,7 @@ int entity9(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_ENTITY_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -519,7 +595,7 @@ int notation0(PROLOG_STATE *state, state->handler = notation1; return XML_ROLE_NOTATION_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -533,17 +609,17 @@ int notation1(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + if (XmlNameMatchesAscii(enc, ptr, end, "SYSTEM")) { state->handler = notation3; return XML_ROLE_NONE; } - if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + if (XmlNameMatchesAscii(enc, ptr, end, "PUBLIC")) { state->handler = notation2; return XML_ROLE_NONE; } break; } - return syntaxError(state); + return common(state, tok); } static @@ -560,7 +636,7 @@ int notation2(PROLOG_STATE *state, state->handler = notation4; return XML_ROLE_NOTATION_PUBLIC_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -577,7 +653,7 @@ int notation3(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_NOTATION_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -594,10 +670,10 @@ int notation4(PROLOG_STATE *state, state->handler = declClose; return XML_ROLE_NOTATION_SYSTEM_ID; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NOTATION_NO_SYSTEM_ID; } - return syntaxError(state); + return common(state, tok); } static @@ -615,7 +691,7 @@ int attlist0(PROLOG_STATE *state, state->handler = attlist1; return XML_ROLE_ATTLIST_ELEMENT_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -629,14 +705,14 @@ int attlist1(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist2; return XML_ROLE_ATTRIBUTE_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -663,12 +739,12 @@ int attlist2(PROLOG_STATE *state, }; int i; for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) - if (XmlNameMatchesAscii(enc, ptr, types[i])) { + if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { state->handler = attlist8; return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; } } - if (XmlNameMatchesAscii(enc, ptr, "NOTATION")) { + if (XmlNameMatchesAscii(enc, ptr, end, "NOTATION")) { state->handler = attlist5; return XML_ROLE_NONE; } @@ -677,7 +753,7 @@ int attlist2(PROLOG_STATE *state, state->handler = attlist3; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -696,7 +772,7 @@ int attlist3(PROLOG_STATE *state, state->handler = attlist4; return XML_ROLE_ATTRIBUTE_ENUM_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -716,7 +792,7 @@ int attlist4(PROLOG_STATE *state, state->handler = attlist3; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -733,7 +809,7 @@ int attlist5(PROLOG_STATE *state, state->handler = attlist6; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } @@ -751,7 +827,7 @@ int attlist6(PROLOG_STATE *state, state->handler = attlist7; return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -771,7 +847,7 @@ int attlist7(PROLOG_STATE *state, state->handler = attlist6; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } /* default value */ @@ -788,18 +864,21 @@ int attlist8(PROLOG_STATE *state, case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "IMPLIED")) { state->handler = attlist1; return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "REQUIRED")) { state->handler = attlist1; return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "FIXED")) { state->handler = attlist9; return XML_ROLE_NONE; @@ -809,7 +888,7 @@ int attlist8(PROLOG_STATE *state, state->handler = attlist1; return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -826,7 +905,7 @@ int attlist9(PROLOG_STATE *state, state->handler = attlist1; return XML_ROLE_FIXED_ATTRIBUTE_VALUE; } - return syntaxError(state); + return common(state, tok); } static @@ -844,7 +923,7 @@ int element0(PROLOG_STATE *state, state->handler = element1; return XML_ROLE_ELEMENT_NAME; } - return syntaxError(state); + return common(state, tok); } static @@ -858,11 +937,11 @@ int element1(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, "EMPTY")) { + if (XmlNameMatchesAscii(enc, ptr, end, "EMPTY")) { state->handler = declClose; return XML_ROLE_CONTENT_EMPTY; } - if (XmlNameMatchesAscii(enc, ptr, "ANY")) { + if (XmlNameMatchesAscii(enc, ptr, end, "ANY")) { state->handler = declClose; return XML_ROLE_CONTENT_ANY; } @@ -872,7 +951,7 @@ int element1(PROLOG_STATE *state, state->level = 1; return XML_ROLE_GROUP_OPEN; } - return syntaxError(state); + return common(state, tok); } static @@ -888,6 +967,7 @@ int element2(PROLOG_STATE *state, case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), + end, "PCDATA")) { state->handler = element3; return XML_ROLE_CONTENT_PCDATA; @@ -911,7 +991,7 @@ int element2(PROLOG_STATE *state, state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } - return syntaxError(state); + return common(state, tok); } static @@ -932,7 +1012,7 @@ int element3(PROLOG_STATE *state, state->handler = element4; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -950,7 +1030,7 @@ int element4(PROLOG_STATE *state, state->handler = element5; return XML_ROLE_CONTENT_ELEMENT; } - return syntaxError(state); + return common(state, tok); } static @@ -970,7 +1050,7 @@ int element5(PROLOG_STATE *state, state->handler = element4; return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } static @@ -1000,7 +1080,7 @@ int element6(PROLOG_STATE *state, state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } - return syntaxError(state); + return common(state, tok); } static @@ -1040,9 +1120,72 @@ int element7(PROLOG_STATE *state, state->handler = element6; return XML_ROLE_GROUP_CHOICE; } - return syntaxError(state); + return common(state, tok); } +#ifdef XML_DTD + +static +int condSect0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, "INCLUDE")) { + state->handler = condSect1; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, "IGNORE")) { + state->handler = condSect2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static +int condSect1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + state->includeLevel += 1; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static +int condSect2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + return XML_ROLE_IGNORE_SECT; + } + return common(state, tok); +} + +#endif /* XML_DTD */ + static int declClose(PROLOG_STATE *state, int tok, @@ -1054,10 +1197,10 @@ int declClose(PROLOG_STATE *state, case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; + setTopLevel(state); return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } #if 0 @@ -1076,23 +1219,27 @@ int ignore(PROLOG_STATE *state, default: return XML_ROLE_NONE; } - return syntaxError(state); + return common(state, tok); } #endif static int error(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) { return XML_ROLE_NONE; } static -int syntaxError(PROLOG_STATE *state) +int common(PROLOG_STATE *state, int tok) { +#ifdef XML_DTD + if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) + return XML_ROLE_INNER_PARAM_ENTITY_REF; +#endif state->handler = error; return XML_ROLE_ERROR; } @@ -1100,11 +1247,19 @@ int syntaxError(PROLOG_STATE *state) void XmlPrologStateInit(PROLOG_STATE *state) { state->handler = prolog0; +#ifdef XML_DTD + state->documentEntity = 1; + state->includeLevel = 0; +#endif /* XML_DTD */ } -#ifdef EXTERNAL_ENTITY_SUPPORT -void XmlPrologStateHack(PROLOG_STATE *state) +#ifdef XML_DTD + +void XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { - state->handler = prolog1; + state->handler = externalSubset0; + state->documentEntity = 0; + state->includeLevel = 0; } -#endif + +#endif /* XML_DTD */ diff --git a/mozilla/parser/expat/lib/xmlrole.h b/mozilla/parser/expat/lib/xmlrole.h index 28b245698f6..3e780e7f6e0 100644 --- a/mozilla/parser/expat/lib/xmlrole.h +++ b/mozilla/parser/expat/lib/xmlrole.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef XmlRole_INCLUDED @@ -77,6 +87,11 @@ enum { XML_ROLE_CONTENT_ELEMENT_REP, XML_ROLE_CONTENT_ELEMENT_OPT, XML_ROLE_CONTENT_ELEMENT_PLUS, +#ifdef XML_DTD + XML_ROLE_TEXT_DECL, + XML_ROLE_IGNORE_SECT, + XML_ROLE_INNER_PARAM_ENTITY_REF, +#endif /* XML_DTD */ XML_ROLE_PARAM_ENTITY_REF }; @@ -87,14 +102,16 @@ typedef struct prolog_state { const char *end, const ENCODING *enc); unsigned level; +#ifdef XML_DTD + unsigned includeLevel; + int documentEntity; +#endif /* XML_DTD */ } PROLOG_STATE; void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *); - -/* #define EXTERNAL_ENTITY_SUPPORT */ -#ifdef EXTERNAL_ENTITY_SUPPORT -void XMLTOKAPI XmlPrologStateHack(PROLOG_STATE *); -#endif +#ifdef XML_DTD +void XMLTOKAPI XmlPrologStateInitExternalEntity(PROLOG_STATE *); +#endif /* XML_DTD */ #define XmlTokenRole(state, tok, ptr, end, enc) \ (((state)->handler)(state, tok, ptr, end, enc)) diff --git a/mozilla/parser/expat/lib/xmltok.c b/mozilla/parser/expat/lib/xmltok.c index cd96f00d9dc..7e50a00a8ab 100644 --- a/mozilla/parser/expat/lib/xmltok.c +++ b/mozilla/parser/expat/lib/xmltok.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,18 +12,35 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #include "xmldef.h" #include "xmltok.h" #include "nametab.h" +#ifdef XML_DTD +#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) +#else +#define IGNORE_SECTION_TOK_VTABLE /* as nothing */ +#endif + #define VTABLE1 \ - { PREFIX(prologTok), PREFIX(contentTok), PREFIX(cdataSectionTok) }, \ + { PREFIX(prologTok), PREFIX(contentTok), \ + PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ PREFIX(sameName), \ PREFIX(nameMatchesAscii), \ @@ -658,7 +675,7 @@ int little2_isNmstrtMin(const ENCODING *enc, const char *p) static const struct normal_encoding little2_encoding_ns = { { VTABLE, 2, 0, -#if BYTE_ORDER == 12 +#if XML_BYTE_ORDER == 12 1 #else 0 @@ -675,7 +692,7 @@ static const struct normal_encoding little2_encoding_ns = { static const struct normal_encoding little2_encoding = { { VTABLE, 2, 0, -#if BYTE_ORDER == 12 +#if XML_BYTE_ORDER == 12 1 #else 0 @@ -690,7 +707,7 @@ static const struct normal_encoding little2_encoding = { STANDARD_VTABLE(little2_) }; -#if BYTE_ORDER != 21 +#if XML_BYTE_ORDER != 21 #ifdef XML_NS @@ -797,7 +814,7 @@ int big2_isNmstrtMin(const ENCODING *enc, const char *p) static const struct normal_encoding big2_encoding_ns = { { VTABLE, 2, 0, -#if BYTE_ORDER == 21 +#if XML_BYTE_ORDER == 21 1 #else 0 @@ -814,7 +831,7 @@ static const struct normal_encoding big2_encoding_ns = { static const struct normal_encoding big2_encoding = { { VTABLE, 2, 0, -#if BYTE_ORDER == 21 +#if XML_BYTE_ORDER == 21 1 #else 0 @@ -829,7 +846,7 @@ static const struct normal_encoding big2_encoding = { STANDARD_VTABLE(big2_) }; -#if BYTE_ORDER != 12 +#if XML_BYTE_ORDER != 12 #ifdef XML_NS @@ -916,6 +933,7 @@ int parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, const char **namePtr, + const char **nameEndPtr, const char **valPtr, const char **nextTokPtr) { @@ -943,9 +961,12 @@ int parsePseudoAttribute(const ENCODING *enc, *nextTokPtr = ptr; return 0; } - if (c == '=') + if (c == '=') { + *nameEndPtr = ptr; break; + } if (isSpace(c)) { + *nameEndPtr = ptr; do { ptr += enc->minBytesPerChar; } while (isSpace(c = toAscii(enc, ptr, end))); @@ -1008,13 +1029,14 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, { const char *val = 0; const char *name = 0; + const char *nameEnd = 0; ptr += 5 * enc->minBytesPerChar; end -= 2 * enc->minBytesPerChar; - if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr) || !name) { + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) { *badPtr = ptr; return 0; } - if (!XmlNameMatchesAscii(enc, name, "version")) { + if (!XmlNameMatchesAscii(enc, name, nameEnd, "version")) { if (!isGeneralTextEntity) { *badPtr = name; return 0; @@ -1023,7 +1045,7 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, else { if (versionPtr) *versionPtr = val; - if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } @@ -1036,7 +1058,7 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, return 1; } } - if (XmlNameMatchesAscii(enc, name, "encoding")) { + if (XmlNameMatchesAscii(enc, name, nameEnd, "encoding")) { int c = toAscii(enc, val, end); if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) { *badPtr = val; @@ -1046,22 +1068,22 @@ int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, *encodingName = val; if (encoding) *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); - if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } if (!name) return 1; } - if (!XmlNameMatchesAscii(enc, name, "standalone") || isGeneralTextEntity) { + if (!XmlNameMatchesAscii(enc, name, nameEnd, "standalone") || isGeneralTextEntity) { *badPtr = name; return 0; } - if (XmlNameMatchesAscii(enc, val, "yes")) { + if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, "yes")) { if (standalone) *standalone = 1; } - else if (XmlNameMatchesAscii(enc, val, "no")) { + else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, "no")) { if (standalone) *standalone = 0; } @@ -1158,7 +1180,7 @@ struct unknown_encoding { char utf8[256][4]; }; -int XmlSizeOfUnknownEncoding() +int XmlSizeOfUnknownEncoding(void) { return sizeof(struct unknown_encoding); } @@ -1361,7 +1383,8 @@ int getEncodingIndex(const char *name) /* For binary compatibility, we store the index of the encoding specified at initialization in the isUtf16 member. */ -#define INIT_ENC_INDEX(enc) ((enc)->initEnc.isUtf16) +#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) +#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) /* This is what detects the encoding. encodingTable maps from encoding indices to encodings; @@ -1386,9 +1409,11 @@ int initScan(const ENCODING **encodingTable, encPtr = enc->encPtr; if (ptr + 1 == end) { /* only a single byte available for auto-detection */ +#ifndef XML_DTD /* FIXME */ /* a well-formed document entity must have more than one byte */ if (state != XML_CONTENT_STATE) return XML_TOK_PARTIAL; +#endif /* so we're parsing an external text entity... */ /* if UTF-16 was externally specified, then we need at least 2 bytes */ switch (INIT_ENC_INDEX(enc)) { diff --git a/mozilla/parser/expat/lib/xmltok.h b/mozilla/parser/expat/lib/xmltok.h index dc0364a5031..abf682ade57 100644 --- a/mozilla/parser/expat/lib/xmltok.h +++ b/mozilla/parser/expat/lib/xmltok.h @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef XmlTok_INCLUDED @@ -98,10 +108,26 @@ extern "C" { for a name with a colon. */ #define XML_TOK_PREFIXED_NAME 41 +#if 0 +#define XML_DTD +#endif /* 0 */ + +#ifdef XML_DTD +#define XML_TOK_IGNORE_SECT 42 +#endif /* XML_DTD */ + +#ifdef XML_DTD +#define XML_N_STATES 4 +#else /* not XML_DTD */ #define XML_N_STATES 3 +#endif /* not XML_DTD */ + #define XML_PROLOG_STATE 0 #define XML_CONTENT_STATE 1 #define XML_CDATA_SECTION_STATE 2 +#ifdef XML_DTD +#define XML_IGNORE_SECTION_STATE 3 +#endif /* XML_DTD */ #define XML_N_LITERAL_TYPES 2 #define XML_ATTRIBUTE_VALUE_LITERAL 0 @@ -140,7 +166,7 @@ struct encoding { int (*sameName)(const ENCODING *, const char *, const char *); int (*nameMatchesAscii)(const ENCODING *, - const char *, const char *); + const char *, const char *, const char *); int (*nameLength)(const ENCODING *, const char *); const char *(*skipS)(const ENCODING *, const char *); int (*getAtts)(const ENCODING *enc, const char *ptr, @@ -201,6 +227,13 @@ literals, comments and processing instructions. #define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) +#ifdef XML_DTD + +#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) + +#endif /* XML_DTD */ + /* This is used for performing a 2nd-level tokenization on the content of a literal that has already been returned by XmlTok. */ @@ -215,8 +248,8 @@ the content of a literal that has already been returned by XmlTok. */ #define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) -#define XmlNameMatchesAscii(enc, ptr1, ptr2) \ - (((enc)->nameMatchesAscii)(enc, ptr1, ptr2)) +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ + (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) #define XmlNameLength(enc, ptr) \ (((enc)->nameLength)(enc, ptr)) @@ -261,16 +294,16 @@ int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity, int *standalonePtr); int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); -const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(); -const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(); +const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(void); +const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(void); int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf); int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf); -int XMLTOKAPI XmlSizeOfUnknownEncoding(); +int XMLTOKAPI XmlSizeOfUnknownEncoding(void); ENCODING XMLTOKAPI * XmlInitUnknownEncoding(void *mem, int *table, - int (*convert)(void *userData, const char *p), + int (*conv)(void *userData, const char *p), void *userData); int XMLTOKAPI XmlParseXmlDeclNS(int isGeneralTextEntity, @@ -288,7 +321,7 @@ const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncodingNS(); ENCODING XMLTOKAPI * XmlInitUnknownEncodingNS(void *mem, int *table, - int (*convert)(void *userData, const char *p), + int (*conv)(void *userData, const char *p), void *userData); #ifdef __cplusplus } diff --git a/mozilla/parser/expat/lib/xmltok_impl.c b/mozilla/parser/expat/lib/xmltok_impl.c index f35938128ad..b3d358dd2d0 100644 --- a/mozilla/parser/expat/lib/xmltok_impl.c +++ b/mozilla/parser/expat/lib/xmltok_impl.c @@ -1,6 +1,6 @@ /* The contents of this file are subject to the Mozilla Public License -Version 1.0 (the "License"); you may not use this file except in +Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ @@ -12,10 +12,20 @@ under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. -Portions created by James Clark are Copyright (C) 1998 +Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): + +Alternatively, the contents of this file may be used under the terms +of the GNU General Public License (the "GPL"), in which case the +provisions of the GPL are applicable instead of those above. If you +wish to allow use of your version of this file only under the terms of +the GPL and not to allow others to use your version of this file under +the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the +GPL. If you do not delete the provisions above, a recipient may use +your version of this file under either the MPL or the GPL. */ #ifndef IS_INVALID_CHAR @@ -943,7 +953,7 @@ int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_INVALID; } } - return XML_TOK_PARTIAL; + return -XML_TOK_POUND_NAME; } static @@ -961,7 +971,7 @@ int PREFIX(scanLit)(int open, const ENCODING *enc, if (t != open) break; if (ptr == end) - return XML_TOK_PARTIAL; + return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: @@ -1023,7 +1033,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, } case BT_CR: if (ptr + MINBPC(enc) == end) - return XML_TOK_TRAILING_CR; + return -XML_TOK_PROLOG_S; /* fall through */ case BT_S: case BT_LF: for (;;) { @@ -1056,7 +1066,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_RSQB: ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ']')) { if (ptr + MINBPC(enc) == end) return XML_TOK_PARTIAL; @@ -1073,7 +1083,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_RPAR: ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return -XML_TOK_CLOSE_PAREN; switch (BYTE_TYPE(enc, ptr)) { case BT_AST: *nextTokPtr = ptr + MINBPC(enc); @@ -1203,7 +1213,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_INVALID; } } - return XML_TOK_PARTIAL; + return -tok; } static @@ -1316,6 +1326,61 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end return XML_TOK_DATA_CHARS; } +#ifdef XML_DTD + +static +int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + int level = 0; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + end = ptr + n; + } + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + INVALID_CASES(ptr, nextTokPtr) + case BT_LT: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, '!')) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, '[')) { + ++level; + ptr += MINBPC(enc); + } + } + break; + case BT_RSQB: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ']')) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, '>')) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } + } + break; + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +#endif /* XML_DTD */ + static int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr) @@ -1381,7 +1446,8 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, { enum { other, inName, inValue } state = inName; int nAtts = 0; - int open; + int open = 0; /* defined when state == inValue; + initialization just to shut up compilers */ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { @@ -1625,29 +1691,16 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) } static -int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *ptr2) +int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, + const char *end1, const char *ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { + if (ptr1 == end1) + return 0; if (!CHAR_MATCHES(enc, ptr1, *ptr2)) return 0; } - switch (BYTE_TYPE(enc, ptr1)) { - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - return 0; - default: - return 1; - } + return ptr1 == end1; } static diff --git a/mozilla/parser/expat/lib/xmltok_ns.c b/mozilla/parser/expat/lib/xmltok_ns.c index 435ad7808f8..77d0e739df0 100644 --- a/mozilla/parser/expat/lib/xmltok_ns.c +++ b/mozilla/parser/expat/lib/xmltok_ns.c @@ -1,13 +1,13 @@ -const ENCODING *NS(XmlGetUtf8InternalEncoding)() +const ENCODING *NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } -const ENCODING *NS(XmlGetUtf16InternalEncoding)() +const ENCODING *NS(XmlGetUtf16InternalEncoding)(void) { -#if BYTE_ORDER == 12 +#if XML_BYTE_ORDER == 12 return &ns(internal_little2_encoding).enc; -#elif BYTE_ORDER == 21 +#elif XML_BYTE_ORDER == 21 return &ns(internal_big2_encoding).enc; #else const short n = 1; @@ -45,7 +45,7 @@ int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *n int i = getEncodingIndex(name); if (i == UNKNOWN_ENC) return 0; - INIT_ENC_INDEX(p) = (char)i; + SET_INIT_ENC_INDEX(p, i); p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); p->initEnc.updatePosition = initUpdatePosition;