Bug 2062690 - Update to Expat 2.8.4. r=mccr8

Differential Revision: https://phabricator.services.mozilla.com/D322437
This commit is contained in:
Ryan VanderMeulen
2026-09-11 01:51:45 +00:00
committed by rvandermeulen@mozilla.com
parent a5566dd1d1
commit f09cc8bec5
5 changed files with 195 additions and 69 deletions
+1 -1
View File
@@ -1096,7 +1096,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
*/
# define XML_MAJOR_VERSION 2
# define XML_MINOR_VERSION 8
# define XML_MICRO_VERSION 3
# define XML_MICRO_VERSION 4
# ifdef __cplusplus
}
+1
View File
@@ -33,6 +33,7 @@
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
Copyright (c) 2026 Matthew Wozniczka <mattheww@simba.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
+189 -64
View File
@@ -1,4 +1,4 @@
/* ee5f82c3ffd57c5224394ba46f348dbce466d34d6c925a527ae46b1cfe6adf1d (2.8.3+)
/* 13c4e8da8fccffb0e8e599684e0d447ad14c1bb0b48792cf5dd77d8712301871 (2.8.4+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -51,6 +51,9 @@
Copyright (c) 2026 Kartik Kenchi <netliomax25@gmail.com>
Copyright (c) 2026 Haris Hussain <hextheshadow0x@gmail.com>
Copyright (c) 2026 Evgeny Kotkov <kotkov@apache.org>
Copyright (c) 2026 Darren Carreras <carrerasdarren@gmail.com>
Copyright (c) 2026 Alberto Maschietto <albertomaschietto9@gmail.com>
Copyright (c) 2026 Zeyou Liu <zeyouliu@tencent.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -340,7 +343,7 @@ typedef struct {
const XML_Char *base;
const XML_Char *publicId;
const XML_Char *notation;
XML_Bool open;
bool open;
XML_Bool hasMore; /* true if entity has not been completely processed */
/* An entity can be open while being already completely processed (hasMore ==
XML_FALSE). The reason is the delayed closing of entities until their inner
@@ -391,6 +394,22 @@ typedef struct {
const XML_Char *value;
} DEFAULT_ATTRIBUTE;
// This structure allows mapping attribute names to instances of
// `DEFAULT_ATTRIBUTE`.
typedef struct {
// Member `name` goes first to make this structure compatible with structure
// `NAMED` (further up), which is needed to support use of structure
// `NAME_AND_DEFAULT_ATTRIBUTE` in a hash table as implemented by function
// `lookup` (further down).
const XML_Char *name;
// We would store a `DEFAULT_ATTRIBUTE *` here but the backing array
// can be reallocated which would invalidate the pointer. Using an index
// into the array instead, avoids that problem.
size_t attIndex;
// This is set to `false` by function `lookup`.
bool initialized;
} NAME_AND_DEFAULT_ATTRIBUTE;
typedef struct {
unsigned long version;
unsigned long hash;
@@ -404,7 +423,7 @@ typedef struct {
size_t nDefaultAtts;
size_t allocDefaultAtts;
DEFAULT_ATTRIBUTE *defaultAtts;
HASH_TABLE defaultAttsNames;
HASH_TABLE defaultAttForName;
} ELEMENT_TYPE;
typedef struct {
@@ -612,6 +631,8 @@ static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
XML_Parser parser);
static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
STRING_POOL *newPool, const HASH_TABLE *oldTable);
static NAMED *lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name,
size_t nameLen, size_t createSize);
static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
size_t createSize);
static void FASTCALL hashTableInit(HASH_TABLE *table, XML_Parser parser);
@@ -804,6 +825,8 @@ struct XML_ParserStruct {
void *m_unknownEncodingMem;
void *m_unknownEncodingData;
void *m_unknownEncodingHandlerData;
// Application callback invoked by callUnknownEncodingConvert.
int(XMLCALL *m_unknownEncodingConvert)(void *, const char *);
void(XMLCALL *m_unknownEncodingRelease)(void *);
PROLOG_STATE m_prologState;
Processor *m_processor;
@@ -1267,6 +1290,25 @@ isCalledFromInsideHandler(XML_Parser parser) {
return parser->m_handlerCallDepth > 0;
}
static void
callUnknownEncodingRelease(XML_Parser parser) {
beforeHandler(parser);
parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
afterHandler(parser);
parser->m_unknownEncodingRelease = NULL;
parser->m_unknownEncodingData = NULL;
}
static int XMLCALL
callUnknownEncodingConvert(void *data, const char *p) {
XML_Parser parser = data;
beforeHandler(parser);
const int result
= parser->m_unknownEncodingConvert(parser->m_unknownEncodingData, p);
afterHandler(parser);
return result;
}
static enum XML_Error
callProcessor(XML_Parser parser, const char *start, const char *end,
const char **endPtr) {
@@ -1626,6 +1668,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
parser->m_inheritedBindings = NULL;
parser->m_nSpecifiedAtts = 0;
parser->m_unknownEncodingMem = NULL;
parser->m_unknownEncodingConvert = NULL;
parser->m_unknownEncodingRelease = NULL;
parser->m_unknownEncodingData = NULL;
parser->m_parsingStatus.parsing = XML_INITIALIZED;
@@ -1716,7 +1759,7 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
moveToFreeBindingList(parser, parser->m_inheritedBindings);
FREE(parser, parser->m_unknownEncodingMem);
if (parser->m_unknownEncodingRelease)
parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
callUnknownEncodingRelease(parser);
poolClear(&parser->m_tempPool);
poolClear(&parser->m_temp2Pool);
FREE(parser, (void *)parser->m_protocolEncodingName);
@@ -2033,7 +2076,7 @@ XML_ParserFree(XML_Parser parser) {
FREE(parser, parser->m_nsAtts);
FREE(parser, parser->m_unknownEncodingMem);
if (parser->m_unknownEncodingRelease)
parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
callUnknownEncodingRelease(parser);
FREE(parser, parser);
}
@@ -2895,7 +2938,7 @@ XML_GetCurrentLineNumber(XML_Parser parser) {
parser->m_eventPtr, &parser->m_position);
parser->m_positionPtr = parser->m_eventPtr;
}
// NOTE: XML_Size is known to wrap around for >2 4iB content
// NOTE: XML_Size is known to wrap around for >4 GiB content
// on 32bit machines and 64bit Windows, unless (non-default and
// uncommon) XML_LARGE_SIZE is defined.
// That's a bug and it only lives on because we cannot break
@@ -2912,7 +2955,7 @@ XML_GetCurrentColumnNumber(XML_Parser parser) {
parser->m_eventPtr, &parser->m_position);
parser->m_positionPtr = parser->m_eventPtr;
}
// NOTE: XML_Size is known to wrap around for >2 4iB content
// NOTE: XML_Size is known to wrap around for >4 GiB content
// on 32bit machines and 64bit Windows, unless (non-default and
// uncommon) XML_LARGE_SIZE is defined.
// That's a bug and it only lives on because we cannot break
@@ -3600,9 +3643,9 @@ doContentInternal(XML_Parser parser, int startTagLevel, const ENCODING *enc,
return result;
} else if (parser->m_externalEntityRefHandler) {
const XML_Char *context;
entity->open = XML_TRUE;
entity->open = true;
context = getContext(parser);
entity->open = XML_FALSE;
entity->open = false;
if (! context)
return XML_ERROR_NO_MEMORY;
beforeHandler(parser);
@@ -4057,8 +4100,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
sizeof(ELEMENT_TYPE));
if (! elementType)
return XML_ERROR_NO_MEMORY;
if (! elementType->defaultAttsNames.parser)
hashTableInit(&(elementType->defaultAttsNames), parser);
if (! elementType->defaultAttForName.parser)
hashTableInit(&(elementType->defaultAttForName), parser);
if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
return XML_ERROR_NO_MEMORY;
}
@@ -4171,11 +4214,14 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
/* figure out whether declared as other than CDATA */
if (attId->maybeTokenized) {
for (size_t j = 0; j < nDefaultAtts; j++) {
if (attId == elementType->defaultAtts[j].id) {
isCdata = elementType->defaultAtts[j].isCdata;
break;
}
NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
= (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
parser, &(elementType->defaultAttForName), attId->name, 0);
if (nameAndDefaultAttribute != NULL) {
assert(nameAndDefaultAttribute->attIndex < elementType->nDefaultAtts);
const DEFAULT_ATTRIBUTE *const att
= elementType->defaultAtts + nameAndDefaultAttribute->attIndex;
isCdata = att->isCdata;
}
}
@@ -4289,8 +4335,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
/* END MOZILLA CHANGE */
unsigned char oldNsAttsPower = parser->m_nsAttsPower;
/* size of hash table must be at least 2 * (# of prefixed attributes) */
if ((nPrefixes << 1)
>> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
if (parser->m_nsAttsPower == 0
|| (nPrefixes >> (parser->m_nsAttsPower - 1))) {
/* hash table size must also be a power of 2 and >= 8 */
while (nPrefixes >> parser->m_nsAttsPower++)
;
@@ -5245,25 +5291,34 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
const int status = parser->m_unknownEncodingHandler(
parser->m_unknownEncodingHandlerData, encodingName, &info);
afterHandler(parser);
parser->m_unknownEncodingRelease = info.release;
parser->m_unknownEncodingData = info.data;
if (status) {
ENCODING *enc;
parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
if (! parser->m_unknownEncodingMem) {
if (info.release)
info.release(info.data);
if (parser->m_unknownEncodingRelease)
callUnknownEncodingRelease(parser);
else
parser->m_unknownEncodingData = NULL;
return XML_ERROR_NO_MEMORY;
}
parser->m_unknownEncodingConvert = info.convert;
enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
parser->m_unknownEncodingMem, info.map, info.convert, info.data);
parser->m_unknownEncodingMem, info.map,
info.convert ? callUnknownEncodingConvert : NULL, parser);
if (enc) {
parser->m_unknownEncodingData = info.data;
parser->m_unknownEncodingRelease = info.release;
parser->m_encoding = enc;
return XML_ERROR_NONE;
}
parser->m_unknownEncodingConvert = NULL;
}
if (info.release != NULL)
info.release(info.data);
if (parser->m_unknownEncodingRelease != NULL)
callUnknownEncodingRelease(parser);
else
parser->m_unknownEncodingData = NULL;
}
return XML_ERROR_UNKNOWN_ENCODING;
}
@@ -6391,7 +6446,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
}
if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
entity->open = XML_TRUE;
entity->open = true;
entityTrackingOnOpen(parser, entity, __LINE__);
beforeHandler(parser);
const int status = parser->m_externalEntityRefHandler(
@@ -6406,11 +6461,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
afterHandler(parser);
if (! status) {
entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
entity->open = false;
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
}
entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
entity->open = false;
handleDefault = XML_FALSE;
if (! dtd->paramEntityRead) {
dtd->keepProcessing = dtd->standalone;
@@ -6734,7 +6789,7 @@ processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
if (! openEntity)
return XML_ERROR_NO_MEMORY;
}
entity->open = XML_TRUE;
entity->open = true;
entity->hasMore = XML_TRUE;
#if XML_GE == 1
entityTrackingOnOpen(parser, entity, __LINE__);
@@ -6825,7 +6880,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
// to false. This means we can directly remove the head of
// m_openInternalEntities
assert(parser->m_openInternalEntities == openEntity);
entity->open = XML_FALSE;
entity->open = false;
parser->m_openInternalEntities = parser->m_openInternalEntities->next;
/* put openEntity back in list of free instances */
@@ -6903,7 +6958,7 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
// with hasMore set to false. This means we can directly remove the head
// of m_openAttributeEntities
assert(parser->m_openAttributeEntities == openEntity);
entity->open = XML_FALSE;
entity->open = false;
parser->m_openAttributeEntities = parser->m_openAttributeEntities->next;
/* put openEntity back in list of free instances */
@@ -7205,7 +7260,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
if (entity->systemId) {
if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
entity->open = XML_TRUE;
entity->open = true;
entityTrackingOnOpen(parser, entity, __LINE__);
beforeHandler(parser);
const int status = parser->m_externalEntityRefHandler(
@@ -7214,12 +7269,12 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
afterHandler(parser);
if (! status) {
entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
entity->open = false;
result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
goto endEntityValue;
}
entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
entity->open = false;
if (! dtd->paramEntityRead)
dtd->keepProcessing = dtd->standalone;
} else
@@ -7369,7 +7424,7 @@ callStoreEntityValue(XML_Parser parser, const ENCODING *enc,
// with hasMore set to false. This means we can directly remove the head
// of m_openValueEntities
assert(parser->m_openValueEntities == openEntity);
entity->open = XML_FALSE;
entity->open = false;
parser->m_openValueEntities = parser->m_openValueEntities->next;
/* put openEntity back in list of free instances */
@@ -7550,7 +7605,7 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
/* The handling of default attributes gets messed up if we have
a default which duplicates a non-default. */
NAMED *const nameFound
= lookup(parser, &(type->defaultAttsNames), attId->name, 0);
= lookup(parser, &(type->defaultAttForName), attId->name, 0);
if (nameFound)
return 1;
if (isId && ! type->idAtt && ! attId->xmlns)
@@ -7586,11 +7641,24 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
if (! isCdata)
attId->maybeTokenized = XML_TRUE;
NAMED *const nameAddedOrFound
= lookup(parser, &(type->defaultAttsNames), attId->name, sizeof(NAMED));
if (! nameAddedOrFound)
NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
= (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
parser, &(type->defaultAttForName), attId->name,
sizeof(NAME_AND_DEFAULT_ATTRIBUTE));
if (! nameAndDefaultAttribute)
return 0;
assert(nameAndDefaultAttribute->name == attId->name);
// NOTE: The XML 1.0r4 spec says:
// "When more than one definition is provided for the same attribute of a
// given element type, the first declaration is binding and later
// declarations are ignored."
if (! nameAndDefaultAttribute->initialized) {
nameAndDefaultAttribute->attIndex = type->nDefaultAtts;
nameAndDefaultAttribute->initialized = true;
}
type->nDefaultAtts += 1;
return 1;
}
@@ -7791,7 +7859,7 @@ setContext(XML_Parser parser, const XML_Char *context) {
e = (ENTITY *)lookup(parser, &dtd->generalEntities,
poolStart(&parser->m_tempPool), 0);
if (e)
e->open = XML_TRUE;
e->open = true;
if (*s != XML_T('\0'))
s++;
context = s;
@@ -7910,7 +7978,7 @@ dtdReset(DTD *p, XML_Parser parser) {
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
if (! e)
break;
hashTableDestroy(&(e->defaultAttsNames));
hashTableDestroy(&(e->defaultAttForName));
FREE(parser, e->defaultAtts);
}
hashTableClear(&(p->generalEntities));
@@ -7954,7 +8022,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser) {
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
if (! e)
break;
hashTableDestroy(&(e->defaultAttsNames));
hashTableDestroy(&(e->defaultAttForName));
FREE(parser, e->defaultAtts);
}
hashTableDestroy(&(p->generalEntities));
@@ -8047,8 +8115,8 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
if (! newE)
return 0;
if (! newE->defaultAttsNames.parser)
hashTableInit(&(newE->defaultAttsNames), parser);
if (! newE->defaultAttForName.parser)
hashTableInit(&(newE->defaultAttForName), parser);
if (oldE->nDefaultAtts) {
/* Detect and prevent integer overflow. */
@@ -8081,11 +8149,22 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
} else
newE->defaultAtts[i].value = NULL;
NAMED *const nameAddedOrFound = lookup(parser, &(newE->defaultAttsNames),
attributeName, sizeof(NAMED));
if (! nameAddedOrFound) {
NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
= (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
parser, &(newE->defaultAttForName), attributeName,
sizeof(NAME_AND_DEFAULT_ATTRIBUTE));
if (! nameAndDefaultAttribute) {
return 0;
}
// NOTE: The XML 1.0r4 spec says:
// "When more than one definition is provided for the same attribute of a
// given element type, the first declaration is binding and later
// declarations are ignored."
if (! nameAndDefaultAttribute->initialized) {
nameAndDefaultAttribute->attIndex = i;
nameAndDefaultAttribute->initialized = true;
}
}
}
@@ -8182,19 +8261,23 @@ copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
#define INIT_POWER 6
// Compares two strings `s1` and `s2` whereas:
// - `s2` is zero-terminated but
// - `s1` is made up of exactly (not just up to) `s1len` non-zero characters.
static XML_Bool FASTCALL
keyeq(KEY s1, KEY s2) {
keyeq(KEY s1, size_t s1len, KEY s2) {
#ifdef XML_UNICODE
# ifdef XML_UNICODE_WCHAR_T
return (wcscmp(s1, s2) == 0) ? XML_TRUE : XML_FALSE;
return (wcsncmp(s1, s2, s1len) == 0 && s2[s1len] == L'\0') ? XML_TRUE
: XML_FALSE;
# else
for (; *s1 == *s2; s1++, s2++)
if (*s1 == 0)
return XML_TRUE;
return XML_FALSE;
for (; s1len > 0 && *s1 == *s2; s1len--, s1++, s2++)
; /* no loop body! */
return ((s1len == 0) && (*s2 == 0)) ? XML_TRUE : XML_FALSE;
# endif
#else
return (strcmp(s1, s2) == 0) ? XML_TRUE : XML_FALSE;
return (strncmp(s1, s2, s1len) == 0 && s2[s1len] == '\0') ? XML_TRUE
: XML_FALSE;
#endif
}
@@ -8212,18 +8295,38 @@ copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
}
static unsigned long FASTCALL
hash(XML_Parser parser, KEY s) {
hash(XML_Parser parser, KEY s, size_t keyLen) {
struct siphash state;
struct sipkey key;
(void)sip24_valid;
copy_salt_to_sipkey(parser, &key);
sip24_init(&state, &key);
sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
sip24_update(&state, s, keyLen * sizeof(XML_Char));
return (unsigned long)sip24_final(&state);
}
// Function `lookupWithLength` can be used to either…
//
// a) check whether an element with key `name` exists in the given hash table
// (read-only mode where `createSize == 0`) or
//
// b) check whether an element with key `name` exists in the given hash table
// *and* insert it if missing (i.e. read-write mode where `createSize != 0`.
//
// When inserting, a block of `createSize` number of bytes will be allocated
// and set to zero, and the resulting block of memory will be considered
// to start with a `NAMED` structure, and `->name = name;` is performed.
// The fact that all other bytes in the structure are initially zero can
// be used to tell cases "existed and found" and "newly inserted" apart
// with the structure returned.
//
// NOTE: Read-only lookup does not need zero-terminated keys but
// read-write mode does, because keys can be re-hashed later and the
// hash table does not store key length information.
//
static NAMED *
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name, size_t nameLen,
size_t createSize) {
size_t i;
if (table->size == 0) {
size_t tsize;
@@ -8239,14 +8342,14 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
return NULL;
}
memset(table->v, 0, tsize);
i = hash(parser, name) & ((unsigned long)table->size - 1);
i = hash(parser, name, nameLen) & ((unsigned long)table->size - 1);
} else {
unsigned long h = hash(parser, name);
unsigned long h = hash(parser, name, nameLen);
unsigned long mask = (unsigned long)table->size - 1;
unsigned char step = 0;
i = h & mask;
while (table->v[i]) {
if (keyeq(name, table->v[i]->name))
if (keyeq(name, nameLen, table->v[i]->name))
return table->v[i];
if (! step)
step = PROBE_STEP(h, mask, table->power);
@@ -8279,7 +8382,8 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
memset(newV, 0, tsize);
for (i = 0; i < table->size; i++)
if (table->v[i]) {
unsigned long newHash = hash(parser, table->v[i]->name);
KEY const key = table->v[i]->name;
unsigned long newHash = hash(parser, key, keylen(key));
size_t j = newHash & newMask;
step = 0;
while (newV[j]) {
@@ -8302,15 +8406,36 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
}
}
}
assert(createSize >= sizeof(NAMED));
table->v[i] = MALLOC(table->parser, createSize);
if (! table->v[i])
return NULL;
memset(table->v[i], 0, createSize);
table->v[i]->name = name;
table->v[i]->name = name; // NOTE: This requires and assumes zero termination!
(table->used)++;
return table->v[i];
}
// Function `lookup` can be used to either…
//
// a) check whether an element with key `name` exists in the given hash table
// (read-only mode where `createSize == 0`) or
//
// b) check whether an element with key `name` exists in the given hash table
// *and* insert it if missing (i.e. read-write mode where `createSize != 0`.
//
// When inserting, a block of `createSize` number of bytes will be allocated
// and set to zero, and the resulting block of memory will be considered
// to start with a `NAMED` structure, and `->name = name;` is performed.
// The fact that all other bytes in the structure are initially zero can
// be used to tell cases "existed and found" and "newly inserted" apart
// with the structure returned.
//
static NAMED *
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
return lookupWithLength(parser, table, name, keylen(name), createSize);
}
/* BEGIN MOZILLA CHANGE (unused API) */
#if 0
static void FASTCALL
@@ -8854,8 +8979,8 @@ getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
sizeof(ELEMENT_TYPE));
if (! ret)
return NULL;
if (! ret->defaultAttsNames.parser)
hashTableInit(&(ret->defaultAttsNames), getRootParserOf(parser, NULL));
if (! ret->defaultAttForName.parser)
hashTableInit(&(ret->defaultAttForName), getRootParserOf(parser, NULL));
if (ret->name != name)
poolDiscard(&dtd->pool);
else {
+2 -2
View File
@@ -169,8 +169,8 @@ typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *,
enum XML_Convert_Result {
XML_CONVERT_COMPLETED = 0,
XML_CONVERT_INPUT_INCOMPLETE = 1,
XML_CONVERT_OUTPUT_EXHAUSTED
= 2 /* and therefore potentially input remaining as well */
XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining
as well */
};
struct encoding {
+2 -2
View File
@@ -9,8 +9,8 @@ origin:
name: libexpat
description: Expat is an XML parser.
url: https://github.com/libexpat/libexpat
release: R_2_8_3 (2026-08-10T23:49:33+02:00).
revision: R_2_8_3
release: R_2_8_4 (2026-08-31T15:24:26+02:00).
revision: R_2_8_4
license: MIT
license-file: COPYING