[Expat-checkins] expat/lib expat.h,1.51,1.52 xmlparse.c,1.108,1.109

Karl Waclawek kwaclaw at users.sourceforge.net
Fri Mar 7 07:54:14 EST 2003


Update of /cvsroot/expat/expat/lib
In directory sc8-pr-cvs1:/tmp/cvs-serv22062

Modified Files:
	expat.h xmlparse.c 
Log Message:
Apply patch NSAttFix3.diff for bug #692964 (with one minor modification).
This also fixes bug #695401.

Index: expat.h
===================================================================
RCS file: /cvsroot/expat/expat/lib/expat.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- expat.h	29 Jan 2003 02:43:08 -0000	1.51
+++ expat.h	7 Mar 2003 15:54:06 -0000	1.52
@@ -104,7 +104,8 @@
   XML_ERROR_UNEXPECTED_STATE,
   XML_ERROR_ENTITY_DECLARED_IN_PE,
   XML_ERROR_FEATURE_REQUIRES_XML_DTD,
-  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
+  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
+  XML_ERROR_UNBOUND_PREFIX
 };
 
 enum XML_Content_Type {

Index: xmlparse.c
===================================================================
RCS file: /cvsroot/expat/expat/lib/xmlparse.c,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -d -r1.108 -r1.109
--- xmlparse.c	3 Feb 2003 20:32:45 -0000	1.108
+++ xmlparse.c	7 Mar 2003 15:54:08 -0000	1.109
@@ -224,6 +224,11 @@
 } DEFAULT_ATTRIBUTE;
 
 typedef struct {
+  unsigned long hash;
+  const XML_Char *uriName;
+} NS_ATT;
+
+typedef struct {
   const XML_Char *name;
   PREFIX *prefix;
   const ATTRIBUTE_ID *idAtt;
@@ -499,6 +504,8 @@
   int m_nSpecifiedAtts;
   int m_idAttIndex;
   ATTRIBUTE *m_atts;
+  NS_ATT *m_nsAtts;
+  int m_nsAttsSize;
   POSITION m_position;
   STRING_POOL m_tempPool;
   STRING_POOL m_temp2Pool;
@@ -601,6 +608,8 @@
 #define attsSize (parser->m_attsSize)
 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
 #define idAttIndex (parser->m_idAttIndex)
+#define nsAtts (parser->m_nsAtts)
+#define nsAttsSize (parser->m_nsAttsSize)
 #define tempPool (parser->m_tempPool)
 #define temp2Pool (parser->m_temp2Pool)
 #define groupConnector (parser->m_groupConnector)
@@ -747,6 +756,9 @@
   ns = XML_FALSE;
   ns_triplets = XML_FALSE;
 
+  nsAtts = NULL;
+  nsAttsSize = 0;
+
   poolInit(&tempPool, &(parser->m_mem));
   poolInit(&temp2Pool, &(parser->m_mem));
   parserInit(parser, encodingName);
@@ -868,8 +880,7 @@
     freeTagList = tag;
   }
   moveToFreeBindingList(parser, inheritedBindings);
-  if (unknownEncodingMem)
-    FREE(unknownEncodingMem);
+  FREE(unknownEncodingMem);
   if (unknownEncodingRelease)
     unknownEncodingRelease(unknownEncodingData);
   poolClear(&tempPool);
@@ -1072,13 +1083,11 @@
 #endif /* XML_DTD */
     dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
   FREE((void *)atts);
-  if (groupConnector)
-    FREE(groupConnector);
-  if (buffer)
-    FREE(buffer);
+  FREE(groupConnector);
+  FREE(buffer);
   FREE(dataBuf);
-  if (unknownEncodingMem)
-    FREE(unknownEncodingMem);
+  FREE(nsAtts);
+  FREE(unknownEncodingMem);
   if (unknownEncodingRelease)
     unknownEncodingRelease(unknownEncodingData);
   FREE(parser);
@@ -1660,7 +1669,8 @@
     XML_L("unexpected parser state - please send a bug report"),
     XML_L("entity declared in parameter entity"),
     XML_L("requested feature requires XML_DTD support in Expat"),
-    XML_L("cannot change setting once parsing has begun")
+    XML_L("cannot change setting once parsing has begun"),
+    XML_L("unbound prefix")
   };
   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
     return message[code];
@@ -2409,7 +2419,7 @@
                                          + XmlNameLength(enc, atts[i].name));
     if (!attId)
       return XML_ERROR_NO_MEMORY;
-    /* detect duplicate attributes */
+    /* detect duplicate attributes by their QNames */
     if ((attId->name)[-1]) {
       if (enc == encoding)
         eventPtr = atts[i].name;
@@ -2509,48 +2519,88 @@
   }
   appAtts[attIndex] = 0;
 
