summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2023-03-14 13:55:06 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2023-03-14 15:14:38 +0100
commitf8efa589e886b6910a438d84357d9b5a76ba9ca0 (patch)
tree8634fea2e4a4ae2bf597d5c104bfa7565db06c98
parent64b76f8163d3608f9881b4de23dcc06530ba9323 (diff)
downloadlibxml2-f8efa589e886b6910a438d84357d9b5a76ba9ca0.tar.gz
malloc-fail: Handle malloc failures in xmlSchemaInitTypes
Note that this changes the return value of public function xmlSchemaInitTypes from void to int. This shouldn't break the ABI on most platforms. Found when investigating #500.
-rw-r--r--include/libxml/xmlschemastypes.h2
-rw-r--r--xmlschemas.c3
-rw-r--r--xmlschemastypes.c204
3 files changed, 163 insertions, 46 deletions
diff --git a/include/libxml/xmlschemastypes.h b/include/libxml/xmlschemastypes.h
index eb1388db..e2cde357 100644
--- a/include/libxml/xmlschemastypes.h
+++ b/include/libxml/xmlschemastypes.h
@@ -30,7 +30,7 @@ typedef enum {
XML_SCHEMA_WHITESPACE_COLLAPSE = 3
} xmlSchemaWhitespaceValueType;
-XMLPUBFUN void
+XMLPUBFUN int
xmlSchemaInitTypes (void);
XML_DEPRECATED
XMLPUBFUN void
diff --git a/xmlschemas.c b/xmlschemas.c
index 65c9123c..6a353858 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -21457,7 +21457,8 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
* the API; i.e. not automatically by the validated instance document.
*/
- xmlSchemaInitTypes();
+ if (xmlSchemaInitTypes() < 0)
+ return (NULL);
if (ctxt == NULL)
return (NULL);
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 5d7eb419..60268e2d 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -385,18 +385,61 @@ xmlSchemaAddParticle(void)
return (ret);
}
+static void
+xmlSchemaFreeTypeEntry(void *type, const xmlChar *name ATTRIBUTE_UNUSED) {
+ xmlSchemaFreeType((xmlSchemaTypePtr) type);
+}
+
+/**
+ * xmlSchemaCleanupTypesInternal:
+ *
+ * Cleanup the default XML Schemas type library
+ */
+static void
+xmlSchemaCleanupTypesInternal(void) {
+ xmlSchemaParticlePtr particle;
+
+ /*
+ * Free xs:anyType.
+ */
+ if (xmlSchemaTypeAnyTypeDef != NULL) {
+ /* Attribute wildcard. */
+ xmlSchemaFreeWildcard(xmlSchemaTypeAnyTypeDef->attributeWildcard);
+ /* Content type. */
+ particle = (xmlSchemaParticlePtr) xmlSchemaTypeAnyTypeDef->subtypes;
+ /* Wildcard. */
+ xmlSchemaFreeWildcard((xmlSchemaWildcardPtr)
+ particle->children->children->children);
+ xmlFree((xmlSchemaParticlePtr) particle->children->children);
+ /* Sequence model group. */
+ xmlFree((xmlSchemaModelGroupPtr) particle->children);
+ xmlFree((xmlSchemaParticlePtr) particle);
+ xmlSchemaTypeAnyTypeDef->subtypes = NULL;
+ xmlSchemaTypeAnyTypeDef = NULL;
+ }
+
+ xmlHashFree(xmlSchemaTypesBank, xmlSchemaFreeTypeEntry);
+ xmlSchemaTypesBank = NULL;
+ /* Note that the xmlSchemaType*Def pointers aren't set to NULL. */
+}
+
/*
* xmlSchemaInitTypes:
*
* Initialize the default XML Schemas type library
+ *
+ * Returns 0 on success, -1 on error.
*/
-void
+int
xmlSchemaInitTypes(void)
{
if (xmlSchemaTypesInitialized != 0)
- return;
+ return (0);
xmlSchemaTypesBank = xmlHashCreate(40);
-
+ if (xmlSchemaTypesBank == NULL) {
+ xmlSchemaTypeErrMemory(NULL, NULL);
+ goto error;
+ }
/*
* 3.4.7 Built-in Complex Type Definition
@@ -404,10 +447,8 @@ xmlSchemaInitTypes(void)
xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType("anyType",
XML_SCHEMAS_ANYTYPE,
NULL);
- if (xmlSchemaTypeAnyTypeDef == NULL) {
- xmlSchemaTypeErrMemory(NULL, NULL);
- return;
- }
+ if (xmlSchemaTypeAnyTypeDef == NULL)
+ goto error;
xmlSchemaTypeAnyTypeDef->baseType = xmlSchemaTypeAnyTypeDef;
xmlSchemaTypeAnyTypeDef->contentType = XML_SCHEMA_CONTENT_MIXED;
/*
@@ -421,14 +462,14 @@ xmlSchemaInitTypes(void)
/* First particle. */
particle = xmlSchemaAddParticle();
if (particle == NULL)
- return;
+ goto error;
xmlSchemaTypeAnyTypeDef->subtypes = (xmlSchemaTypePtr) particle;
/* Sequence model group. */
sequence = (xmlSchemaModelGroupPtr)
xmlMalloc(sizeof(xmlSchemaModelGroup));
if (sequence == NULL) {
xmlSchemaTypeErrMemory(NULL, "allocating model group component");
- return;
+ goto error;
}
memset(sequence, 0, sizeof(xmlSchemaModelGroup));
sequence->type = XML_SCHEMA_TYPE_SEQUENCE;
@@ -436,7 +477,7 @@ xmlSchemaInitTypes(void)
/* Second particle. */
particle = xmlSchemaAddParticle();
if (particle == NULL)
- return;
+ goto error;
particle->minOccurs = 0;
particle->maxOccurs = UNBOUNDED;
sequence->children = (xmlSchemaTreeItemPtr) particle;
@@ -444,7 +485,7 @@ xmlSchemaInitTypes(void)
wild = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
if (wild == NULL) {
xmlSchemaTypeErrMemory(NULL, "allocating wildcard component");
- return;
+ goto error;
}
memset(wild, 0, sizeof(xmlSchemaWildcard));
wild->type = XML_SCHEMA_TYPE_ANY;
@@ -458,7 +499,7 @@ xmlSchemaInitTypes(void)
if (wild == NULL) {
xmlSchemaTypeErrMemory(NULL, "could not create an attribute "
"wildcard on anyType");
- return;
+ goto error;
}
memset(wild, 0, sizeof(xmlSchemaWildcard));
wild->any = 1;
@@ -468,66 +509,106 @@ xmlSchemaInitTypes(void)
xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType",
XML_SCHEMAS_ANYSIMPLETYPE,
xmlSchemaTypeAnyTypeDef);
+ if (xmlSchemaTypeAnySimpleTypeDef == NULL)
+ goto error;
/*
* primitive datatypes
*/
xmlSchemaTypeStringDef = xmlSchemaInitBasicType("string",
XML_SCHEMAS_STRING,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeStringDef == NULL)
+ goto error;
xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType("decimal",
XML_SCHEMAS_DECIMAL,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeDecimalDef == NULL)
+ goto error;
xmlSchemaTypeDateDef = xmlSchemaInitBasicType("date",
XML_SCHEMAS_DATE,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeDateDef == NULL)
+ goto error;
xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType("dateTime",
XML_SCHEMAS_DATETIME,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeDatetimeDef == NULL)
+ goto error;
xmlSchemaTypeTimeDef = xmlSchemaInitBasicType("time",
XML_SCHEMAS_TIME,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeTimeDef == NULL)
+ goto error;
xmlSchemaTypeGYearDef = xmlSchemaInitBasicType("gYear",
XML_SCHEMAS_GYEAR,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeGYearDef == NULL)
+ goto error;
xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType("gYearMonth",
XML_SCHEMAS_GYEARMONTH,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeGYearMonthDef == NULL)
+ goto error;
xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType("gMonth",
XML_SCHEMAS_GMONTH,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeGMonthDef == NULL)
+ goto error;
xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType("gMonthDay",
XML_SCHEMAS_GMONTHDAY,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeGMonthDayDef == NULL)
+ goto error;
xmlSchemaTypeGDayDef = xmlSchemaInitBasicType("gDay",
XML_SCHEMAS_GDAY,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeGDayDef == NULL)
+ goto error;
xmlSchemaTypeDurationDef = xmlSchemaInitBasicType("duration",
XML_SCHEMAS_DURATION,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeDurationDef == NULL)
+ goto error;
xmlSchemaTypeFloatDef = xmlSchemaInitBasicType("float",
XML_SCHEMAS_FLOAT,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeFloatDef == NULL)
+ goto error;
xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType("double",
XML_SCHEMAS_DOUBLE,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeDoubleDef == NULL)
+ goto error;
xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType("boolean",
XML_SCHEMAS_BOOLEAN,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeBooleanDef == NULL)
+ goto error;
xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType("anyURI",
XML_SCHEMAS_ANYURI,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeAnyURIDef == NULL)
+ goto error;
xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType("hexBinary",
XML_SCHEMAS_HEXBINARY,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeHexBinaryDef == NULL)
+ goto error;
xmlSchemaTypeBase64BinaryDef
= xmlSchemaInitBasicType("base64Binary", XML_SCHEMAS_BASE64BINARY,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeBase64BinaryDef == NULL)
+ goto error;
xmlSchemaTypeNotationDef = xmlSchemaInitBasicType("NOTATION",
XML_SCHEMAS_NOTATION,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeNotationDef == NULL)
+ goto error;
xmlSchemaTypeQNameDef = xmlSchemaInitBasicType("QName",
XML_SCHEMAS_QNAME,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeQNameDef == NULL)
+ goto error;
/*
* derived datatypes
@@ -535,69 +616,113 @@ xmlSchemaInitTypes(void)
xmlSchemaTypeIntegerDef = xmlSchemaInitBasicType("integer",
XML_SCHEMAS_INTEGER,
xmlSchemaTypeDecimalDef);
+ if (xmlSchemaTypeIntegerDef == NULL)
+ goto error;
xmlSchemaTypeNonPositiveIntegerDef =
xmlSchemaInitBasicType("nonPositiveInteger",
XML_SCHEMAS_NPINTEGER,
xmlSchemaTypeIntegerDef);
+ if (xmlSchemaTypeNonPositiveIntegerDef == NULL)
+ goto error;
xmlSchemaTypeNegativeIntegerDef =
xmlSchemaInitBasicType("negativeInteger", XML_SCHEMAS_NINTEGER,
xmlSchemaTypeNonPositiveIntegerDef);
+ if (xmlSchemaTypeNegativeIntegerDef == NULL)
+ goto error;
xmlSchemaTypeLongDef =
xmlSchemaInitBasicType("long", XML_SCHEMAS_LONG,
xmlSchemaTypeIntegerDef);
+ if (xmlSchemaTypeLongDef == NULL)
+ goto error;
xmlSchemaTypeIntDef = xmlSchemaInitBasicType("int", XML_SCHEMAS_INT,
xmlSchemaTypeLongDef);
+ if (xmlSchemaTypeIntDef == NULL)
+ goto error;
xmlSchemaTypeShortDef = xmlSchemaInitBasicType("short",
XML_SCHEMAS_SHORT,
xmlSchemaTypeIntDef);
+ if (xmlSchemaTypeShortDef == NULL)
+ goto error;
xmlSchemaTypeByteDef = xmlSchemaInitBasicType("byte",
XML_SCHEMAS_BYTE,
xmlSchemaTypeShortDef);
+ if (xmlSchemaTypeByteDef == NULL)
+ goto error;
xmlSchemaTypeNonNegativeIntegerDef =
xmlSchemaInitBasicType("nonNegativeInteger",
XML_SCHEMAS_NNINTEGER,
xmlSchemaTypeIntegerDef);
+ if (xmlSchemaTypeNonNegativeIntegerDef == NULL)
+ goto error;
xmlSchemaTypeUnsignedLongDef =
xmlSchemaInitBasicType("unsignedLong", XML_SCHEMAS_ULONG,
xmlSchemaTypeNonNegativeIntegerDef);
+ if (xmlSchemaTypeUnsignedLongDef == NULL)
+ goto error;
xmlSchemaTypeUnsignedIntDef =
xmlSchemaInitBasicType("unsignedInt", XML_SCHEMAS_UINT,
xmlSchemaTypeUnsignedLongDef);
+ if (xmlSchemaTypeUnsignedIntDef == NULL)
+ goto error;
xmlSchemaTypeUnsignedShortDef =
xmlSchemaInitBasicType("unsignedShort", XML_SCHEMAS_USHORT,
xmlSchemaTypeUnsignedIntDef);
+ if (xmlSchemaTypeUnsignedShortDef == NULL)
+ goto error;
xmlSchemaTypeUnsignedByteDef =
xmlSchemaInitBasicType("unsignedByte", XML_SCHEMAS_UBYTE,
xmlSchemaTypeUnsignedShortDef);
+ if (xmlSchemaTypeUnsignedByteDef == NULL)
+ goto error;
xmlSchemaTypePositiveIntegerDef =
xmlSchemaInitBasicType("positiveInteger", XML_SCHEMAS_PINTEGER,
xmlSchemaTypeNonNegativeIntegerDef);
+ if (xmlSchemaTypePositiveIntegerDef == NULL)
+ goto error;
xmlSchemaTypeNormStringDef = xmlSchemaInitBasicType("normalizedString",
XML_SCHEMAS_NORMSTRING,
xmlSchemaTypeStringDef);
+ if (xmlSchemaTypeNormStringDef == NULL)
+ goto error;
xmlSchemaTypeTokenDef = xmlSchemaInitBasicType("token",
XML_SCHEMAS_TOKEN,
xmlSchemaTypeNormStringDef);
+ if (xmlSchemaTypeTokenDef == NULL)
+ goto error;
xmlSchemaTypeLanguageDef = xmlSchemaInitBasicType("language",
XML_SCHEMAS_LANGUAGE,
xmlSchemaTypeTokenDef);
+ if (xmlSchemaTypeLanguageDef == NULL)
+ goto error;
xmlSchemaTypeNameDef = xmlSchemaInitBasicType("Name",
XML_SCHEMAS_NAME,
xmlSchemaTypeTokenDef);
+ if (xmlSchemaTypeNameDef == NULL)
+ goto error;
xmlSchemaTypeNmtokenDef = xmlSchemaInitBasicType("NMTOKEN",
XML_SCHEMAS_NMTOKEN,
xmlSchemaTypeTokenDef);
+ if (xmlSchemaTypeNmtokenDef == NULL)
+ goto error;
xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType("NCName",
XML_SCHEMAS_NCNAME,
xmlSchemaTypeNameDef);
+ if (xmlSchemaTypeNCNameDef == NULL)
+ goto error;
xmlSchemaTypeIdDef = xmlSchemaInitBasicType("ID", XML_SCHEMAS_ID,
xmlSchemaTypeNCNameDef);
+ if (xmlSchemaTypeIdDef == NULL)
+ goto error;
xmlSchemaTypeIdrefDef = xmlSchemaInitBasicType("IDREF",
XML_SCHEMAS_IDREF,
xmlSchemaTypeNCNameDef);
+ if (xmlSchemaTypeIdrefDef == NULL)
+ goto error;
xmlSchemaTypeEntityDef = xmlSchemaInitBasicType("ENTITY",
XML_SCHEMAS_ENTITY,
xmlSchemaTypeNCNameDef);
+ if (xmlSchemaTypeEntityDef == NULL)
+ goto error;
/*
* Derived list types.
*/
@@ -605,25 +730,31 @@ xmlSchemaInitTypes(void)
xmlSchemaTypeEntitiesDef = xmlSchemaInitBasicType("ENTITIES",
XML_SCHEMAS_ENTITIES,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeEntitiesDef == NULL)
+ goto error;
xmlSchemaTypeEntitiesDef->subtypes = xmlSchemaTypeEntityDef;
/* IDREFS */
xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType("IDREFS",
XML_SCHEMAS_IDREFS,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeIdrefsDef == NULL)
+ goto error;
xmlSchemaTypeIdrefsDef->subtypes = xmlSchemaTypeIdrefDef;
/* NMTOKENS */
xmlSchemaTypeNmtokensDef = xmlSchemaInitBasicType("NMTOKENS",
XML_SCHEMAS_NMTOKENS,
xmlSchemaTypeAnySimpleTypeDef);
+ if (xmlSchemaTypeNmtokensDef == NULL)
+ goto error;
xmlSchemaTypeNmtokensDef->subtypes = xmlSchemaTypeNmtokenDef;
xmlSchemaTypesInitialized = 1;
-}
+ return (0);
-static void
-xmlSchemaFreeTypeEntry(void *type, const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlSchemaFreeType((xmlSchemaTypePtr) type);
+error:
+ xmlSchemaCleanupTypesInternal();
+ return (-1);
}
/**
@@ -632,34 +763,16 @@ xmlSchemaFreeTypeEntry(void *type, const xmlChar *name ATTRIBUTE_UNUSED) {
* DEPRECATED: This function will be made private. Call xmlCleanupParser
* to free global state but see the warnings there. xmlCleanupParser
* should be only called once at program exit. In most cases, you don't
- * have call cleanup functions at all.
+ * have to call cleanup functions at all.
*
* Cleanup the default XML Schemas type library
*/
void
xmlSchemaCleanupTypes(void) {
- if (xmlSchemaTypesInitialized == 0)
- return;
- /*
- * Free xs:anyType.
- */
- {
- xmlSchemaParticlePtr particle;
- /* Attribute wildcard. */
- xmlSchemaFreeWildcard(xmlSchemaTypeAnyTypeDef->attributeWildcard);
- /* Content type. */
- particle = (xmlSchemaParticlePtr) xmlSchemaTypeAnyTypeDef->subtypes;
- /* Wildcard. */
- xmlSchemaFreeWildcard((xmlSchemaWildcardPtr)
- particle->children->children->children);
- xmlFree((xmlSchemaParticlePtr) particle->children->children);
- /* Sequence model group. */
- xmlFree((xmlSchemaModelGroupPtr) particle->children);
- xmlFree((xmlSchemaParticlePtr) particle);
- xmlSchemaTypeAnyTypeDef->subtypes = NULL;
+ if (xmlSchemaTypesInitialized != 0) {
+ xmlSchemaCleanupTypesInternal();
+ xmlSchemaTypesInitialized = 0;
}
- xmlHashFree(xmlSchemaTypesBank, xmlSchemaFreeTypeEntry);
- xmlSchemaTypesInitialized = 0;
}
/**
@@ -754,8 +867,9 @@ xmlSchemaIsBuiltInTypeFacet(xmlSchemaTypePtr type, int facetType)
xmlSchemaTypePtr
xmlSchemaGetBuiltInType(xmlSchemaValType type)
{
- if (xmlSchemaTypesInitialized == 0)
- xmlSchemaInitTypes();
+ if ((xmlSchemaTypesInitialized == 0) &&
+ (xmlSchemaInitTypes() < 0))
+ return (NULL);
switch (type) {
case XML_SCHEMAS_ANYSIMPLETYPE:
@@ -1087,8 +1201,9 @@ xmlSchemaFreeValue(xmlSchemaValPtr value) {
*/
xmlSchemaTypePtr
xmlSchemaGetPredefinedType(const xmlChar *name, const xmlChar *ns) {
- if (xmlSchemaTypesInitialized == 0)
- xmlSchemaInitTypes();
+ if ((xmlSchemaTypesInitialized == 0) &&
+ (xmlSchemaInitTypes() < 0))
+ return (NULL);
if (name == NULL)
return(NULL);
return((xmlSchemaTypePtr) xmlHashLookup2(xmlSchemaTypesBank, name, ns));
@@ -2257,8 +2372,9 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
xmlChar *norm = NULL;
int ret = 0;
- if (xmlSchemaTypesInitialized == 0)
- xmlSchemaInitTypes();
+ if ((xmlSchemaTypesInitialized == 0) &&
+ (xmlSchemaInitTypes() < 0))
+ return (-1);
if (type == NULL)
return (-1);