jpayne@69: /* jpayne@69: __ __ _ jpayne@69: ___\ \/ /_ __ __ _| |_ jpayne@69: / _ \\ /| '_ \ / _` | __| jpayne@69: | __// \| |_) | (_| | |_ jpayne@69: \___/_/\_\ .__/ \__,_|\__| jpayne@69: |_| XML parser jpayne@69: jpayne@69: Copyright (c) 1997-2000 Thai Open Source Software Center Ltd jpayne@69: Copyright (c) 2000 Clark Cooper jpayne@69: Copyright (c) 2000-2005 Fred L. Drake, Jr. jpayne@69: Copyright (c) 2001-2002 Greg Stein jpayne@69: Copyright (c) 2002-2016 Karl Waclawek jpayne@69: Copyright (c) 2016-2024 Sebastian Pipping jpayne@69: Copyright (c) 2016 Cristian Rodríguez jpayne@69: Copyright (c) 2016 Thomas Beutlich jpayne@69: Copyright (c) 2017 Rhodri James jpayne@69: Copyright (c) 2022 Thijs Schreijer jpayne@69: Copyright (c) 2023 Hanno Böck jpayne@69: Copyright (c) 2023 Sony Corporation / Snild Dolkow jpayne@69: Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> jpayne@69: Licensed under the MIT license: jpayne@69: jpayne@69: Permission is hereby granted, free of charge, to any person obtaining jpayne@69: a copy of this software and associated documentation files (the jpayne@69: "Software"), to deal in the Software without restriction, including jpayne@69: without limitation the rights to use, copy, modify, merge, publish, jpayne@69: distribute, sublicense, and/or sell copies of the Software, and to permit jpayne@69: persons to whom the Software is furnished to do so, subject to the jpayne@69: following conditions: jpayne@69: jpayne@69: The above copyright notice and this permission notice shall be included jpayne@69: in all copies or substantial portions of the Software. jpayne@69: jpayne@69: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, jpayne@69: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF jpayne@69: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN jpayne@69: NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, jpayne@69: DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR jpayne@69: OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE jpayne@69: USE OR OTHER DEALINGS IN THE SOFTWARE. jpayne@69: */ jpayne@69: jpayne@69: #ifndef Expat_INCLUDED jpayne@69: #define Expat_INCLUDED 1 jpayne@69: jpayne@69: #include jpayne@69: #include "expat_external.h" jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: extern "C" { jpayne@69: #endif jpayne@69: jpayne@69: struct XML_ParserStruct; jpayne@69: typedef struct XML_ParserStruct *XML_Parser; jpayne@69: jpayne@69: typedef unsigned char XML_Bool; jpayne@69: #define XML_TRUE ((XML_Bool)1) jpayne@69: #define XML_FALSE ((XML_Bool)0) jpayne@69: jpayne@69: /* The XML_Status enum gives the possible return values for several jpayne@69: API functions. The preprocessor #defines are included so this jpayne@69: stanza can be added to code that still needs to support older jpayne@69: versions of Expat 1.95.x: jpayne@69: jpayne@69: #ifndef XML_STATUS_OK jpayne@69: #define XML_STATUS_OK 1 jpayne@69: #define XML_STATUS_ERROR 0 jpayne@69: #endif jpayne@69: jpayne@69: Otherwise, the #define hackery is quite ugly and would have been jpayne@69: dropped. jpayne@69: */ jpayne@69: enum XML_Status { jpayne@69: XML_STATUS_ERROR = 0, jpayne@69: #define XML_STATUS_ERROR XML_STATUS_ERROR jpayne@69: XML_STATUS_OK = 1, jpayne@69: #define XML_STATUS_OK XML_STATUS_OK jpayne@69: XML_STATUS_SUSPENDED = 2 jpayne@69: #define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED jpayne@69: }; jpayne@69: jpayne@69: enum XML_Error { jpayne@69: XML_ERROR_NONE, jpayne@69: XML_ERROR_NO_MEMORY, jpayne@69: XML_ERROR_SYNTAX, jpayne@69: XML_ERROR_NO_ELEMENTS, jpayne@69: XML_ERROR_INVALID_TOKEN, jpayne@69: XML_ERROR_UNCLOSED_TOKEN, jpayne@69: XML_ERROR_PARTIAL_CHAR, jpayne@69: XML_ERROR_TAG_MISMATCH, jpayne@69: XML_ERROR_DUPLICATE_ATTRIBUTE, jpayne@69: XML_ERROR_JUNK_AFTER_DOC_ELEMENT, jpayne@69: XML_ERROR_PARAM_ENTITY_REF, jpayne@69: XML_ERROR_UNDEFINED_ENTITY, jpayne@69: XML_ERROR_RECURSIVE_ENTITY_REF, jpayne@69: XML_ERROR_ASYNC_ENTITY, jpayne@69: XML_ERROR_BAD_CHAR_REF, jpayne@69: XML_ERROR_BINARY_ENTITY_REF, jpayne@69: XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, jpayne@69: XML_ERROR_MISPLACED_XML_PI, jpayne@69: XML_ERROR_UNKNOWN_ENCODING, jpayne@69: XML_ERROR_INCORRECT_ENCODING, jpayne@69: XML_ERROR_UNCLOSED_CDATA_SECTION, jpayne@69: XML_ERROR_EXTERNAL_ENTITY_HANDLING, jpayne@69: XML_ERROR_NOT_STANDALONE, jpayne@69: XML_ERROR_UNEXPECTED_STATE, jpayne@69: XML_ERROR_ENTITY_DECLARED_IN_PE, jpayne@69: XML_ERROR_FEATURE_REQUIRES_XML_DTD, jpayne@69: XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, jpayne@69: /* Added in 1.95.7. */ jpayne@69: XML_ERROR_UNBOUND_PREFIX, jpayne@69: /* Added in 1.95.8. */ jpayne@69: XML_ERROR_UNDECLARING_PREFIX, jpayne@69: XML_ERROR_INCOMPLETE_PE, jpayne@69: XML_ERROR_XML_DECL, jpayne@69: XML_ERROR_TEXT_DECL, jpayne@69: XML_ERROR_PUBLICID, jpayne@69: XML_ERROR_SUSPENDED, jpayne@69: XML_ERROR_NOT_SUSPENDED, jpayne@69: XML_ERROR_ABORTED, jpayne@69: XML_ERROR_FINISHED, jpayne@69: XML_ERROR_SUSPEND_PE, jpayne@69: /* Added in 2.0. */ jpayne@69: XML_ERROR_RESERVED_PREFIX_XML, jpayne@69: XML_ERROR_RESERVED_PREFIX_XMLNS, jpayne@69: XML_ERROR_RESERVED_NAMESPACE_URI, jpayne@69: /* Added in 2.2.1. */ jpayne@69: XML_ERROR_INVALID_ARGUMENT, jpayne@69: /* Added in 2.3.0. */ jpayne@69: XML_ERROR_NO_BUFFER, jpayne@69: /* Added in 2.4.0. */ jpayne@69: XML_ERROR_AMPLIFICATION_LIMIT_BREACH, jpayne@69: /* Added in 2.6.4. */ jpayne@69: XML_ERROR_NOT_STARTED, jpayne@69: }; jpayne@69: jpayne@69: enum XML_Content_Type { jpayne@69: XML_CTYPE_EMPTY = 1, jpayne@69: XML_CTYPE_ANY, jpayne@69: XML_CTYPE_MIXED, jpayne@69: XML_CTYPE_NAME, jpayne@69: XML_CTYPE_CHOICE, jpayne@69: XML_CTYPE_SEQ jpayne@69: }; jpayne@69: jpayne@69: enum XML_Content_Quant { jpayne@69: XML_CQUANT_NONE, jpayne@69: XML_CQUANT_OPT, jpayne@69: XML_CQUANT_REP, jpayne@69: XML_CQUANT_PLUS jpayne@69: }; jpayne@69: jpayne@69: /* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be jpayne@69: XML_CQUANT_NONE, and the other fields will be zero or NULL. jpayne@69: If type == XML_CTYPE_MIXED, then quant will be NONE or REP and jpayne@69: numchildren will contain number of elements that may be mixed in jpayne@69: and children point to an array of XML_Content cells that will be jpayne@69: all of XML_CTYPE_NAME type with no quantification. jpayne@69: jpayne@69: If type == XML_CTYPE_NAME, then the name points to the name, and jpayne@69: the numchildren field will be zero and children will be NULL. The jpayne@69: quant fields indicates any quantifiers placed on the name. jpayne@69: jpayne@69: CHOICE and SEQ will have name NULL, the number of children in jpayne@69: numchildren and children will point, recursively, to an array jpayne@69: of XML_Content cells. jpayne@69: jpayne@69: The EMPTY, ANY, and MIXED types will only occur at top level. jpayne@69: */ jpayne@69: jpayne@69: typedef struct XML_cp XML_Content; jpayne@69: jpayne@69: struct XML_cp { jpayne@69: enum XML_Content_Type type; jpayne@69: enum XML_Content_Quant quant; jpayne@69: XML_Char *name; jpayne@69: unsigned int numchildren; jpayne@69: XML_Content *children; jpayne@69: }; jpayne@69: jpayne@69: /* This is called for an element declaration. See above for jpayne@69: description of the model argument. It's the user code's responsibility jpayne@69: to free model when finished with it. See XML_FreeContentModel. jpayne@69: There is no need to free the model from the handler, it can be kept jpayne@69: around and freed at a later stage. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, jpayne@69: const XML_Char *name, jpayne@69: XML_Content *model); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl); jpayne@69: jpayne@69: /* The Attlist declaration handler is called for *each* attribute. So jpayne@69: a single Attlist declaration with multiple attributes declared will jpayne@69: generate multiple calls to this handler. The "default" parameter jpayne@69: may be NULL in the case of the "#IMPLIED" or "#REQUIRED" jpayne@69: keyword. The "isrequired" parameter will be true and the default jpayne@69: value will be NULL in the case of "#REQUIRED". If "isrequired" is jpayne@69: true and default is non-NULL, then this is a "#FIXED" default. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_AttlistDeclHandler)( jpayne@69: void *userData, const XML_Char *elname, const XML_Char *attname, jpayne@69: const XML_Char *att_type, const XML_Char *dflt, int isrequired); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl); jpayne@69: jpayne@69: /* The XML declaration handler is called for *both* XML declarations jpayne@69: and text declarations. The way to distinguish is that the version jpayne@69: parameter will be NULL for text declarations. The encoding jpayne@69: parameter may be NULL for XML declarations. The standalone jpayne@69: parameter will be -1, 0, or 1 indicating respectively that there jpayne@69: was no standalone parameter in the declaration, that it was given jpayne@69: as no, or that it was given as yes. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData, jpayne@69: const XML_Char *version, jpayne@69: const XML_Char *encoding, jpayne@69: int standalone); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl); jpayne@69: jpayne@69: typedef struct { jpayne@69: void *(*malloc_fcn)(size_t size); jpayne@69: void *(*realloc_fcn)(void *ptr, size_t size); jpayne@69: void (*free_fcn)(void *ptr); jpayne@69: } XML_Memory_Handling_Suite; jpayne@69: jpayne@69: /* Constructs a new parser; encoding is the encoding specified by the jpayne@69: external protocol or NULL if there is none specified. jpayne@69: */ jpayne@69: XMLPARSEAPI(XML_Parser) jpayne@69: XML_ParserCreate(const XML_Char *encoding); jpayne@69: jpayne@69: /* Constructs a new parser and namespace processor. Element type jpayne@69: names and attribute names that belong to a namespace will be jpayne@69: expanded; unprefixed attribute names are never expanded; unprefixed jpayne@69: element type names are expanded only if there is a default jpayne@69: namespace. The expanded name is the concatenation of the namespace jpayne@69: URI, the namespace separator character, and the local part of the jpayne@69: name. If the namespace separator is '\0' then the namespace URI jpayne@69: and the local part will be concatenated without any separator. jpayne@69: It is a programming error to use the separator '\0' with namespace jpayne@69: triplets (see XML_SetReturnNSTriplet). jpayne@69: If a namespace separator is chosen that can be part of a URI or jpayne@69: part of an XML name, splitting an expanded name back into its jpayne@69: 1, 2 or 3 original parts on application level in the element handler jpayne@69: may end up vulnerable, so these are advised against; sane choices for jpayne@69: a namespace separator are e.g. '\n' (line feed) and '|' (pipe). jpayne@69: jpayne@69: Note that Expat does not validate namespace URIs (beyond encoding) jpayne@69: against RFC 3986 today (and is not required to do so with regard to jpayne@69: the XML 1.0 namespaces specification) but it may start doing that jpayne@69: in future releases. Before that, an application using Expat must jpayne@69: be ready to receive namespace URIs containing non-URI characters. jpayne@69: */ jpayne@69: XMLPARSEAPI(XML_Parser) jpayne@69: XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); jpayne@69: jpayne@69: /* Constructs a new parser using the memory management suite referred to jpayne@69: by memsuite. If memsuite is NULL, then use the standard library memory jpayne@69: suite. If namespaceSeparator is non-NULL it creates a parser with jpayne@69: namespace processing as described above. The character pointed at jpayne@69: will serve as the namespace separator. jpayne@69: jpayne@69: All further memory operations used for the created parser will come from jpayne@69: the given suite. jpayne@69: */ jpayne@69: XMLPARSEAPI(XML_Parser) jpayne@69: XML_ParserCreate_MM(const XML_Char *encoding, jpayne@69: const XML_Memory_Handling_Suite *memsuite, jpayne@69: const XML_Char *namespaceSeparator); jpayne@69: jpayne@69: /* Prepare a parser object to be reused. This is particularly jpayne@69: valuable when memory allocation overhead is disproportionately high, jpayne@69: such as when a large number of small documnents need to be parsed. jpayne@69: All handlers are cleared from the parser, except for the jpayne@69: unknownEncodingHandler. The parser's external state is re-initialized jpayne@69: except for the values of ns and ns_triplets. jpayne@69: jpayne@69: Added in Expat 1.95.3. jpayne@69: */ jpayne@69: XMLPARSEAPI(XML_Bool) jpayne@69: XML_ParserReset(XML_Parser parser, const XML_Char *encoding); jpayne@69: jpayne@69: /* atts is array of name/value pairs, terminated by 0; jpayne@69: names and values are 0 terminated. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_StartElementHandler)(void *userData, jpayne@69: const XML_Char *name, jpayne@69: const XML_Char **atts); jpayne@69: jpayne@69: typedef void(XMLCALL *XML_EndElementHandler)(void *userData, jpayne@69: const XML_Char *name); jpayne@69: jpayne@69: /* s is not 0 terminated. */ jpayne@69: typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData, jpayne@69: const XML_Char *s, int len); jpayne@69: jpayne@69: /* target and data are 0 terminated */ jpayne@69: typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, jpayne@69: const XML_Char *target, jpayne@69: const XML_Char *data); jpayne@69: jpayne@69: /* data is 0 terminated */ jpayne@69: typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data); jpayne@69: jpayne@69: typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData); jpayne@69: typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData); jpayne@69: jpayne@69: /* This is called for any characters in the XML document for which jpayne@69: there is no applicable handler. This includes both characters that jpayne@69: are part of markup which is of a kind that is not reported jpayne@69: (comments, markup declarations), or characters that are part of a jpayne@69: construct which could be reported but for which no handler has been jpayne@69: supplied. The characters are passed exactly as they were in the XML jpayne@69: document except that they will be encoded in UTF-8 or UTF-16. jpayne@69: Line boundaries are not normalized. Note that a byte order mark jpayne@69: character is not passed to the default handler. There are no jpayne@69: guarantees about how characters are divided between calls to the jpayne@69: default handler: for example, a comment might be split between jpayne@69: multiple calls. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s, jpayne@69: int len); jpayne@69: jpayne@69: /* This is called for the start of the DOCTYPE declaration, before jpayne@69: any DTD or internal subset is parsed. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, jpayne@69: const XML_Char *doctypeName, jpayne@69: const XML_Char *sysid, jpayne@69: const XML_Char *pubid, jpayne@69: int has_internal_subset); jpayne@69: jpayne@69: /* This is called for the end of the DOCTYPE declaration when the jpayne@69: closing > is encountered, but after processing any external jpayne@69: subset. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); jpayne@69: jpayne@69: /* This is called for entity declarations. The is_parameter_entity jpayne@69: argument will be non-zero if the entity is a parameter entity, zero jpayne@69: otherwise. jpayne@69: jpayne@69: For internal entities (), value will jpayne@69: be non-NULL and systemId, publicID, and notationName will be NULL. jpayne@69: The value string is NOT null-terminated; the length is provided in jpayne@69: the value_length argument. Since it is legal to have zero-length jpayne@69: values, do not use this argument to test for internal entities. jpayne@69: jpayne@69: For external entities, value will be NULL and systemId will be jpayne@69: non-NULL. The publicId argument will be NULL unless a public jpayne@69: identifier was provided. The notationName argument will have a jpayne@69: non-NULL value only for unparsed entity declarations. jpayne@69: jpayne@69: Note that is_parameter_entity can't be changed to XML_Bool, since jpayne@69: that would break binary compatibility. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_EntityDeclHandler)( jpayne@69: void *userData, const XML_Char *entityName, int is_parameter_entity, jpayne@69: const XML_Char *value, int value_length, const XML_Char *base, jpayne@69: const XML_Char *systemId, const XML_Char *publicId, jpayne@69: const XML_Char *notationName); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); jpayne@69: jpayne@69: /* OBSOLETE -- OBSOLETE -- OBSOLETE jpayne@69: This handler has been superseded by the EntityDeclHandler above. jpayne@69: It is provided here for backward compatibility. jpayne@69: jpayne@69: This is called for a declaration of an unparsed (NDATA) entity. jpayne@69: The base argument is whatever was set by XML_SetBase. The jpayne@69: entityName, systemId and notationName arguments will never be jpayne@69: NULL. The other arguments may be. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)( jpayne@69: void *userData, const XML_Char *entityName, const XML_Char *base, jpayne@69: const XML_Char *systemId, const XML_Char *publicId, jpayne@69: const XML_Char *notationName); jpayne@69: jpayne@69: /* This is called for a declaration of notation. The base argument is jpayne@69: whatever was set by XML_SetBase. The notationName will never be jpayne@69: NULL. The other arguments can be. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData, jpayne@69: const XML_Char *notationName, jpayne@69: const XML_Char *base, jpayne@69: const XML_Char *systemId, jpayne@69: const XML_Char *publicId); jpayne@69: jpayne@69: /* When namespace processing is enabled, these are called once for jpayne@69: each namespace declaration. The call to the start and end element jpayne@69: handlers occur between the calls to the start and end namespace jpayne@69: declaration handlers. For an xmlns attribute, prefix will be jpayne@69: NULL. For an xmlns="" attribute, uri will be NULL. jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, jpayne@69: const XML_Char *prefix, jpayne@69: const XML_Char *uri); jpayne@69: jpayne@69: typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, jpayne@69: const XML_Char *prefix); jpayne@69: jpayne@69: /* This is called if the document is not standalone, that is, it has an jpayne@69: external subset or a reference to a parameter entity, but does not jpayne@69: have standalone="yes". If this handler returns XML_STATUS_ERROR, jpayne@69: then processing will not continue, and the parser will return a jpayne@69: XML_ERROR_NOT_STANDALONE error. jpayne@69: If parameter entity parsing is enabled, then in addition to the jpayne@69: conditions above this handler will only be called if the referenced jpayne@69: entity was actually read. jpayne@69: */ jpayne@69: typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData); jpayne@69: jpayne@69: /* This is called for a reference to an external parsed general jpayne@69: entity. The referenced entity is not automatically parsed. The jpayne@69: application can parse it immediately or later using jpayne@69: XML_ExternalEntityParserCreate. jpayne@69: jpayne@69: The parser argument is the parser parsing the entity containing the jpayne@69: reference; it can be passed as the parser argument to jpayne@69: XML_ExternalEntityParserCreate. The systemId argument is the jpayne@69: system identifier as specified in the entity declaration; it will jpayne@69: not be NULL. jpayne@69: jpayne@69: The base argument is the system identifier that should be used as jpayne@69: the base for resolving systemId if systemId was relative; this is jpayne@69: set by XML_SetBase; it may be NULL. jpayne@69: jpayne@69: The publicId argument is the public identifier as specified in the jpayne@69: entity declaration, or NULL if none was specified; the whitespace jpayne@69: in the public identifier will have been normalized as required by jpayne@69: the XML spec. jpayne@69: jpayne@69: The context argument specifies the parsing context in the format jpayne@69: expected by the context argument to XML_ExternalEntityParserCreate; jpayne@69: context is valid only until the handler returns, so if the jpayne@69: referenced entity is to be parsed later, it must be copied. jpayne@69: context is NULL only when the entity is a parameter entity. jpayne@69: jpayne@69: The handler should return XML_STATUS_ERROR if processing should not jpayne@69: continue because of a fatal error in the handling of the external jpayne@69: entity. In this case the calling parser will return an jpayne@69: XML_ERROR_EXTERNAL_ENTITY_HANDLING error. jpayne@69: jpayne@69: Note that unlike other handlers the first argument is the parser, jpayne@69: not userData. jpayne@69: */ jpayne@69: typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser, jpayne@69: const XML_Char *context, jpayne@69: const XML_Char *base, jpayne@69: const XML_Char *systemId, jpayne@69: const XML_Char *publicId); jpayne@69: jpayne@69: /* This is called in two situations: jpayne@69: 1) An entity reference is encountered for which no declaration jpayne@69: has been read *and* this is not an error. jpayne@69: 2) An internal entity reference is read, but not expanded, because jpayne@69: XML_SetDefaultHandler has been called. jpayne@69: Note: skipped parameter entities in declarations and skipped general jpayne@69: entities in attribute values cannot be reported, because jpayne@69: the event would be out of sync with the reporting of the jpayne@69: declarations or attribute values jpayne@69: */ jpayne@69: typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData, jpayne@69: const XML_Char *entityName, jpayne@69: int is_parameter_entity); jpayne@69: jpayne@69: /* This structure is filled in by the XML_UnknownEncodingHandler to jpayne@69: provide information to the parser about encodings that are unknown jpayne@69: to the parser. jpayne@69: jpayne@69: The map[b] member gives information about byte sequences whose jpayne@69: first byte is b. jpayne@69: jpayne@69: If map[b] is c where c is >= 0, then b by itself encodes the jpayne@69: Unicode scalar value c. jpayne@69: jpayne@69: If map[b] is -1, then the byte sequence is malformed. jpayne@69: jpayne@69: If map[b] is -n, where n >= 2, then b is the first byte of an jpayne@69: n-byte sequence that encodes a single Unicode scalar value. jpayne@69: jpayne@69: The data member will be passed as the first argument to the convert jpayne@69: function. jpayne@69: jpayne@69: The convert function is used to convert multibyte sequences; s will jpayne@69: point to a n-byte sequence where map[(unsigned char)*s] == -n. The jpayne@69: convert function must return the Unicode scalar value represented jpayne@69: by this byte sequence or -1 if the byte sequence is malformed. jpayne@69: jpayne@69: The convert function may be NULL if the encoding is a single-byte jpayne@69: encoding, that is if map[b] >= -1 for all bytes b. jpayne@69: jpayne@69: When the parser is finished with the encoding, then if release is jpayne@69: not NULL, it will call release passing it the data member; once jpayne@69: release has been called, the convert function will not be called jpayne@69: again. jpayne@69: jpayne@69: Expat places certain restrictions on the encodings that are supported jpayne@69: using this mechanism. jpayne@69: jpayne@69: 1. Every ASCII character that can appear in a well-formed XML document, jpayne@69: other than the characters jpayne@69: jpayne@69: $@\^`{}~ jpayne@69: jpayne@69: must be represented by a single byte, and that byte must be the jpayne@69: same byte that represents that character in ASCII. jpayne@69: jpayne@69: 2. No character may require more than 4 bytes to encode. jpayne@69: jpayne@69: 3. All characters encoded must have Unicode scalar values <= jpayne@69: 0xFFFF, (i.e., characters that would be encoded by surrogates in jpayne@69: UTF-16 are not allowed). Note that this restriction doesn't jpayne@69: apply to the built-in support for UTF-8 and UTF-16. jpayne@69: jpayne@69: 4. No Unicode character may be encoded by more than one distinct jpayne@69: sequence of bytes. jpayne@69: */ jpayne@69: typedef struct { jpayne@69: int map[256]; jpayne@69: void *data; jpayne@69: int(XMLCALL *convert)(void *data, const char *s); jpayne@69: void(XMLCALL *release)(void *data); jpayne@69: } XML_Encoding; jpayne@69: jpayne@69: /* This is called for an encoding that is unknown to the parser. jpayne@69: jpayne@69: The encodingHandlerData argument is that which was passed as the jpayne@69: second argument to XML_SetUnknownEncodingHandler. jpayne@69: jpayne@69: The name argument gives the name of the encoding as specified in jpayne@69: the encoding declaration. jpayne@69: jpayne@69: If the callback can provide information about the encoding, it must jpayne@69: fill in the XML_Encoding structure, and return XML_STATUS_OK. jpayne@69: Otherwise it must return XML_STATUS_ERROR. jpayne@69: jpayne@69: If info does not describe a suitable encoding, then the parser will jpayne@69: return an XML_ERROR_UNKNOWN_ENCODING error. jpayne@69: */ jpayne@69: typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, jpayne@69: const XML_Char *name, jpayne@69: XML_Encoding *info); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, jpayne@69: XML_EndElementHandler end); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetCharacterDataHandler(XML_Parser parser, jpayne@69: XML_CharacterDataHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetProcessingInstructionHandler(XML_Parser parser, jpayne@69: XML_ProcessingInstructionHandler handler); jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetCdataSectionHandler(XML_Parser parser, jpayne@69: XML_StartCdataSectionHandler start, jpayne@69: XML_EndCdataSectionHandler end); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetStartCdataSectionHandler(XML_Parser parser, jpayne@69: XML_StartCdataSectionHandler start); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetEndCdataSectionHandler(XML_Parser parser, jpayne@69: XML_EndCdataSectionHandler end); jpayne@69: jpayne@69: /* This sets the default handler and also inhibits expansion of jpayne@69: internal entities. These entity references will be passed to the jpayne@69: default handler, or to the skipped entity handler, if one is set. jpayne@69: */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); jpayne@69: jpayne@69: /* This sets the default handler but does not inhibit expansion of jpayne@69: internal entities. The entity reference will not be passed to the jpayne@69: default handler. jpayne@69: */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, jpayne@69: XML_EndDoctypeDeclHandler end); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetStartDoctypeDeclHandler(XML_Parser parser, jpayne@69: XML_StartDoctypeDeclHandler start); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetUnparsedEntityDeclHandler(XML_Parser parser, jpayne@69: XML_UnparsedEntityDeclHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetNamespaceDeclHandler(XML_Parser parser, jpayne@69: XML_StartNamespaceDeclHandler start, jpayne@69: XML_EndNamespaceDeclHandler end); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetStartNamespaceDeclHandler(XML_Parser parser, jpayne@69: XML_StartNamespaceDeclHandler start); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetEndNamespaceDeclHandler(XML_Parser parser, jpayne@69: XML_EndNamespaceDeclHandler end); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetNotStandaloneHandler(XML_Parser parser, jpayne@69: XML_NotStandaloneHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetExternalEntityRefHandler(XML_Parser parser, jpayne@69: XML_ExternalEntityRefHandler handler); jpayne@69: jpayne@69: /* If a non-NULL value for arg is specified here, then it will be jpayne@69: passed as the first argument to the external entity ref handler jpayne@69: instead of the parser object. jpayne@69: */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetSkippedEntityHandler(XML_Parser parser, jpayne@69: XML_SkippedEntityHandler handler); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetUnknownEncodingHandler(XML_Parser parser, jpayne@69: XML_UnknownEncodingHandler handler, jpayne@69: void *encodingHandlerData); jpayne@69: jpayne@69: /* This can be called within a handler for a start element, end jpayne@69: element, processing instruction or character data. It causes the jpayne@69: corresponding markup to be passed to the default handler. jpayne@69: */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_DefaultCurrent(XML_Parser parser); jpayne@69: jpayne@69: /* If do_nst is non-zero, and namespace processing is in effect, and jpayne@69: a name has a prefix (i.e. an explicit namespace qualifier) then jpayne@69: that name is returned as a triplet in a single string separated by jpayne@69: the separator character specified when the parser was created: URI jpayne@69: + sep + local_name + sep + prefix. jpayne@69: jpayne@69: If do_nst is zero, then namespace information is returned in the jpayne@69: default manner (URI + sep + local_name) whether or not the name jpayne@69: has a prefix. jpayne@69: jpayne@69: Note: Calling XML_SetReturnNSTriplet after XML_Parse or jpayne@69: XML_ParseBuffer has no effect. jpayne@69: */ jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); jpayne@69: jpayne@69: /* This value is passed as the userData argument to callbacks. */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_SetUserData(XML_Parser parser, void *userData); jpayne@69: jpayne@69: /* Returns the last value set by XML_SetUserData or NULL. */ jpayne@69: #define XML_GetUserData(parser) (*(void **)(parser)) jpayne@69: jpayne@69: /* This is equivalent to supplying an encoding argument to jpayne@69: XML_ParserCreate. On success XML_SetEncoding returns non-zero, jpayne@69: zero otherwise. jpayne@69: Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer jpayne@69: has no effect and returns XML_STATUS_ERROR. jpayne@69: */ jpayne@69: XMLPARSEAPI(enum XML_Status) jpayne@69: XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); jpayne@69: jpayne@69: /* If this function is called, then the parser will be passed as the jpayne@69: first argument to callbacks instead of userData. The userData will jpayne@69: still be accessible using XML_GetUserData. jpayne@69: */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_UseParserAsHandlerArg(XML_Parser parser); jpayne@69: jpayne@69: /* If useDTD == XML_TRUE is passed to this function, then the parser jpayne@69: will assume that there is an external subset, even if none is jpayne@69: specified in the document. In such a case the parser will call the jpayne@69: externalEntityRefHandler with a value of NULL for the systemId jpayne@69: argument (the publicId and context arguments will be NULL as well). jpayne@69: Note: For the purpose of checking WFC: Entity Declared, passing jpayne@69: useDTD == XML_TRUE will make the parser behave as if the document jpayne@69: had a DTD with an external subset. jpayne@69: Note: If this function is called, then this must be done before jpayne@69: the first call to XML_Parse or XML_ParseBuffer, since it will jpayne@69: have no effect after that. Returns jpayne@69: XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. jpayne@69: Note: If the document does not have a DOCTYPE declaration at all, jpayne@69: then startDoctypeDeclHandler and endDoctypeDeclHandler will not jpayne@69: be called, despite an external subset being parsed. jpayne@69: Note: If XML_DTD is not defined when Expat is compiled, returns jpayne@69: XML_ERROR_FEATURE_REQUIRES_XML_DTD. jpayne@69: Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. jpayne@69: */ jpayne@69: XMLPARSEAPI(enum XML_Error) jpayne@69: XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); jpayne@69: jpayne@69: /* Sets the base to be used for resolving relative URIs in system jpayne@69: identifiers in declarations. Resolving relative identifiers is jpayne@69: left to the application: this value will be passed through as the jpayne@69: base argument to the XML_ExternalEntityRefHandler, jpayne@69: XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base jpayne@69: argument will be copied. Returns XML_STATUS_ERROR if out of memory, jpayne@69: XML_STATUS_OK otherwise. jpayne@69: */ jpayne@69: XMLPARSEAPI(enum XML_Status) jpayne@69: XML_SetBase(XML_Parser parser, const XML_Char *base); jpayne@69: jpayne@69: XMLPARSEAPI(const XML_Char *) jpayne@69: XML_GetBase(XML_Parser parser); jpayne@69: jpayne@69: /* Returns the number of the attribute/value pairs passed in last call jpayne@69: to the XML_StartElementHandler that were specified in the start-tag jpayne@69: rather than defaulted. Each attribute/value pair counts as 2; thus jpayne@69: this corresponds to an index into the atts array passed to the jpayne@69: XML_StartElementHandler. Returns -1 if parser == NULL. jpayne@69: */ jpayne@69: XMLPARSEAPI(int) jpayne@69: XML_GetSpecifiedAttributeCount(XML_Parser parser); jpayne@69: jpayne@69: /* Returns the index of the ID attribute passed in the last call to jpayne@69: XML_StartElementHandler, or -1 if there is no ID attribute or jpayne@69: parser == NULL. Each attribute/value pair counts as 2; thus this jpayne@69: corresponds to an index into the atts array passed to the jpayne@69: XML_StartElementHandler. jpayne@69: */ jpayne@69: XMLPARSEAPI(int) jpayne@69: XML_GetIdAttributeIndex(XML_Parser parser); jpayne@69: jpayne@69: #ifdef XML_ATTR_INFO jpayne@69: /* Source file byte offsets for the start and end of attribute names and values. jpayne@69: The value indices are exclusive of surrounding quotes; thus in a UTF-8 source jpayne@69: file an attribute value of "blah" will yield: jpayne@69: info->valueEnd - info->valueStart = 4 bytes. jpayne@69: */ jpayne@69: typedef struct { jpayne@69: XML_Index nameStart; /* Offset to beginning of the attribute name. */ jpayne@69: XML_Index nameEnd; /* Offset after the attribute name's last byte. */ jpayne@69: XML_Index valueStart; /* Offset to beginning of the attribute value. */ jpayne@69: XML_Index valueEnd; /* Offset after the attribute value's last byte. */ jpayne@69: } XML_AttrInfo; jpayne@69: jpayne@69: /* Returns an array of XML_AttrInfo structures for the attribute/value pairs jpayne@69: passed in last call to the XML_StartElementHandler that were specified jpayne@69: in the start-tag rather than defaulted. Each attribute/value pair counts jpayne@69: as 1; thus the number of entries in the array is jpayne@69: XML_GetSpecifiedAttributeCount(parser) / 2. jpayne@69: */ jpayne@69: XMLPARSEAPI(const XML_AttrInfo *) jpayne@69: XML_GetAttributeInfo(XML_Parser parser); jpayne@69: #endif jpayne@69: jpayne@69: /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is jpayne@69: detected. The last call to XML_Parse must have isFinal true; len jpayne@69: may be zero for this call (or any other). jpayne@69: jpayne@69: Though the return values for these functions has always been jpayne@69: described as a Boolean value, the implementation, at least for the jpayne@69: 1.95.x series, has always returned exactly one of the XML_Status jpayne@69: values. jpayne@69: */ jpayne@69: XMLPARSEAPI(enum XML_Status) jpayne@69: XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); jpayne@69: jpayne@69: XMLPARSEAPI(void *) jpayne@69: XML_GetBuffer(XML_Parser parser, int len); jpayne@69: jpayne@69: XMLPARSEAPI(enum XML_Status) jpayne@69: XML_ParseBuffer(XML_Parser parser, int len, int isFinal); jpayne@69: jpayne@69: /* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. jpayne@69: Must be called from within a call-back handler, except when aborting jpayne@69: (resumable = 0) an already suspended parser. Some call-backs may jpayne@69: still follow because they would otherwise get lost. Examples: jpayne@69: - endElementHandler() for empty elements when stopped in jpayne@69: startElementHandler(), jpayne@69: - endNameSpaceDeclHandler() when stopped in endElementHandler(), jpayne@69: and possibly others. jpayne@69: jpayne@69: Can be called from most handlers, including DTD related call-backs, jpayne@69: except when parsing an external parameter entity and resumable != 0. jpayne@69: Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. jpayne@69: Possible error codes: jpayne@69: - XML_ERROR_SUSPENDED: when suspending an already suspended parser. jpayne@69: - XML_ERROR_FINISHED: when the parser has already finished. jpayne@69: - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. jpayne@69: jpayne@69: When resumable != 0 (true) then parsing is suspended, that is, jpayne@69: XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. jpayne@69: Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() jpayne@69: return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. jpayne@69: jpayne@69: *Note*: jpayne@69: This will be applied to the current parser instance only, that is, if jpayne@69: there is a parent parser then it will continue parsing when the jpayne@69: externalEntityRefHandler() returns. It is up to the implementation of jpayne@69: the externalEntityRefHandler() to call XML_StopParser() on the parent jpayne@69: parser (recursively), if one wants to stop parsing altogether. jpayne@69: jpayne@69: When suspended, parsing can be resumed by calling XML_ResumeParser(). jpayne@69: */ jpayne@69: XMLPARSEAPI(enum XML_Status) jpayne@69: XML_StopParser(XML_Parser parser, XML_Bool resumable); jpayne@69: jpayne@69: /* Resumes parsing after it has been suspended with XML_StopParser(). jpayne@69: Must not be called from within a handler call-back. Returns same jpayne@69: status codes as XML_Parse() or XML_ParseBuffer(). jpayne@69: Additional error code XML_ERROR_NOT_SUSPENDED possible. jpayne@69: jpayne@69: *Note*: jpayne@69: This must be called on the most deeply nested child parser instance jpayne@69: first, and on its parent parser only after the child parser has finished, jpayne@69: to be applied recursively until the document entity's parser is restarted. jpayne@69: That is, the parent parser will not resume by itself and it is up to the jpayne@69: application to call XML_ResumeParser() on it at the appropriate moment. jpayne@69: */ jpayne@69: XMLPARSEAPI(enum XML_Status) jpayne@69: XML_ResumeParser(XML_Parser parser); jpayne@69: jpayne@69: enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED }; jpayne@69: jpayne@69: typedef struct { jpayne@69: enum XML_Parsing parsing; jpayne@69: XML_Bool finalBuffer; jpayne@69: } XML_ParsingStatus; jpayne@69: jpayne@69: /* Returns status of parser with respect to being initialized, parsing, jpayne@69: finished, or suspended and processing the final buffer. jpayne@69: XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, jpayne@69: XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED jpayne@69: */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); jpayne@69: jpayne@69: /* Creates an XML_Parser object that can parse an external general jpayne@69: entity; context is a '\0'-terminated string specifying the parse jpayne@69: context; encoding is a '\0'-terminated string giving the name of jpayne@69: the externally specified encoding, or NULL if there is no jpayne@69: externally specified encoding. The context string consists of a jpayne@69: sequence of tokens separated by formfeeds (\f); a token consisting jpayne@69: of a name specifies that the general entity of the name is open; a jpayne@69: token of the form prefix=uri specifies the namespace for a jpayne@69: particular prefix; a token of the form =uri specifies the default jpayne@69: namespace. This can be called at any point after the first call to jpayne@69: an ExternalEntityRefHandler so longer as the parser has not yet jpayne@69: been freed. The new parser is completely independent and may jpayne@69: safely be used in a separate thread. The handlers and userData are jpayne@69: initialized from the parser argument. Returns NULL if out of memory. jpayne@69: Otherwise returns a new XML_Parser object. jpayne@69: */ jpayne@69: XMLPARSEAPI(XML_Parser) jpayne@69: XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, jpayne@69: const XML_Char *encoding); jpayne@69: jpayne@69: enum XML_ParamEntityParsing { jpayne@69: XML_PARAM_ENTITY_PARSING_NEVER, jpayne@69: XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, jpayne@69: XML_PARAM_ENTITY_PARSING_ALWAYS jpayne@69: }; jpayne@69: jpayne@69: /* Controls parsing of parameter entities (including the external DTD jpayne@69: subset). If parsing of parameter entities is enabled, then jpayne@69: references to external parameter entities (including the external jpayne@69: DTD subset) will be passed to the handler set with jpayne@69: XML_SetExternalEntityRefHandler. The context passed will be 0. jpayne@69: jpayne@69: Unlike external general entities, external parameter entities can jpayne@69: only be parsed synchronously. If the external parameter entity is jpayne@69: to be parsed, it must be parsed during the call to the external jpayne@69: entity ref handler: the complete sequence of jpayne@69: XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and jpayne@69: XML_ParserFree calls must be made during this call. After jpayne@69: XML_ExternalEntityParserCreate has been called to create the parser jpayne@69: for the external parameter entity (context must be 0 for this jpayne@69: call), it is illegal to make any calls on the old parser until jpayne@69: XML_ParserFree has been called on the newly created parser. jpayne@69: If the library has been compiled without support for parameter jpayne@69: entity parsing (ie without XML_DTD being defined), then jpayne@69: XML_SetParamEntityParsing will return 0 if parsing of parameter jpayne@69: entities is requested; otherwise it will return non-zero. jpayne@69: Note: If XML_SetParamEntityParsing is called after XML_Parse or jpayne@69: XML_ParseBuffer, then it has no effect and will always return 0. jpayne@69: Note: If parser == NULL, the function will do nothing and return 0. jpayne@69: */ jpayne@69: XMLPARSEAPI(int) jpayne@69: XML_SetParamEntityParsing(XML_Parser parser, jpayne@69: enum XML_ParamEntityParsing parsing); jpayne@69: jpayne@69: /* Sets the hash salt to use for internal hash calculations. jpayne@69: Helps in preventing DoS attacks based on predicting hash jpayne@69: function behavior. This must be called before parsing is started. jpayne@69: Returns 1 if successful, 0 when called after parsing has started. jpayne@69: Note: If parser == NULL, the function will do nothing and return 0. jpayne@69: */ jpayne@69: XMLPARSEAPI(int) jpayne@69: XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); jpayne@69: jpayne@69: /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then jpayne@69: XML_GetErrorCode returns information about the error. jpayne@69: */ jpayne@69: XMLPARSEAPI(enum XML_Error) jpayne@69: XML_GetErrorCode(XML_Parser parser); jpayne@69: jpayne@69: /* These functions return information about the current parse jpayne@69: location. They may be called from any callback called to report jpayne@69: some parse event; in this case the location is the location of the jpayne@69: first of the sequence of characters that generated the event. When jpayne@69: called from callbacks generated by declarations in the document jpayne@69: prologue, the location identified isn't as neatly defined, but will jpayne@69: be within the relevant markup. When called outside of the callback jpayne@69: functions, the position indicated will be just past the last parse jpayne@69: event (regardless of whether there was an associated callback). jpayne@69: jpayne@69: They may also be called after returning from a call to XML_Parse jpayne@69: or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then jpayne@69: the location is the location of the character at which the error jpayne@69: was detected; otherwise the location is the location of the last jpayne@69: parse event, as described above. jpayne@69: jpayne@69: Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber jpayne@69: return 0 to indicate an error. jpayne@69: Note: XML_GetCurrentByteIndex returns -1 to indicate an error. jpayne@69: */ jpayne@69: XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); jpayne@69: XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); jpayne@69: XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); jpayne@69: jpayne@69: /* Return the number of bytes in the current event. jpayne@69: Returns 0 if the event is in an internal entity. jpayne@69: */ jpayne@69: XMLPARSEAPI(int) jpayne@69: XML_GetCurrentByteCount(XML_Parser parser); jpayne@69: jpayne@69: /* If XML_CONTEXT_BYTES is >=1, returns the input buffer, sets jpayne@69: the integer pointed to by offset to the offset within this buffer jpayne@69: of the current parse position, and sets the integer pointed to by size jpayne@69: to the size of this buffer (the number of input bytes). Otherwise jpayne@69: returns a NULL pointer. Also returns a NULL pointer if a parse isn't jpayne@69: active. jpayne@69: jpayne@69: NOTE: The character pointer returned should not be used outside jpayne@69: the handler that makes the call. jpayne@69: */ jpayne@69: XMLPARSEAPI(const char *) jpayne@69: XML_GetInputContext(XML_Parser parser, int *offset, int *size); jpayne@69: jpayne@69: /* For backwards compatibility with previous versions. */ jpayne@69: #define XML_GetErrorLineNumber XML_GetCurrentLineNumber jpayne@69: #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber jpayne@69: #define XML_GetErrorByteIndex XML_GetCurrentByteIndex jpayne@69: jpayne@69: /* Frees the content model passed to the element declaration handler */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_FreeContentModel(XML_Parser parser, XML_Content *model); jpayne@69: jpayne@69: /* Exposing the memory handling functions used in Expat */ jpayne@69: XMLPARSEAPI(void *) jpayne@69: XML_ATTR_MALLOC jpayne@69: XML_ATTR_ALLOC_SIZE(2) jpayne@69: XML_MemMalloc(XML_Parser parser, size_t size); jpayne@69: jpayne@69: XMLPARSEAPI(void *) jpayne@69: XML_ATTR_ALLOC_SIZE(3) jpayne@69: XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); jpayne@69: jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_MemFree(XML_Parser parser, void *ptr); jpayne@69: jpayne@69: /* Frees memory used by the parser. */ jpayne@69: XMLPARSEAPI(void) jpayne@69: XML_ParserFree(XML_Parser parser); jpayne@69: jpayne@69: /* Returns a string describing the error. */ jpayne@69: XMLPARSEAPI(const XML_LChar *) jpayne@69: XML_ErrorString(enum XML_Error code); jpayne@69: jpayne@69: /* Return a string containing the version number of this expat */ jpayne@69: XMLPARSEAPI(const XML_LChar *) jpayne@69: XML_ExpatVersion(void); jpayne@69: jpayne@69: typedef struct { jpayne@69: int major; jpayne@69: int minor; jpayne@69: int micro; jpayne@69: } XML_Expat_Version; jpayne@69: jpayne@69: /* Return an XML_Expat_Version structure containing numeric version jpayne@69: number information for this version of expat. jpayne@69: */ jpayne@69: XMLPARSEAPI(XML_Expat_Version) jpayne@69: XML_ExpatVersionInfo(void); jpayne@69: jpayne@69: /* Added in Expat 1.95.5. */ jpayne@69: enum XML_FeatureEnum { jpayne@69: XML_FEATURE_END = 0, jpayne@69: XML_FEATURE_UNICODE, jpayne@69: XML_FEATURE_UNICODE_WCHAR_T, jpayne@69: XML_FEATURE_DTD, jpayne@69: XML_FEATURE_CONTEXT_BYTES, jpayne@69: XML_FEATURE_MIN_SIZE, jpayne@69: XML_FEATURE_SIZEOF_XML_CHAR, jpayne@69: XML_FEATURE_SIZEOF_XML_LCHAR, jpayne@69: XML_FEATURE_NS, jpayne@69: XML_FEATURE_LARGE_SIZE, jpayne@69: XML_FEATURE_ATTR_INFO, jpayne@69: /* Added in Expat 2.4.0. */ jpayne@69: XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, jpayne@69: XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, jpayne@69: /* Added in Expat 2.6.0. */ jpayne@69: XML_FEATURE_GE jpayne@69: /* Additional features must be added to the end of this enum. */ jpayne@69: }; jpayne@69: jpayne@69: typedef struct { jpayne@69: enum XML_FeatureEnum feature; jpayne@69: const XML_LChar *name; jpayne@69: long int value; jpayne@69: } XML_Feature; jpayne@69: jpayne@69: XMLPARSEAPI(const XML_Feature *) jpayne@69: XML_GetFeatureList(void); jpayne@69: jpayne@69: #if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1) jpayne@69: /* Added in Expat 2.4.0 for XML_DTD defined and jpayne@69: * added in Expat 2.6.0 for XML_GE == 1. */ jpayne@69: XMLPARSEAPI(XML_Bool) jpayne@69: XML_SetBillionLaughsAttackProtectionMaximumAmplification( jpayne@69: XML_Parser parser, float maximumAmplificationFactor); jpayne@69: jpayne@69: /* Added in Expat 2.4.0 for XML_DTD defined and jpayne@69: * added in Expat 2.6.0 for XML_GE == 1. */ jpayne@69: XMLPARSEAPI(XML_Bool) jpayne@69: XML_SetBillionLaughsAttackProtectionActivationThreshold( jpayne@69: XML_Parser parser, unsigned long long activationThresholdBytes); jpayne@69: #endif jpayne@69: jpayne@69: /* Added in Expat 2.6.0. */ jpayne@69: XMLPARSEAPI(XML_Bool) jpayne@69: XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); jpayne@69: jpayne@69: /* Expat follows the semantic versioning convention. jpayne@69: See https://semver.org jpayne@69: */ jpayne@69: #define XML_MAJOR_VERSION 2 jpayne@69: #define XML_MINOR_VERSION 6 jpayne@69: #define XML_MICRO_VERSION 4 jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: } jpayne@69: #endif jpayne@69: jpayne@69: #endif /* not Expat_INCLUDED */