+  /* expand prefixed attribute names and
+     clear flags that say whether attributes were specified */
   i = 0;
   if (nPrefixes) {
-    /* expand prefixed attribute names */
+    int j;
+    if ((nPrefixes * 2) > nsAttsSize) {
+      NS_ATT *temp = (NS_ATT *)REALLOC(nsAtts, nPrefixes * 2 * sizeof(NS_ATT));
+      if (!temp)
+        return XML_ERROR_NO_MEMORY;
+      nsAtts = temp;
+      nsAttsSize = nPrefixes * 2;
+    }
+    /* clear nsAtts hash table */
+    for (j = 0; j < nsAttsSize; j++)
+      nsAtts[j].uriName = NULL;
+
     for (; i < attIndex; i += 2) {
-      if (appAtts[i][-1] == 2) {
+      const XML_Char *s = appAtts[i];
+      if (s[-1] == 2) {
         ATTRIBUTE_ID *id;
-        ((XML_Char *)(appAtts[i]))[-1] = 0;
-        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, appAtts[i], 0);
-        if (id->prefix->binding) {
-          int j;
-          const BINDING *b = id->prefix->binding;
-          const XML_Char *s = appAtts[i];
-          for (j = 0; j < b->uriLen; j++) {
-            if (!poolAppendChar(&tempPool, b->uri[j]))
-              return XML_ERROR_NO_MEMORY;
+        const BINDING *b;
+        unsigned long uriHash = 0;
+        ((XML_Char *)s)[-1] = 0;
+        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
+        b = id->prefix->binding;
+        if (!b) 
+          return XML_ERROR_UNBOUND_PREFIX;
+
+        /* b->uri includes namespace separator */
+        for (j = 0; j < b->uriLen; j++) {
+          const XML_Char c = b->uri[j];
+          if (!poolAppendChar(&tempPool, c))
+            return XML_ERROR_NO_MEMORY;
+          uriHash = (uriHash << 5) + uriHash + (unsigned char)c;
+        }
+        while (*s++ != XML_T(':'))
+          ;
+        do {
+          const XML_Char c = *s;
+          if (!poolAppendChar(&tempPool, *s))
+            return XML_ERROR_NO_MEMORY;
+          uriHash = (uriHash << 5) + uriHash + (unsigned char)c;
+        } while (*s++);
+
+        /* detect duplicate attributes based on uriName = uri + local name */
+        for (j = uriHash & (nsAttsSize - 1);
+             nsAtts[j].uriName; 
+             j == 0 ? j = nsAttsSize - 1 : --j) {
+          if (uriHash == nsAtts[j].hash) {
+            const XML_Char *s1 = poolStart(&tempPool); /* null-terminated */
+            const XML_Char *s2 = nsAtts[j].uriName;
+            for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
+            if (*s1 == 0)
+              return XML_ERROR_DUPLICATE_ATTRIBUTE;
           }
-          while (*s++ != XML_T(':'))
-            ;
+        }
+
+        if (ns_triplets) {
+          tempPool.ptr[-1] = namespaceSeparator;
+          s = b->prefix->name;
           do {
             if (!poolAppendChar(&tempPool, *s))
               return XML_ERROR_NO_MEMORY;
           } while (*s++);
-          if (ns_triplets) {
-            tempPool.ptr[-1] = namespaceSeparator;
-            s = b->prefix->name;
-            do {
-              if (!poolAppendChar(&tempPool, *s))
-                return XML_ERROR_NO_MEMORY;
-            } while (*s++);
-          }
-
-          appAtts[i] = poolStart(&tempPool);
-          poolFinish(&tempPool);
         }
+
+        s = poolStart(&tempPool);
+        appAtts[i] = s;
+        poolFinish(&tempPool);
+
+        /* fill empty slot with new attribute */
+        nsAtts[j].hash = uriHash;
+        nsAtts[j].uriName = s;
+        
         if (!--nPrefixes)
           break;
       }
       else
-        ((XML_Char *)(appAtts[i]))[-1] = 0;
+        ((XML_Char *)s)[-1] = 0;
     }
   }
-  /* clear the flags that say whether attributes were specified */
+  /* clear flags for the remaining attributes */
   for (; i < attIndex; i += 2)
     ((XML_Char *)(appAtts[i]))[-1] = 0;
   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
@@ -2560,7 +2610,7 @@
   if (elementType->prefix) {
     binding = elementType->prefix->binding;
     if (!binding)
-      return XML_ERROR_NONE;
+      return XML_ERROR_UNBOUND_PREFIX;
     localPart = tagNamePtr->str;
     while (*localPart++ != XML_T(':'))
       ;
@@ -2599,8 +2649,9 @@
   uri = binding->uri + binding->uriLen;
   memcpy(uri, localPart, i * sizeof(XML_Char));
   if (prefixLen) {
-        uri = uri + (i - 1);
-    if (namespaceSeparator) { *(uri) = namespaceSeparator; }
+    uri = uri + (i - 1);
+    if (namespaceSeparator)
+      *uri = namespaceSeparator;
     memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
   }
   tagNamePtr->str = binding->uri;
@@ -2655,6 +2706,7 @@
   b->prefix = prefix;
   b->attId = attId;
   b->prevPrefixBinding = prefix->binding;
+  /* NULL binding when default namespace undeclared */
   if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
     prefix->binding = NULL;
   else
@@ -3502,8 +3554,8 @@
     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
       if (dtd->keepProcessing) {
         if (!defineAttribute(declElementType, declAttributeId,
-                              declAttributeIsCdata, declAttributeIsId, 0,
-                              parser))
+                             declAttributeIsCdata, declAttributeIsId,
+                             0, parser))
           return XML_ERROR_NO_MEMORY;
         if (attlistDeclHandler && declAttributeType) {
           if (*declAttributeType == XML_T('(')
@@ -3529,11 +3581,11 @@
     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
       if (dtd->keepProcessing) {
         const XML_Char *attVal;
-        enum XML_Error result
-          = storeAttributeValue(parser, enc, declAttributeIsCdata,
-                                s + enc->minBytesPerChar,
-                                next - enc->minBytesPerChar,
-                                &dtd->pool);
+        enum XML_Error result =
+          storeAttributeValue(parser, enc, declAttributeIsCdata,
+                              s + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar,
+                              &dtd->pool);
         if (result)
           return result;
         attVal = poolStart(&dtd->pool);
@@ -4749,6 +4801,7 @@
   name = poolStoreString(&dtd->pool, enc, start, end);
   if (!name)
     return NULL;
+  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
   ++name;
   id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
   if (!id)
@@ -4774,6 +4827,7 @@
     else {
       int i;
       for (i = 0; name[i]; i++) {
+        /* attributes without prefix are *not* in the default namespace */
         if (name[i] == XML_T(':')) {
           int j;
           for (j = 0; j < i; j++) {
@@ -5013,14 +5067,12 @@
   p->defaultPrefix.binding = NULL;
 
   p->in_eldecl = XML_FALSE;
-  if (p->scaffIndex) {
-    ms->free_fcn(p->scaffIndex);
-    p->scaffIndex = NULL;
-  }
-  if (p->scaffold) {
-    ms->free_fcn(p->scaffold);
-    p->scaffold = NULL;
-  }
+
+  ms->free_fcn(p->scaffIndex);
+  p->scaffIndex = NULL;
+  ms->free_fcn(p->scaffold);
+  p->scaffold = NULL;
+
   p->scaffLevel = 0;
   p->scaffSize = 0;
   p->scaffCount = 0;
@@ -5055,10 +5107,8 @@
   poolDestroy(&(p->entityValuePool));
 #endif /* XML_DTD */
   if (isDocEntity) {
-    if (p->scaffIndex)
-      ms->free_fcn(p->scaffIndex);
-    if (p->scaffold)
-      ms->free_fcn(p->scaffold);
+    ms->free_fcn(p->scaffIndex);
+    ms->free_fcn(p->scaffold);
   }
   ms->free_fcn(p);
 }
@@ -5264,13 +5314,13 @@
 
 #define INIT_SIZE 64
 
-static int FASTCALL
+static XML_Bool FASTCALL
 keyeq(KEY s1, KEY s2)
 {
   for (; *s1 == *s2; s1++, s2++)
     if (*s1 == 0)
-      return 1;
-  return 0;
+      return XML_TRUE;
+  return XML_FALSE;
 }
 
 static unsigned long FASTCALL
@@ -5351,11 +5401,8 @@
 {
   size_t i;
   for (i = 0; i < table->size; i++) {
-    NAMED *p = table->v[i];
-    if (p) {
-      table->mem->free_fcn(p);
-      table->v[i] = NULL;
-    }
+    table->mem->free_fcn(table->v[i]);
+    table->v[i] = NULL;
   }
   table->usedLim = table->size / 2;
   table->used = 0;
@@ -5365,13 +5412,9 @@
 hashTableDestroy(HASH_TABLE *table)
 {
   size_t i;
-  for (i = 0; i < table->size; i++) {
-    NAMED *p = table->v[i];
-    if (p)
-      table->mem->free_fcn(p);
-  }
-  if (table->v)
-    table->mem->free_fcn(table->v);
+  for (i = 0; i < table->size; i++)
+    table->mem->free_fcn(table->v[i]);
+  table->mem->free_fcn(table->v);
 }
 
 static void FASTCALL
@@ -5709,3 +5752,4 @@
   }
   return ret;
 }
+





More information about the Expat-checkins mailing list