]> granicus.if.org Git - libexpat/commitdiff
Support for external DTDs completed.
authorJames Clark <jjc@jclark.com>
Sat, 26 Jun 1999 11:29:49 +0000 (11:29 +0000)
committerJames Clark <jjc@jclark.com>
Sat, 26 Jun 1999 11:29:49 +0000 (11:29 +0000)
expat/xmlparse/xmlparse.c
expat/xmlparse/xmlparse.dsp
expat/xmlparse/xmlparse.h
expat/xmltok/xmlrole.c
expat/xmltok/xmlrole.h
expat/xmltok/xmltok.dsp
expat/xmlwf/xmlwf.c

index 54fb57b00f98eb3703eb4708f26fc728ef452f42..9d629403bc45d8ccef431acb55908474d3498740 100755 (executable)
@@ -28,12 +28,6 @@ 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.
 */
 
-/* FIXME
-need current base rather than dtd.base
-check parse state at end of outer param entity
-default handler
-eventPtr incorrectly set within internal entities
- */
 #include "xmldef.h"
 #include "xmlparse.h"
 
@@ -174,10 +168,8 @@ typedef struct {
   STRING_POOL pool;
   int complete;
   int standalone;
-  const XML_Char *base;
 #ifdef XML_DTD
   HASH_TABLE paramEntities;
-  const XML_Char *systemId;
 #endif /* XML_DTD */
   PREFIX defaultPrefix;
 } DTD;
