7154639 Problem with library/libexpat s11-sru S11SRU11_04
authorPetr Sumbera <petr.sumbera@oracle.com>
Wed, 22 Aug 2012 09:34:32 -0500
branchs11-sru
changeset 2334 b52a7ffea126
parent 2329 b5648e26057f
child 2335 e578e0325a89
7154639 Problem with library/libexpat
components/libexpat/patches/CVE-2012-0876.patch
components/libexpat/patches/CVE-2012-1148.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/libexpat/patches/CVE-2012-0876.patch	Wed Aug 22 09:34:32 2012 -0500
@@ -0,0 +1,567 @@
+
+https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-0876
+
+--- lib/expat.h.cve0876
++++ lib/expat.h
+@@ -883,6 +883,15 @@ XMLPARSEAPI(int)
+ XML_SetParamEntityParsing(XML_Parser parser,
+                           enum XML_ParamEntityParsing parsing);
+ 
++/* Sets the hash salt to use for internal hash calculations.
++   Helps in preventing DoS attacks based on predicting hash
++   function behavior. This must be called before parsing is started.
++   Returns 1 if successful, 0 when called after parsing has started.
++*/
++XMLPARSEAPI(int)
++XML_SetHashSalt(XML_Parser parser,
++                unsigned long hash_salt);
++
+ /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
+    XML_GetErrorCode returns information about the error.
+ */
+--- lib/xmlparse.c.cve0876
++++ lib/xmlparse.c
+@@ -5,6 +5,8 @@
+ #include <stddef.h>
+ #include <string.h>                     /* memset(), memcpy() */
+ #include <assert.h>
++#include <limits.h>                     /* UINT_MAX */
++#include <time.h>                       /* time() */
+ 
+ #define XML_BUILDING_EXPAT 1
+ 
+@@ -391,12 +393,13 @@ static void dtdReset(DTD *p, const XML_M
+ static void
+ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
+ static int
+-dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
++dtdCopy(XML_Parser oldParser,
++        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
+ static int
+-copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
+-
++copyEntityTable(XML_Parser oldParser,
++                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
+ static NAMED *
+-lookup(HASH_TABLE *table, KEY name, size_t createSize);
++lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
+ static void FASTCALL
+ hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+ static void FASTCALL hashTableClear(HASH_TABLE *);
+@@ -429,11 +432,15 @@ static ELEMENT_TYPE *
+ getElementType(XML_Parser parser, const ENCODING *enc,
+                const char *ptr, const char *end);
+ 
++static unsigned long generate_hash_secret_salt(void);
++static XML_Bool startParsing(XML_Parser parser);
++
+ static XML_Parser
+ parserCreate(const XML_Char *encodingName,
+              const XML_Memory_Handling_Suite *memsuite,
+              const XML_Char *nameSep,
+              DTD *dtd);
++
+ static void
+ parserInit(XML_Parser parser, const XML_Char *encodingName);
+ 
+@@ -546,6 +553,7 @@ struct XML_ParserStruct {
+   XML_Bool m_useForeignDTD;
+   enum XML_ParamEntityParsing m_paramEntityParsing;
+ #endif
++  unsigned long m_hash_secret_salt;
+ };
+ 
+ #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
+@@ -653,6 +661,7 @@ struct XML_ParserStruct {
+ #define useForeignDTD (parser->m_useForeignDTD)
+ #define paramEntityParsing (parser->m_paramEntityParsing)
+ #endif /* XML_DTD */
++#define hash_secret_salt (parser->m_hash_secret_salt)
+ 
+ XML_Parser XMLCALL
+ XML_ParserCreate(const XML_Char *encodingName)
+@@ -677,22 +686,35 @@ static const XML_Char implicitContext[] 
+   ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
+ };
+ 
++static unsigned long
++generate_hash_secret_salt(void)
++{
++  unsigned int seed = time(NULL) % UINT_MAX;
++  srand(seed);
++  return rand();
++}
++
++static XML_Bool  /* only valid for root parser */
++startParsing(XML_Parser parser)
++{
++    /* hash functions must be initialized before setContext() is called */
++    if (hash_secret_salt == 0)
++      hash_secret_salt = generate_hash_secret_salt();
++    if (ns) {
++      /* implicit context only set for root parser, since child
++         parsers (i.e. external entity parsers) will inherit it
++      */
++      return setContext(parser, implicitContext);
++    }
++    return XML_TRUE;
++}
++
+ XML_Parser XMLCALL
+ XML_ParserCreate_MM(const XML_Char *encodingName,
+                     const XML_Memory_Handling_Suite *memsuite,
+                     const XML_Char *nameSep)
+ {
+-  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
+-  if (parser != NULL && ns) {
+-    /* implicit context only set for root parser, since child
+-       parsers (i.e. external entity parsers) will inherit it
+-    */
+-    if (!setContext(parser, implicitContext)) {
+-      XML_ParserFree(parser);
+-      return NULL;
+-    }
+-  }
+-  return parser;
++  return parserCreate(encodingName, memsuite, nameSep, NULL);
+ }
+ 
+ static XML_Parser
+@@ -866,6 +888,7 @@ parserInit(XML_Parser parser, const XML_
+   useForeignDTD = XML_FALSE;
+   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+ #endif
++  hash_secret_salt = 0;
+ }
+ 
+ /* moves list of bindings to freeBindingList */
+@@ -913,7 +936,7 @@ XML_ParserReset(XML_Parser parser, const
+   poolClear(&temp2Pool);
+   parserInit(parser, encodingName);
+   dtdReset(_dtd, &parser->m_mem);
+-  return setContext(parser, implicitContext);
++  return XML_TRUE;
+ }
+ 
+ enum XML_Status XMLCALL
+@@ -982,6 +1005,12 @@ XML_ExternalEntityParserCreate(XML_Parse
+   int oldInEntityValue = prologState.inEntityValue;
+ #endif
+   XML_Bool oldns_triplets = ns_triplets;
++  /* Note that the new parser shares the same hash secret as the old
++     parser, so that dtdCopy and copyEntityTable can lookup values
++     from hash tables associated with either parser without us having
++     to worry which hash secrets each table has.
++  */
++  unsigned long oldhash_secret_salt = hash_secret_salt;
+ 
+ #ifdef XML_DTD
+   if (!context)
+@@ -1035,13 +1064,14 @@ XML_ExternalEntityParserCreate(XML_Parse
+     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+   ns_triplets = oldns_triplets;
++  hash_secret_salt = oldhash_secret_salt;
+   parentParser = oldParser;
+ #ifdef XML_DTD
+   paramEntityParsing = oldParamEntityParsing;
+   prologState.inEntityValue = oldInEntityValue;
+   if (context) {
+ #endif /* XML_DTD */
+-    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
++    if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
+       || !setContext(parser, context)) {
+       XML_ParserFree(parser);
+       return NULL;
+@@ -1426,6 +1456,17 @@ XML_SetParamEntityParsing(XML_Parser par
+ #endif
+ }
+ 
++int XMLCALL
++XML_SetHashSalt(XML_Parser parser,
++                unsigned long hash_salt)
++{
++  /* block after XML_Parse()/XML_ParseBuffer() has been called */
++  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
++    return 0;
++  hash_secret_salt = hash_salt;
++  return 1;
++}
++
+ enum XML_Status XMLCALL
+ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+ {
+@@ -1436,6 +1477,11 @@ XML_Parse(XML_Parser parser, const char 
+   case XML_FINISHED:
+     errorCode = XML_ERROR_FINISHED;
+     return XML_STATUS_ERROR;
++  case XML_INITIALIZED:
++    if (parentParser == NULL && !startParsing(parser)) {
++      errorCode = XML_ERROR_NO_MEMORY;
++      return XML_STATUS_ERROR;
++    }
+   default:
+     ps_parsing = XML_PARSING;
+   }
+@@ -1494,11 +1540,13 @@ XML_Parse(XML_Parser parser, const char 
+         break;
+       case XML_INITIALIZED:
+       case XML_PARSING:
+-        result = XML_STATUS_OK;
+         if (isFinal) {
+           ps_parsing = XML_FINISHED;
+-          return result;
++          return XML_STATUS_OK;
+         }
++      /* fall through */
++      default:
++        result = XML_STATUS_OK;
+       }
+     }
+ 
+@@ -1559,6 +1607,11 @@ XML_ParseBuffer(XML_Parser parser, int l
+   case XML_FINISHED:
+     errorCode = XML_ERROR_FINISHED;
+     return XML_STATUS_ERROR;
++  case XML_INITIALIZED:
++    if (parentParser == NULL && !startParsing(parser)) {
++      errorCode = XML_ERROR_NO_MEMORY;
++      return XML_STATUS_ERROR;
++    }
+   default:
+     ps_parsing = XML_PARSING;
+   }
+@@ -2240,7 +2293,7 @@ doContent(XML_Parser parser,
+                                 next - enc->minBytesPerChar);
+         if (!name)
+           return XML_ERROR_NO_MEMORY;
+-        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
++        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
+         poolDiscard(&dtd->pool);
+         /* First, determine if a check for an existing declaration is needed;
+            if yes, check that the entity exists, and that it is internal,
+@@ -2630,12 +2683,12 @@ storeAtts(XML_Parser parser, const ENCOD
+   const XML_Char *localPart;
+ 
+   /* lookup the element type name */
+-  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
++  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
+   if (!elementType) {
+     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
+     if (!name)
+       return XML_ERROR_NO_MEMORY;
+-    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
++    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
+                                          sizeof(ELEMENT_TYPE));
+     if (!elementType)
+       return XML_ERROR_NO_MEMORY;
+@@ -2804,9 +2857,9 @@ storeAtts(XML_Parser parser, const ENCOD
+       if (s[-1] == 2) {  /* prefixed */
+         ATTRIBUTE_ID *id;
+         const BINDING *b;
+-        unsigned long uriHash = 0;
++        unsigned long uriHash = hash_secret_salt;
+         ((XML_Char *)s)[-1] = 0;  /* clear flag */
+-        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
++        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
+         b = id->prefix->binding;
+         if (!b)
+           return XML_ERROR_UNBOUND_PREFIX;
+@@ -2828,7 +2881,7 @@ storeAtts(XML_Parser parser, const ENCOD
+         } while (*s++);
+ 
+         { /* Check hash table for duplicate of expanded name (uriName).
+-             Derived from code in lookup(HASH_TABLE *table, ...).
++             Derived from code in lookup(parser, HASH_TABLE *table, ...).
+           */
+           unsigned char step = 0;
+           unsigned long mask = nsAttsSize - 1;
+@@ -3777,7 +3830,8 @@ doProlog(XML_Parser parser,
+     case XML_ROLE_DOCTYPE_PUBLIC_ID:
+ #ifdef XML_DTD
+       useForeignDTD = XML_FALSE;
+-      declEntity = (ENTITY *)lookup(&dtd->paramEntities,
++      declEntity = (ENTITY *)lookup(parser,
++                                    &dtd->paramEntities,
+                                     externalSubsetName,
+                                     sizeof(ENTITY));
+       if (!declEntity)
+@@ -3832,7 +3886,8 @@ doProlog(XML_Parser parser,
+         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+         dtd->hasParamEntityRefs = XML_TRUE;
+         if (paramEntityParsing && externalEntityRefHandler) {
+-          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
++          ENTITY *entity = (ENTITY *)lookup(parser,
++                                            &dtd->paramEntities,
+                                             externalSubsetName,
+                                             sizeof(ENTITY));
+           if (!entity)
+@@ -3876,7 +3931,7 @@ doProlog(XML_Parser parser,
+         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+         dtd->hasParamEntityRefs = XML_TRUE;
+         if (paramEntityParsing && externalEntityRefHandler) {
+-          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
++          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
+                                             externalSubsetName,
+                                             sizeof(ENTITY));
+           if (!entity)
+@@ -4090,7 +4145,8 @@ doProlog(XML_Parser parser,
+       break;
+ #else /* XML_DTD */
+       if (!declEntity) {
+-        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
++        declEntity = (ENTITY *)lookup(parser,
++                                      &dtd->paramEntities,
+                                       externalSubsetName,
+                                       sizeof(ENTITY));
+         if (!declEntity)
+@@ -4165,7 +4221,7 @@ doProlog(XML_Parser parser,
+           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+           if (!name)
+             return XML_ERROR_NO_MEMORY;
+-          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
++          declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
+                                         sizeof(ENTITY));
+           if (!declEntity)
+             return XML_ERROR_NO_MEMORY;
+@@ -4197,7 +4253,7 @@ doProlog(XML_Parser parser,
+         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+         if (!name)
+           return XML_ERROR_NO_MEMORY;
+-        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
++        declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
+                                            name, sizeof(ENTITY));
+         if (!declEntity)
+           return XML_ERROR_NO_MEMORY;
+@@ -4379,7 +4435,7 @@ doProlog(XML_Parser parser,
+                                 next - enc->minBytesPerChar);
+         if (!name)
+           return XML_ERROR_NO_MEMORY;
+-        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
++        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
+         poolDiscard(&dtd->pool);
+         /* first, determine if a check for an existing declaration is needed;
+            if yes, check that the entity exists, and that it is internal,
+@@ -4903,7 +4959,7 @@ appendAttributeValue(XML_Parser parser, 
+                                next - enc->minBytesPerChar);
+         if (!name)
+           return XML_ERROR_NO_MEMORY;
+-        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
++        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
+         poolDiscard(&temp2Pool);
+         /* First, determine if a check for an existing declaration is needed;
+            if yes, check that the entity exists, and that it is internal.
+@@ -5012,7 +5068,7 @@ storeEntityValue(XML_Parser parser,
+           result = XML_ERROR_NO_MEMORY;
+           goto endEntityValue;
+         }
+-        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
++        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
+         poolDiscard(&tempPool);
+         if (!entity) {
+           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
+@@ -5302,7 +5358,7 @@ setElementTypePrefix(XML_Parser parser, 
+       }
+       if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+         return 0;
+-      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
++      prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
+                                 sizeof(PREFIX));
+       if (!prefix)
+         return 0;
+@@ -5331,7 +5387,7 @@ getAttributeId(XML_Parser parser, const 
+     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));
++  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
+   if (!id)
+     return NULL;
+   if (id->name != name)
+@@ -5349,7 +5405,7 @@ getAttributeId(XML_Parser parser, const 
+       if (name[5] == XML_T('\0'))
+         id->prefix = &dtd->defaultPrefix;
+       else
+-        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
++        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
+       id->xmlns = XML_TRUE;
+     }
+     else {
+@@ -5364,7 +5420,7 @@ getAttributeId(XML_Parser parser, const 
+           }
+           if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+             return NULL;
+-          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
++          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
+                                         sizeof(PREFIX));
+           if (id->prefix->name == poolStart(&dtd->pool))
+             poolFinish(&dtd->pool);
+@@ -5460,7 +5516,7 @@ setContext(XML_Parser parser, const XML_
+       ENTITY *e;
+       if (!poolAppendChar(&tempPool, XML_T('\0')))
+         return XML_FALSE;
+-      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
++      e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
+       if (e)
+         e->open = XML_TRUE;
+       if (*s != XML_T('\0'))
+@@ -5475,7 +5531,7 @@ setContext(XML_Parser parser, const XML_
+       else {
+         if (!poolAppendChar(&tempPool, XML_T('\0')))
+           return XML_FALSE;
+-        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
++        prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
+                                   sizeof(PREFIX));
+         if (!prefix)
+           return XML_FALSE;
+@@ -5639,7 +5695,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity,
+    The new DTD has already been initialized.
+ */
+ static int
+-dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
++dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
+ {
+   HASH_TABLE_ITER iter;
+ 
+@@ -5654,7 +5710,7 @@ dtdCopy(DTD *newDtd, const DTD *oldDtd, 
+     name = poolCopyString(&(newDtd->pool), oldP->name);
+     if (!name)
+       return 0;
+-    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
++    if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
+       return 0;
+   }
+ 
+@@ -5676,7 +5732,7 @@ dtdCopy(DTD *newDtd, const DTD *oldDtd, 
+     if (!name)
+       return 0;
+     ++name;
+-    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
++    newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
+                                   sizeof(ATTRIBUTE_ID));
+     if (!newA)
+       return 0;
+@@ -5686,7 +5742,7 @@ dtdCopy(DTD *newDtd, const DTD *oldDtd, 
+       if (oldA->prefix == &oldDtd->defaultPrefix)
+         newA->prefix = &newDtd->defaultPrefix;
+       else
+-        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
++        newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
+                                         oldA->prefix->name, 0);
+     }
+   }
+@@ -5705,7 +5761,7 @@ dtdCopy(DTD *newDtd, const DTD *oldDtd, 
+     name = poolCopyString(&(newDtd->pool), oldE->name);
+     if (!name)
+       return 0;
+-    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
++    newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
+                                   sizeof(ELEMENT_TYPE));
+     if (!newE)
+       return 0;
+@@ -5719,14 +5775,14 @@ dtdCopy(DTD *newDtd, const DTD *oldDtd, 
+     }
+     if (oldE->idAtt)
+       newE->idAtt = (ATTRIBUTE_ID *)
+-          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
++          lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
+     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+     if (oldE->prefix)
+-      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
++      newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
+                                       oldE->prefix->name, 0);
+     for (i = 0; i < newE->nDefaultAtts; i++) {
+       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
+-          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
++          lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+       if (oldE->defaultAtts[i].value) {
+         newE->defaultAtts[i].value
+@@ -5740,13 +5796,15 @@ dtdCopy(DTD *newDtd, const DTD *oldDtd, 
+   }
+ 
+   /* Copy the entity tables. */
+-  if (!copyEntityTable(&(newDtd->generalEntities),
++  if (!copyEntityTable(oldParser,
++                       &(newDtd->generalEntities),
+                        &(newDtd->pool),
+                        &(oldDtd->generalEntities)))
+       return 0;
+ 
+ #ifdef XML_DTD
+-  if (!copyEntityTable(&(newDtd->paramEntities),
++  if (!copyEntityTable(oldParser,
++                       &(newDtd->paramEntities),
+                        &(newDtd->pool),
+                        &(oldDtd->paramEntities)))
+       return 0;
+@@ -5769,7 +5827,8 @@ dtdCopy(DTD *newDtd, const DTD *oldDtd, 
+ }  /* End dtdCopy */
+ 
+ static int
+-copyEntityTable(HASH_TABLE *newTable,
++copyEntityTable(XML_Parser oldParser,
++                HASH_TABLE *newTable,
+                 STRING_POOL *newPool,
+                 const HASH_TABLE *oldTable)
+ {
+@@ -5788,7 +5847,7 @@ copyEntityTable(HASH_TABLE *newTable,
+     name = poolCopyString(newPool, oldE->name);
+     if (!name)
+       return 0;
+-    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
++    newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
+     if (!newE)
+       return 0;
+     if (oldE->systemId) {
+@@ -5846,16 +5905,16 @@ keyeq(KEY s1, KEY s2)
+ }
+ 
+ static unsigned long FASTCALL
+-hash(KEY s)
++hash(XML_Parser parser, KEY s)
+ {
+-  unsigned long h = 0;
++  unsigned long h = hash_secret_salt;
+   while (*s)
+     h = CHAR_HASH(h, *s++);
+   return h;
+ }
+ 
+ static NAMED *
+-lookup(HASH_TABLE *table, KEY name, size_t createSize)
++lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
+ {
+   size_t i;
+   if (table->size == 0) {
+@@ -5872,10 +5931,10 @@ lookup(HASH_TABLE *table, KEY name, size
+       return NULL;
+     }
+     memset(table->v, 0, tsize);
+-    i = hash(name) & ((unsigned long)table->size - 1);
++    i = hash(parser, name) & ((unsigned long)table->size - 1);
+   }
+   else {
+-    unsigned long h = hash(name);
++    unsigned long h = hash(parser, name);
+     unsigned long mask = (unsigned long)table->size - 1;
+     unsigned char step = 0;
+     i = h & mask;
+@@ -5901,7 +5960,7 @@ lookup(HASH_TABLE *table, KEY name, size
+       memset(newV, 0, tsize);
+       for (i = 0; i < table->size; i++)
+         if (table->v[i]) {
+-          unsigned long newHash = hash(table->v[i]->name);
++          unsigned long newHash = hash(parser, table->v[i]->name);
+           size_t j = newHash & newMask;
+           step = 0;
+           while (newV[j]) {
+@@ -6276,7 +6335,7 @@ getElementType(XML_Parser parser,
+ 
+   if (!name)
+     return NULL;
+-  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
++  ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
+   if (!ret)
+     return NULL;
+   if (ret->name != name)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/libexpat/patches/CVE-2012-1148.patch	Wed Aug 22 09:34:32 2012 -0500
@@ -0,0 +1,21 @@
+
+https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-1148
+
+--- lib/xmlparse.c.cve1148
++++ lib/xmlparse.c
+@@ -6181,12 +6181,13 @@ poolGrow(STRING_POOL *pool)
+   }
+   if (pool->blocks && pool->start == pool->blocks->s) {
+     int blockSize = (int)(pool->end - pool->start)*2;
+-    pool->blocks = (BLOCK *)
++    BLOCK *temp = (BLOCK *)
+       pool->mem->realloc_fcn(pool->blocks,
+                              (offsetof(BLOCK, s)
+                               + blockSize * sizeof(XML_Char)));
+-    if (pool->blocks == NULL)
++    if (temp == NULL)
+       return XML_FALSE;
++    pool->blocks = temp;
+     pool->blocks->size = blockSize;
+     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+     pool->start = pool->blocks->s;