@@ -215,6 +207,11 @@ 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
@@ -313,6 +310,7 @@ typedef struct {
   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;
@@ -335,6 +333,7 @@ typedef struct {
   ATTRIBUTE_ID *m_declAttributeId;
   char m_declAttributeIsCdata;
   DTD m_dtd;
+  const XML_Char *m_curBase;
   TAG *m_tagStack;
   TAG *m_freeTagList;
   BINDING *m_inheritedBindings;
@@ -350,6 +349,7 @@ typedef struct {
   int m_hadExternalDoctype;
   XML_Char m_namespaceSeparator;
 #ifdef XML_DTD
+  enum XML_ParamEntityParsing m_paramEntityParsing;
   XML_Parser m_parentParser;
 #endif
 } Parser;
@@ -374,6 +374,7 @@ typedef struct {
 #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 \
@@ -400,6 +401,7 @@ typedef struct {
 #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)
@@ -421,7 +423,8 @@ typedef struct {
 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
 #ifdef XML_DTD
 #define parentParser (((Parser *)parser)->m_parentParser)
-#endif
+#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
+#endif /* XML_DTD */
 
 #ifdef _MSC_VER
 #ifdef _DEBUG
@@ -498,6 +501,7 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName)
   poolInit(&tempPool);
   poolInit(&temp2Pool);
   protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
+  curBase = 0;
   if (!dtdInit(&dtd) || !atts || !dataBuf
       || (encodingName && !protocolEncodingName)) {
     XML_ParserFree(parser);
@@ -505,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;
 }
 
@@ -528,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)) {
@@ -572,7 +578,9 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
   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));
@@ -600,6 +608,7 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
 #ifdef XML_DTD
+  paramEntityParsing = oldParamEntityParsing;
   if (context) {
 #endif /* XML_DTD */
     if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
@@ -690,16 +699,16 @@ 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)
@@ -803,6 +812,17 @@ 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) {
@@ -959,7 +979,7 @@ void XML_DefaultCurrent(XML_Parser parser)
   if (defaultHandler) {
     if (openInternalEntities)
       reportDefault(parser,
-                   ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(),
+                   internalEncoding,
                    openInternalEntities->internalEventPtr,
                    openInternalEntities->internalEventEndPtr);
     else
@@ -1106,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) {
@@ -1214,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);
@@ -1232,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;
@@ -2013,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) {
@@ -2095,15 +2119,6 @@ prologInitProcessor(XML_Parser parser,
   return prologProcessor(parser, s, end, 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);
-
 static enum XML_Error
 prologProcessor(XML_Parser parser,
                const char *s,
@@ -2115,34 +2130,6 @@ prologProcessor(XML_Parser parser,
   return doProlog(parser, encoding, s, end, tok, next, nextPtr);
 }
 
-#ifdef XML_DTD
-
-static enum XML_Error
-processInternalParamEntity(XML_Parser parser,
-                          ENTITY *entity)
-{
-  const char *s, *end, *next;
-  const ENCODING *enc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
-  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(enc, s, end, &next);
-  result = doProlog(parser, enc, s, end, tok, next, 0);
-  entity->open = 0;
-  openInternalEntities = openEntity.next;
-  return result;
-}
-
-#endif /* XML_DTD */
-
 static enum XML_Error
 doProlog(XML_Parser parser,
         const ENCODING *enc,
@@ -2152,6 +2139,10 @@ doProlog(XML_Parser parser,
         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) {
@@ -2162,8 +2153,10 @@ doProlog(XML_Parser parser,
     eventPP = &(openInternalEntities->internalEventPtr);
     eventEndPP = &(openInternalEntities->internalEventEndPtr);
   }
-  /* FIXME use eventPP not eventPtr */
   for (;;) {
+    int role;
+    *eventPP = s;
+    *eventEndPP = next;
     if (tok <= 0) {
       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
        *nextPtr = s;
@@ -2171,7 +2164,7 @@ doProlog(XML_Parser parser,
       }
       switch (tok) {
       case XML_TOK_INVALID:
-       eventPtr = next;
+       *eventPP = next;
        return XML_ERROR_INVALID_TOKEN;
       case XML_TOK_PARTIAL:
        return XML_ERROR_UNCLOSED_TOKEN;
@@ -2182,6 +2175,9 @@ doProlog(XML_Parser parser,
        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;
        }
@@ -2193,7 +2189,8 @@ doProlog(XML_Parser parser,
        break;
       }
     }
-    switch (XmlTokenRole(&prologState, tok, s, next, enc)) {
+    role = XmlTokenRole(&prologState, tok, s, next, enc);
+    switch (role) {
     case XML_ROLE_XML_DECL:
       {
        enum XML_Error result = processXmlDecl(parser, 0, s, next);
@@ -2210,27 +2207,17 @@ doProlog(XML_Parser parser,
       }
       break;
 #endif /* XML_DTD */
-    case XML_ROLE_DOCTYPE_SYSTEM_ID:
-#ifndef XML_DTD /* FIXME */
-      if (!dtd.standalone
-         && notStandaloneHandler
-         && !notStandaloneHandler(handlerArg))
-       return XML_ERROR_NOT_STANDALONE;
-#endif /* not XML_DTD */
+    case XML_ROLE_DOCTYPE_PUBLIC_ID:
 #ifdef XML_DTD
-      dtd.systemId = poolStoreString(&dtd.pool, enc,
-                                    s + enc->minBytesPerChar,
-                                    next - enc->minBytesPerChar);
-      if (!dtd.systemId)
+      declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+                                   externalSubsetName,
+                                   sizeof(ENTITY));
+      if (!declEntity)
        return XML_ERROR_NO_MEMORY;
-      poolFinish(&dtd.pool);
 #endif /* XML_DTD */
-      hadExternalDoctype = 1;
-      break;
-    case XML_ROLE_DOCTYPE_PUBLIC_ID:
-      /* FIXME */
+      /* fall through */
     case XML_ROLE_ENTITY_PUBLIC_ID:
-      if (!XmlIsPublicId(enc, s, next, &eventPtr))
+      if (!XmlIsPublicId(enc, s, next, eventPP))
        return XML_ERROR_SYNTAX;
       if (declEntity) {
        XML_Char *tem = poolStoreString(&dtd.pool,
@@ -2244,33 +2231,31 @@ doProlog(XML_Parser parser,
        poolFinish(&dtd.pool);
       }
       break;
-#ifdef XML_DTD
     case XML_ROLE_DOCTYPE_CLOSE:
       if (dtd.complete && hadExternalDoctype) {
        dtd.complete = 0;
-       if (dtd.systemId /* && paramEntities*/ && externalEntityRefHandler) {
+#ifdef XML_DTD
+       if (paramEntityParsing && externalEntityRefHandler) {
+         ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
+                                           externalSubsetName,
+                                           0);
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                                        0,
-                                       dtd.base,
-                                       dtd.systemId,
-                                       0))
+                                       entity->base,
+                                       entity->systemId,
+                                       entity->publicId))
           return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-         if (!dtd.complete
-             && !dtd.standalone
-             && notStandaloneHandler
-             && !notStandaloneHandler(handlerArg))
-           return XML_ERROR_NOT_STANDALONE;
-         errorCode = XML_ERROR_NONE;
        }
+#endif /* XML_DTD */
+       if (!dtd.complete
+           && !dtd.standalone
+           && notStandaloneHandler
+           && !notStandaloneHandler(handlerArg))
+         return XML_ERROR_NOT_STANDALONE;
       }
       break;
-#endif /* XML_DTD */
     case XML_ROLE_INSTANCE_START:
       processor = contentProcessor;
-#ifndef XML_DTD
-      if (hadExternalDoctype)
-       dtd.complete = 0;
-#endif /* not XML_DTD */
       return contentProcessor(parser, s, end, nextPtr);
     case XML_ROLE_ATTLIST_ELEMENT_NAME:
       {
@@ -2338,6 +2323,27 @@ doProlog(XML_Parser parser,
          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, enc,
@@ -2345,7 +2351,7 @@ doProlog(XML_Parser parser,
                                               next - enc->minBytesPerChar);
        if (!declEntity->systemId)
          return XML_ERROR_NO_MEMORY;
-       declEntity->base = dtd.base;
+       declEntity->base = curBase;
        poolFinish(&dtd.pool);
       }
       break;
@@ -2356,7 +2362,7 @@ doProlog(XML_Parser parser,
          return XML_ERROR_NO_MEMORY;
        poolFinish(&dtd.pool);
        if (unparsedEntityDeclHandler) {
-         eventPtr = eventEndPtr = s;
+         *eventEndPP = s;
          unparsedEntityDeclHandler(handlerArg,
                                    declEntity->name,
                                    declEntity->base,
@@ -2425,7 +2431,7 @@ doProlog(XML_Parser parser,
       }
       break;
     case XML_ROLE_NOTATION_PUBLIC_ID:
-      if (!XmlIsPublicId(enc, s, next, &eventPtr))
+      if (!XmlIsPublicId(enc, s, next, eventPP))
        return XML_ERROR_SYNTAX;
       if (declNotationName) {
        XML_Char *tem = poolStoreString(&tempPool,
@@ -2447,10 +2453,10 @@ doProlog(XML_Parser parser,
                            next - enc->minBytesPerChar);
        if (!systemId)
          return XML_ERROR_NO_MEMORY;
-       eventPtr = eventEndPtr = s;
+       *eventEndPP = s;
        notationDeclHandler(handlerArg,
                            declNotationName,
-                           dtd.base,
+                           curBase,
                            systemId,
                            declNotationPublicId);
       }
@@ -2458,17 +2464,16 @@ doProlog(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;
@@ -2503,59 +2508,20 @@ doProlog(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;
-#ifdef XML_DTD /* FIXME merge code with following case */
-    case XML_ROLE_INNER_PARAM_ENTITY_REF:
-      {
-       /* FIXME what if !dtd.complete */
-       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)
-         return XML_ERROR_UNDEFINED_ENTITY;
-       if (entity->open)
-         return XML_ERROR_RECURSIVE_ENTITY_REF;
-       if (entity->textPtr) {
-         enum XML_Error result;
-#if 0 /* do we need this? */
-         if (defaultHandler && !defaultExpandInternalEntities) {
-           reportDefault(parser, enc, s, next);
-           break;
-         }
-#endif
-         result = processInternalParamEntity(parser, entity);
-         if (result != XML_ERROR_NONE)
-           return result;
-       }
-       else
-         return XML_ERROR_PARAM_ENTITY_REF;
-      }
-      break;
-#endif
     case XML_ROLE_PARAM_ENTITY_REF:
-      if (!dtd.complete)
-       break;
-      dtd.complete = 0;
 #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,
@@ -2565,28 +2531,27 @@ doProlog(XML_Parser parser,
          return XML_ERROR_NO_MEMORY;
        entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
        poolDiscard(&dtd.pool);
-       if (!entity)
+       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;
-#if 0 /* do we need this */
-         if (defaultHandler && !defaultExpandInternalEntities) {
-           reportDefault(parser, enc, s, next);
-           break;
-         }
-#endif
-         dtd.complete = 1;
          result = processInternalParamEntity(parser, entity);
          if (result != XML_ERROR_NONE)
            return result;
+         break;
        }
-       else if (externalEntityRefHandler) {
+       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,
-                                       dtd.base,
+                                       entity->base,
                                        entity->systemId,
                                        entity->publicId)) {
            entity->open = 0;
@@ -2602,18 +2567,17 @@ doProlog(XML_Parser parser,
          && 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, enc, s, next))
          return XML_ERROR_NO_MEMORY;
        break;
       case XML_TOK_COMMENT:
-       eventPtr = s;
-       eventEndPtr = next;
        if (!reportComment(parser, enc, s, next))
          return XML_ERROR_NO_MEMORY;
        break;
@@ -2626,10 +2590,10 @@ doProlog(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, enc, s, next);
       }
     }
@@ -2696,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,
@@ -2725,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);
@@ -2826,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;
@@ -2847,7 +2836,6 @@ enum XML_Error storeEntityValue(XML_Parser parser,
                                const char *entityTextPtr,
                                const char *entityTextEnd)
 {
-  /* FIXME eventPtr */
   STRING_POOL *pool = &(dtd.pool);
   for (;;) {
     const char *next;
@@ -2883,7 +2871,7 @@ enum XML_Error storeEntityValue(XML_Parser parser,
        }
        entity->open = 1;
        result = storeEntityValue(parser,
-                                 ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(),
+                                 internalEncoding,
                                  (char *)entity->textPtr,
                                  (char *)(entity->textPtr + entity->textLen));
        entity->open = 0;
@@ -2915,12 +2903,14 @@ enum XML_Error storeEntityValue(XML_Parser parser,
        int i;
        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++) {
@@ -2931,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();
@@ -3317,10 +3309,8 @@ static int dtdInit(DTD *p)
   hashTableInit(&(p->prefixes));
   p->complete = 1;
   p->standalone = 0;
-  p->base = 0;
 #ifdef XML_DTD
   hashTableInit(&(p->paramEntities));
-  p->systemId = 0;
 #endif /* XML_DTD */
   p->defaultPrefix.name = 0;
   p->defaultPrefix.binding = 0;
@@ -3367,22 +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;
-  }
-
-#ifdef XML_DTD
-  if (oldDtd->systemId) {
-    const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->systemId);
-    if (!tem)
-      return 0;
-    newDtd->systemId = tem;
-  }
-#endif /* XML_DTD */
-
   /* Copy the prefix table. */
 
   hashTableIterInit(&iter, &(oldDtd->prefixes));
@@ -3490,6 +3464,8 @@ static int copyEntityTable(HASH_TABLE *newTable,
                           const HASH_TABLE *oldTable)
 {
   HASH_TABLE_ITER iter;
+  const XML_Char *cachedOldBase = 0;
+  const XML_Char *cachedNewBase = 0;
 
   hashTableIterInit(&iter, oldTable);
 
@@ -3511,14 +3487,15 @@ static int copyEntityTable(HASH_TABLE *newTable,
        return 0;
       newE->systemId = tem;
       if (oldE->base) {
-#if 0 /* FIXME */
-       if (oldE->base == oldDtd->base)
-         newE->base = newDtd->base;
-#endif
-       tem = poolCopyString(newPool, 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 {
index 6499c9b3e4fdd634e8f45cedc247b1ae22f59ed9..dd446919c66a0aba1b7dcce3c6419b60be1bd014 100755 (executable)
@@ -44,7 +44,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir "."
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /W3 /GX /O2 /I "..\xmltok" /I "..\xmlwf" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllexport) /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\xmltok" /I "..\xmlwf" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllexport) /D "NDEBUG" /D "XML_NS" /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x809 /d "NDEBUG"
@@ -71,7 +71,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir "."
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\xmltok" /I "..\xmlwf" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllexport) /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\xmltok" /I "..\xmlwf" /D "_DEBUG" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllexport) /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /YX /FD /c
 # ADD BASE MTL /nologo /D "_DEBUG" /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x809 /d "_DEBUG"
index f2f9c9be1c0d69d926dcf22b4e4c58cab8bd0ac9..065ad036d7d78b2234d6f73ca0f3a8839a787920 100755 (executable)
@@ -415,6 +415,35 @@ 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,
index 48ef943b9b3046bca6c93a6cb1bd43eb3b12114e..a8fdda78da2b4809533c47bdc0eb21f0c03d82e6 100755 (executable)
@@ -369,6 +369,10 @@ int externalSubset1(PROLOG_STATE *state,
     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);
   }
@@ -1258,11 +1262,4 @@ void XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
   state->includeLevel = 0;
 }
 
-void XmlPrologStateInitInternalEntity(PROLOG_STATE *state)
-{
-  state->handler = externalSubset1;
-  state->documentEntity = 0;
-  state->includeLevel = 0;
-}
-
 #endif /* XML_DTD */
index cb271086233deae28a7eea69e0ada6766238baf8..3e780e7f6e095f46433cf8d7755d3a676b93047d 100755 (executable)
@@ -110,7 +110,6 @@ typedef struct prolog_state {
 
 void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *);
 #ifdef XML_DTD
-void XMLTOKAPI XmlPrologStateInitInternalEntity(PROLOG_STATE *);
 void XMLTOKAPI XmlPrologStateInitExternalEntity(PROLOG_STATE *);
 #endif /* XML_DTD */
 
index 8d30425e3b943ba3493e4d813464962e9af41acd..8e3a05a42e67ed5feb141f56e1a5db18234500aa 100755 (executable)
@@ -43,7 +43,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir "."
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D XMLTOKAPI=__declspec(dllexport) /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D XMLTOKAPI=__declspec(dllexport) /D "NDEBUG" /D "XML_NS" /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x809 /d "NDEBUG"
@@ -70,7 +70,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir "."
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D XMLTOKAPI=__declspec(dllexport) /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D XMLTOKAPI=__declspec(dllexport) /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /YX /FD /c
 # ADD BASE MTL /nologo /D "_DEBUG" /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x809 /d "_DEBUG"
@@ -103,7 +103,7 @@ SOURCE=..\gennmtab\gennmtab.c
 
 # PROP Ignore_Default_Tool 1
 # Begin Custom Build - Creating nametab.h
-InputDir=\temp\expat\gennmtab
+InputDir=\home\work\expat\gennmtab
 OutDir=.\Release
 ProjDir=.
 InputPath=..\gennmtab\gennmtab.c
@@ -117,7 +117,7 @@ InputPath=..\gennmtab\gennmtab.c
 
 # PROP Ignore_Default_Tool 1
 # Begin Custom Build - Creating nametab.h
-InputDir=\temp\expat\gennmtab
+InputDir=\home\work\expat\gennmtab
 OutDir=.\Debug
 ProjDir=.
 InputPath=..\gennmtab\gennmtab.c
index ea30402b7270e01bc0dc64d29a32f835eb15f033..f52b2f79da0da665545eec2b2a75acac4a8f760c 100755 (executable)
@@ -469,7 +469,7 @@ int notStandalone(void *userData)
 static
 void usage(const XML_Char *prog)
 {
-  ftprintf(stderr, T("usage: %s [-n] [-r] [-s] [-w] [-x] [-d output-dir] [-e encoding] file ...\n"), prog);
+  ftprintf(stderr, T("usage: %s [-n] [-p] [-r] [-s] [-w] [-x] [-d output-dir] [-e encoding] file ...\n"), prog);
   exit(1);
 }
 
@@ -483,6 +483,7 @@ int tmain(int argc, XML_Char **argv)
   int outputType = 0;
   int useNamespaces = 0;
   int requireStandalone = 0;
+  int paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
 
 #ifdef _MSC_VER
   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
@@ -513,6 +514,9 @@ int tmain(int argc, XML_Char **argv)
       useNamespaces = 1;
       j++;
       break;
+    case T('p'):
+      paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS;
+      /* fall through */
     case T('x'):
       processFlags |= XML_EXTERNAL_ENTITIES;
       j++;
@@ -580,6 +584,7 @@ int tmain(int argc, XML_Char **argv)
       parser = XML_ParserCreate(encoding);
     if (requireStandalone)
       XML_SetNotStandaloneHandler(parser, notStandalone);
+    XML_SetParamEntityParsing(parser, paramEntityParsing);
     if (outputType == 't') {
       /* This is for doing timings; this gives a more realistic estimate of
         the parsing time. */