2003-08-21 02:54:39 +04:00
/*
* SAX2 . c : Default SAX2 handler to build a tree .
*
* See Copyright for the status of this software .
*
* Daniel Veillard < daniel @ veillard . com >
*/
# define IN_LIBXML
# include "libxml.h"
# include <stdlib.h>
# include <string.h>
2008-11-17 18:59:21 +03:00
# include <limits.h>
2017-10-09 14:37:42 +03:00
# include <stddef.h>
2023-09-20 17:57:22 +03:00
# include <libxml/SAX2.h>
2003-08-21 02:54:39 +04:00
# include <libxml/xmlmemory.h>
# include <libxml/tree.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/valid.h>
# include <libxml/entities.h>
# include <libxml/xmlerror.h>
# include <libxml/debugXML.h>
# include <libxml/xmlIO.h>
# include <libxml/uri.h>
# include <libxml/valid.h>
# include <libxml/HTMLtree.h>
2022-08-26 02:22:33 +03:00
# include "private/error.h"
# include "private/parser.h"
# include "private/tree.h"
2024-01-07 22:44:40 +03:00
# define XML_MAX_URI_LENGTH 2000
2004-07-29 11:07:16 +04:00
/*
* xmlSAX2ErrMemory :
* @ ctxt : an XML validation parser context
* @ msg : a string to accompany the error message
*/
2023-12-18 21:31:29 +03:00
static void
xmlSAX2ErrMemory ( xmlParserCtxtPtr ctxt ) {
xmlCtxtErrMemory ( ctxt ) ;
2004-07-29 11:07:16 +04:00
}
2003-12-08 13:25:02 +03:00
/**
* xmlValidError :
* @ ctxt : an XML validation parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : extra data
* @ str2 : extra data
*
* Handle a validation error
*/
2016-05-13 10:13:17 +03:00
static void LIBXML_ATTR_FORMAT ( 3 , 0 )
2003-12-08 13:25:02 +03:00
xmlErrValid ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
2023-12-10 20:10:42 +03:00
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
2003-12-08 13:25:02 +03:00
{
2023-12-20 02:33:34 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_DTD , error , XML_ERR_ERROR ,
str1 , str2 , NULL , 0 , msg , str1 , str2 ) ;
2023-12-10 20:10:42 +03:00
if ( ctxt ! = NULL )
2004-11-04 20:34:35 +03:00
ctxt - > valid = 0 ;
2003-12-08 13:25:02 +03:00
}
2005-07-05 18:04:36 +04:00
/**
* xmlFatalErrMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
* @ str2 : an error string
*
* Handle a fatal parser error , i . e . violating Well - Formedness constraints
*/
2016-05-13 10:13:17 +03:00
static void LIBXML_ATTR_FORMAT ( 3 , 0 )
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
2023-12-20 02:33:34 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_PARSER , error , XML_ERR_FATAL ,
str1 , str2 , NULL , 0 , msg , str1 , str2 ) ;
2005-07-05 18:04:36 +04:00
}
/**
* xmlWarnMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
* @ str2 : an error string
*
* Handle a parser warning
*/
2016-05-13 10:13:17 +03:00
static void LIBXML_ATTR_FORMAT ( 3 , 0 )
2005-07-05 18:04:36 +04:00
xmlWarnMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 )
{
2023-12-20 02:33:34 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_PARSER , error , XML_ERR_WARNING ,
str1 , NULL , NULL , 0 , msg , str1 ) ;
2005-07-05 18:04:36 +04:00
}
/**
* xmlNsWarnMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
*
* Handle a namespace warning
*/
2016-05-13 10:13:17 +03:00
static void LIBXML_ATTR_FORMAT ( 3 , 0 )
2005-07-05 18:04:36 +04:00
xmlNsWarnMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
2023-12-20 02:33:34 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_NAMESPACE , error , XML_ERR_WARNING ,
str1 , str2 , NULL , 0 , msg , str1 , str2 ) ;
2005-07-05 18:04:36 +04:00
}
2003-08-21 02:54:39 +04:00
/**
* xmlSAX2GetPublicId :
* @ ctx : the user data ( XML parser context )
*
* Provides the public ID e . g . " -//SGMLSOURCE//DTD DEMO//EN "
*
* Returns a xmlChar *
*/
const xmlChar *
xmlSAX2GetPublicId ( void * ctx ATTRIBUTE_UNUSED )
{
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
return ( NULL ) ;
}
/**
* xmlSAX2GetSystemId :
* @ ctx : the user data ( XML parser context )
*
* Provides the system ID , basically URL or filename e . g .
* http : //www.sgmlsource.com/dtds/memo.dtd
*
* Returns a xmlChar *
*/
const xmlChar *
xmlSAX2GetSystemId ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2005-07-29 03:49:35 +04:00
if ( ( ctx = = NULL ) | | ( ctxt - > input = = NULL ) ) return ( NULL ) ;
2012-09-11 09:26:36 +04:00
return ( ( const xmlChar * ) ctxt - > input - > filename ) ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2GetLineNumber :
* @ ctx : the user data ( XML parser context )
*
* Provide the line number of the current parsing point .
*
* Returns an int
*/
int
xmlSAX2GetLineNumber ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ( ctx = = NULL ) | | ( ctxt - > input = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > input - > line ) ;
}
/**
* xmlSAX2GetColumnNumber :
* @ ctx : the user data ( XML parser context )
*
* Provide the column number of the current parsing point .
*
* Returns an int
*/
int
xmlSAX2GetColumnNumber ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ( ctx = = NULL ) | | ( ctxt - > input = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > input - > col ) ;
}
/**
* xmlSAX2IsStandalone :
* @ ctx : the user data ( XML parser context )
*
* Is this document tagged standalone ?
*
* Returns 1 if true
*/
int
xmlSAX2IsStandalone ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ( ctx = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > myDoc - > standalone = = 1 ) ;
}
/**
* xmlSAX2HasInternalSubset :
* @ ctx : the user data ( XML parser context )
*
* Does this document has an internal subset
*
* Returns 1 if true
*/
int
xmlSAX2HasInternalSubset ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-08 17:02:18 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > myDoc - > intSubset ! = NULL ) ;
}
/**
* xmlSAX2HasExternalSubset :
* @ ctx : the user data ( XML parser context )
*
* Does this document has an external subset
*
* Returns 1 if true
*/
int
xmlSAX2HasExternalSubset ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-08 17:02:18 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > myDoc - > extSubset ! = NULL ) ;
}
/**
* xmlSAX2InternalSubset :
* @ ctx : the user data ( XML parser context )
* @ name : the root element name
* @ ExternalID : the external ID
* @ SystemID : the SYSTEM ID ( e . g . filename or URL )
*
* Callback on internal subset declaration .
*/
void
xmlSAX2InternalSubset ( void * ctx , const xmlChar * name ,
const xmlChar * ExternalID , const xmlChar * SystemID )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlDtdPtr dtd ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > myDoc = = NULL )
return ;
dtd = xmlGetIntSubset ( ctxt - > myDoc ) ;
if ( dtd ! = NULL ) {
if ( ctxt - > html )
return ;
xmlUnlinkNode ( ( xmlNodePtr ) dtd ) ;
xmlFreeDtd ( dtd ) ;
ctxt - > myDoc - > intSubset = NULL ;
}
2012-09-11 09:26:36 +04:00
ctxt - > myDoc - > intSubset =
2003-08-21 02:54:39 +04:00
xmlCreateIntSubset ( ctxt - > myDoc , name , ExternalID , SystemID ) ;
2004-07-29 11:07:16 +04:00
if ( ctxt - > myDoc - > intSubset = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2ExternalSubset :
* @ ctx : the user data ( XML parser context )
* @ name : the root element name
* @ ExternalID : the external ID
* @ SystemID : the SYSTEM ID ( e . g . filename or URL )
*
* Callback on external subset declaration .
*/
void
xmlSAX2ExternalSubset ( void * ctx , const xmlChar * name ,
const xmlChar * ExternalID , const xmlChar * SystemID )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2024-01-05 06:17:14 +03:00
if ( ( SystemID ! = NULL ) & &
( ( ctxt - > options & XML_PARSE_NO_XXE ) = = 0 ) & &
( ( ( ctxt - > validate ) | | ( ctxt - > loadsubset ) ) & &
2003-08-21 02:54:39 +04:00
( ctxt - > wellFormed & & ctxt - > myDoc ) ) ) {
/*
* Try to fetch and parse the external subset .
*/
xmlParserInputPtr oldinput ;
int oldinputNr ;
int oldinputMax ;
xmlParserInputPtr * oldinputTab ;
xmlParserInputPtr input = NULL ;
2013-03-27 09:21:38 +04:00
const xmlChar * oldencoding ;
2022-12-19 20:39:45 +03:00
unsigned long consumed ;
size_t buffered ;
2003-08-21 02:54:39 +04:00
/*
* Ask the Entity resolver to load the damn thing
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > resolveEntity ! = NULL ) )
input = ctxt - > sax - > resolveEntity ( ctxt - > userData , ExternalID ,
SystemID ) ;
if ( input = = NULL ) {
return ;
}
2023-12-10 20:10:42 +03:00
if ( xmlNewDtd ( ctxt - > myDoc , name , ExternalID , SystemID ) = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
xmlFreeInputStream ( input ) ;
return ;
}
2003-08-21 02:54:39 +04:00
/*
* make sure we won ' t destroy the main document context
*/
oldinput = ctxt - > input ;
oldinputNr = ctxt - > inputNr ;
oldinputMax = ctxt - > inputMax ;
oldinputTab = ctxt - > inputTab ;
2013-03-27 09:21:38 +04:00
oldencoding = ctxt - > encoding ;
ctxt - > encoding = NULL ;
2003-08-21 02:54:39 +04:00
ctxt - > inputTab = ( xmlParserInputPtr * )
xmlMalloc ( 5 * sizeof ( xmlParserInputPtr ) ) ;
if ( ctxt - > inputTab = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2022-11-02 18:05:05 +03:00
xmlFreeInputStream ( input ) ;
2003-08-21 02:54:39 +04:00
ctxt - > input = oldinput ;
ctxt - > inputNr = oldinputNr ;
ctxt - > inputMax = oldinputMax ;
ctxt - > inputTab = oldinputTab ;
2013-03-27 09:21:38 +04:00
ctxt - > encoding = oldencoding ;
2003-08-21 02:54:39 +04:00
return ;
}
ctxt - > inputNr = 0 ;
ctxt - > inputMax = 5 ;
ctxt - > input = NULL ;
xmlPushInput ( ctxt , input ) ;
if ( input - > filename = = NULL )
input - > filename = ( char * ) xmlCanonicPath ( SystemID ) ;
input - > line = 1 ;
input - > col = 1 ;
input - > base = ctxt - > input - > cur ;
input - > cur = ctxt - > input - > cur ;
input - > free = NULL ;
/*
* let ' s parse that entity knowing it ' s an external subset .
*/
xmlParseExternalSubset ( ctxt , ExternalID , SystemID ) ;
/*
* Free up the external entities
*/
while ( ctxt - > inputNr > 1 )
xmlPopInput ( ctxt ) ;
2022-12-19 20:39:45 +03:00
consumed = ctxt - > input - > consumed ;
buffered = ctxt - > input - > cur - ctxt - > input - > base ;
if ( buffered > ULONG_MAX - consumed )
consumed = ULONG_MAX ;
else
consumed + = buffered ;
if ( consumed > ULONG_MAX - ctxt - > sizeentities )
ctxt - > sizeentities = ULONG_MAX ;
else
ctxt - > sizeentities + = consumed ;
2003-08-21 02:54:39 +04:00
xmlFreeInputStream ( ctxt - > input ) ;
xmlFree ( ctxt - > inputTab ) ;
/*
* Restore the parsing context of the main entity
*/
ctxt - > input = oldinput ;
ctxt - > inputNr = oldinputNr ;
ctxt - > inputMax = oldinputMax ;
ctxt - > inputTab = oldinputTab ;
2013-03-27 09:21:38 +04:00
if ( ( ctxt - > encoding ! = NULL ) & &
( ( ctxt - > dict = = NULL ) | |
( ! xmlDictOwns ( ctxt - > dict , ctxt - > encoding ) ) ) )
xmlFree ( ( xmlChar * ) ctxt - > encoding ) ;
ctxt - > encoding = oldencoding ;
2003-08-21 02:54:39 +04:00
/* ctxt->wellFormed = oldwellFormed; */
}
}
/**
* xmlSAX2ResolveEntity :
* @ ctx : the user data ( XML parser context )
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
2024-06-11 04:51:43 +03:00
* This is only used to load DTDs . The preferred way to install
* custom resolvers is xmlCtxtSetResourceLoader .
2003-08-21 02:54:39 +04:00
*
2024-06-11 04:51:43 +03:00
* Returns a parser input .
2003-08-21 02:54:39 +04:00
*/
xmlParserInputPtr
2024-06-11 04:51:43 +03:00
xmlSAX2ResolveEntity ( void * ctx , const xmlChar * publicId ,
const xmlChar * systemId )
2003-08-21 02:54:39 +04:00
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2024-01-07 22:44:40 +03:00
xmlParserInputPtr ret = NULL ;
2003-08-21 02:54:39 +04:00
xmlChar * URI ;
2024-04-05 14:09:45 +03:00
const xmlChar * base = NULL ;
2024-05-10 03:04:52 +03:00
int res ;
2003-08-21 02:54:39 +04:00
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ( NULL ) ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > input ! = NULL )
2024-04-05 14:09:45 +03:00
base = BAD_CAST ctxt - > input - > filename ;
2003-08-21 02:54:39 +04:00
2024-04-05 14:09:45 +03:00
if ( ( xmlStrlen ( systemId ) > XML_MAX_URI_LENGTH ) | |
( xmlStrlen ( base ) > XML_MAX_URI_LENGTH ) ) {
xmlFatalErr ( ctxt , XML_ERR_RESOURCE_LIMIT , " URI too long " ) ;
return ( NULL ) ;
}
2024-05-10 03:04:52 +03:00
res = xmlBuildURISafe ( systemId , base , & URI ) ;
if ( URI = = NULL ) {
if ( res < 0 )
xmlSAX2ErrMemory ( ctxt ) ;
else
xmlWarnMsg ( ctxt , XML_ERR_INVALID_URI ,
" Can't resolve URI: %s \n " , systemId ) ;
2024-01-07 22:44:40 +03:00
return ( NULL ) ;
}
if ( xmlStrlen ( URI ) > XML_MAX_URI_LENGTH ) {
xmlFatalErr ( ctxt , XML_ERR_RESOURCE_LIMIT , " URI too long " ) ;
} else {
2024-06-11 20:10:41 +03:00
ret = xmlLoadResource ( ctxt , ( const char * ) URI ,
( const char * ) publicId , XML_RESOURCE_DTD ) ;
2024-01-07 22:44:40 +03:00
}
2003-08-21 02:54:39 +04:00
2024-01-07 22:44:40 +03:00
xmlFree ( URI ) ;
2003-08-21 02:54:39 +04:00
return ( ret ) ;
}
/**
* xmlSAX2GetEntity :
* @ ctx : the user data ( XML parser context )
* @ name : The entity name
*
* Get an entity by name
*
* Returns the xmlEntityPtr if found .
*/
xmlEntityPtr
xmlSAX2GetEntity ( void * ctx , const xmlChar * name )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlEntityPtr ret = NULL ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ( NULL ) ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > inSubset = = 0 ) {
ret = xmlGetPredefinedEntity ( name ) ;
if ( ret ! = NULL )
return ( ret ) ;
}
if ( ( ctxt - > myDoc ! = NULL ) & & ( ctxt - > myDoc - > standalone = = 1 ) ) {
if ( ctxt - > inSubset = = 2 ) {
ctxt - > myDoc - > standalone = 0 ;
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
ctxt - > myDoc - > standalone = 1 ;
} else {
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
if ( ret = = NULL ) {
ctxt - > myDoc - > standalone = 0 ;
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
if ( ret ! = NULL ) {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_NOT_STANDALONE ,
" Entity(%s) document marked standalone but requires external subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
}
ctxt - > myDoc - > standalone = 1 ;
}
}
} else {
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
}
return ( ret ) ;
}
/**
* xmlSAX2GetParameterEntity :
* @ ctx : the user data ( XML parser context )
* @ name : The entity name
*
* Get a parameter entity by name
*
* Returns the xmlEntityPtr if found .
*/
xmlEntityPtr
xmlSAX2GetParameterEntity ( void * ctx , const xmlChar * name )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlEntityPtr ret ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ( NULL ) ;
2003-08-21 02:54:39 +04:00
ret = xmlGetParameterEntity ( ctxt - > myDoc , name ) ;
return ( ret ) ;
}
/**
* xmlSAX2EntityDecl :
* @ ctx : the user data ( XML parser context )
2012-09-11 09:26:36 +04:00
* @ name : the entity name
* @ type : the entity type
2003-08-21 02:54:39 +04:00
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
* @ content : the entity value ( without processing ) .
*
* An entity definition has been parsed
*/
void
xmlSAX2EntityDecl ( void * ctx , const xmlChar * name , int type ,
const xmlChar * publicId , const xmlChar * systemId , xmlChar * content )
{
xmlEntityPtr ent ;
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2023-12-10 20:10:42 +03:00
int extSubset ;
int res ;
2003-08-21 02:54:39 +04:00
2023-12-10 20:10:42 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) )
return ;
extSubset = ctxt - > inSubset = = 2 ;
res = xmlAddEntity ( ctxt - > myDoc , extSubset , name , type , publicId , systemId ,
content , & ent ) ;
switch ( res ) {
case XML_ERR_OK :
break ;
case XML_ERR_NO_MEMORY :
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
case XML_WAR_ENTITY_REDEFINED :
if ( ctxt - > pedantic ) {
if ( extSubset )
xmlWarnMsg ( ctxt , res , " Entity(%s) already defined in the "
" external subset \n " , name ) ;
else
xmlWarnMsg ( ctxt , res , " Entity(%s) already defined in the "
" internal subset \n " , name ) ;
}
return ;
case XML_ERR_REDECL_PREDEF_ENTITY :
/*
* Technically an error but it ' s a common mistake to get double
* escaping according to " 4.6 Predefined Entities " wrong .
*/
xmlWarnMsg ( ctxt , res , " Invalid redeclaration of predefined "
" entity '%s' " , name ) ;
return ;
default :
xmlFatalErrMsg ( ctxt , XML_ERR_INTERNAL_ERROR ,
" Unexpected error code from xmlAddEntity \n " ,
NULL , NULL ) ;
return ;
}
if ( ( ent - > URI = = NULL ) & & ( systemId ! = NULL ) ) {
xmlChar * URI ;
const char * base = NULL ;
2024-05-03 01:44:42 +03:00
int i ;
2023-12-10 20:10:42 +03:00
2024-05-03 01:44:42 +03:00
for ( i = ctxt - > inputNr - 1 ; i > = 0 ; i - - ) {
if ( ctxt - > inputTab [ i ] - > filename ! = NULL ) {
base = ctxt - > inputTab [ i ] - > filename ;
break ;
}
}
2023-12-10 20:10:42 +03:00
2024-05-10 03:04:52 +03:00
res = xmlBuildURISafe ( systemId , ( const xmlChar * ) base , & URI ) ;
if ( URI = = NULL ) {
if ( res < 0 ) {
xmlSAX2ErrMemory ( ctxt ) ;
} else {
xmlWarnMsg ( ctxt , XML_ERR_INVALID_URI ,
" Can't resolve URI: %s \n " , systemId ) ;
}
} else if ( xmlStrlen ( URI ) > XML_MAX_URI_LENGTH ) {
2024-03-29 13:55:20 +03:00
xmlFatalErr ( ctxt , XML_ERR_RESOURCE_LIMIT , " URI too long " ) ;
xmlFree ( URI ) ;
} else {
ent - > URI = URI ;
2023-12-10 20:10:42 +03:00
}
2003-08-21 02:54:39 +04:00
}
}
/**
* xmlSAX2AttributeDecl :
* @ ctx : the user data ( XML parser context )
* @ elem : the name of the element
2012-09-11 09:26:36 +04:00
* @ fullname : the attribute name
* @ type : the attribute type
2003-08-21 02:54:39 +04:00
* @ def : the type of default value
* @ defaultValue : the attribute default value
* @ tree : the tree of enumerated value set
*
* An attribute definition has been parsed
*/
void
xmlSAX2AttributeDecl ( void * ctx , const xmlChar * elem , const xmlChar * fullname ,
int type , int def , const xmlChar * defaultValue ,
xmlEnumerationPtr tree )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlAttributePtr attr ;
xmlChar * name = NULL , * prefix = NULL ;
2022-02-22 21:57:12 +03:00
/* Avoid unused variable warning if features are disabled. */
( void ) attr ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) )
return ;
2004-04-19 00:55:39 +04:00
if ( ( xmlStrEqual ( fullname , BAD_CAST " xml:id " ) ) & &
( type ! = XML_ATTRIBUTE_ID ) ) {
/*
* Raise the error but keep the validity flag
*/
int tmp = ctxt - > valid ;
xmlErrValid ( ctxt , XML_DTD_XMLID_TYPE ,
" xml:id : attribute type should be ID \n " , NULL , NULL ) ;
ctxt - > valid = tmp ;
}
2003-09-10 14:50:59 +04:00
/* TODO: optimize name/prefix allocation */
2003-08-21 02:54:39 +04:00
name = xmlSplitQName ( ctxt , fullname , & prefix ) ;
2023-12-10 20:10:42 +03:00
if ( name = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
ctxt - > vctxt . valid = 1 ;
if ( ctxt - > inSubset = = 1 )
attr = xmlAddAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset , elem ,
name , prefix , ( xmlAttributeType ) type ,
( xmlAttributeDefault ) def , defaultValue , tree ) ;
else if ( ctxt - > inSubset = = 2 )
attr = xmlAddAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset , elem ,
2012-09-11 09:26:36 +04:00
name , prefix , ( xmlAttributeType ) type ,
2003-08-21 02:54:39 +04:00
( xmlAttributeDefault ) def , defaultValue , tree ) ;
else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_INTERNAL_ERROR ,
" SAX.xmlSAX2AttributeDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2021-07-14 13:37:07 +03:00
xmlFree ( name ) ;
2023-12-10 20:10:42 +03:00
xmlFree ( prefix ) ;
2003-09-10 14:50:59 +04:00
xmlFreeEnumeration ( tree ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ctxt - > vctxt . valid = = 0 )
ctxt - > valid = 0 ;
if ( ( attr ! = NULL ) & & ( ctxt - > validate ) & & ( ctxt - > wellFormed ) & &
2006-03-09 19:49:24 +03:00
( ctxt - > myDoc - > intSubset ! = NULL ) )
2003-08-21 02:54:39 +04:00
ctxt - > valid & = xmlValidateAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc ,
attr ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
if ( name ! = NULL )
xmlFree ( name ) ;
}
/**
* xmlSAX2ElementDecl :
* @ ctx : the user data ( XML parser context )
2012-09-11 09:26:36 +04:00
* @ name : the element name
* @ type : the element type
2003-08-21 02:54:39 +04:00
* @ content : the element value tree
*
* An element definition has been parsed
*/
void
xmlSAX2ElementDecl ( void * ctx , const xmlChar * name , int type ,
xmlElementContentPtr content )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlElementPtr elem = NULL ;
2022-02-22 21:57:12 +03:00
/* Avoid unused variable warning if features are disabled. */
( void ) elem ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) )
return ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > inSubset = = 1 )
elem = xmlAddElementDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset ,
name , ( xmlElementTypeVal ) type , content ) ;
else if ( ctxt - > inSubset = = 2 )
elem = xmlAddElementDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset ,
name , ( xmlElementTypeVal ) type , content ) ;
else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_INTERNAL_ERROR ,
" SAX.xmlSAX2ElementDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( elem = = NULL )
ctxt - > valid = 0 ;
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & =
xmlValidateElementDecl ( & ctxt - > vctxt , ctxt - > myDoc , elem ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2NotationDecl :
* @ ctx : the user data ( XML parser context )
* @ name : The name of the notation
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
* What to do when a notation declaration has been parsed .
*/
void
xmlSAX2NotationDecl ( void * ctx , const xmlChar * name ,
const xmlChar * publicId , const xmlChar * systemId )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNotationPtr nota = NULL ;
2022-02-22 21:57:12 +03:00
/* Avoid unused variable warning if features are disabled. */
( void ) nota ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) )
return ;
2003-08-21 02:54:39 +04:00
if ( ( publicId = = NULL ) & & ( systemId = = NULL ) ) {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_NOTATION_PROCESSING ,
" SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
return ;
} else if ( ctxt - > inSubset = = 1 )
nota = xmlAddNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset , name ,
publicId , systemId ) ;
else if ( ctxt - > inSubset = = 2 )
nota = xmlAddNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset , name ,
publicId , systemId ) ;
else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_NOTATION_PROCESSING ,
" SAX.xmlSAX2NotationDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( nota = = NULL ) ctxt - > valid = 0 ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt - > validate ) & & ( ctxt - > wellFormed ) & &
( ctxt - > myDoc - > intSubset ! = NULL ) )
2003-08-21 02:54:39 +04:00
ctxt - > valid & = xmlValidateNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc ,
nota ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2UnparsedEntityDecl :
* @ ctx : the user data ( XML parser context )
* @ name : The name of the entity
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
* @ notationName : the name of the notation
*
* What to do when an unparsed entity declaration is parsed
*/
void
xmlSAX2UnparsedEntityDecl ( void * ctx , const xmlChar * name ,
const xmlChar * publicId , const xmlChar * systemId ,
const xmlChar * notationName )
{
2023-12-10 20:10:42 +03:00
xmlSAX2EntityDecl ( ctx , name , XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ,
publicId , systemId , ( xmlChar * ) notationName ) ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2SetDocumentLocator :
* @ ctx : the user data ( XML parser context )
* @ loc : A SAX Locator
*
* Receive the document locator at startup , actually xmlDefaultSAXLocator
* Everything is available on the context , so this is useless in our case .
*/
void
xmlSAX2SetDocumentLocator ( void * ctx ATTRIBUTE_UNUSED , xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED )
{
}
/**
* xmlSAX2StartDocument :
* @ ctx : the user data ( XML parser context )
*
* called when the document start being processed .
*/
void
xmlSAX2StartDocument ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlDocPtr doc ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef LIBXML_HTML_ENABLED
2023-12-10 20:10:42 +03:00
if ( ctxt - > html ) {
2003-08-21 02:54:39 +04:00
if ( ctxt - > myDoc = = NULL )
ctxt - > myDoc = htmlNewDocNoDtD ( NULL , NULL ) ;
if ( ctxt - > myDoc = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2013-08-03 18:16:02 +04:00
ctxt - > myDoc - > properties = XML_DOC_HTML ;
ctxt - > myDoc - > parseFlags = ctxt - > options ;
2023-12-10 20:10:42 +03:00
} else
2003-08-21 02:54:39 +04:00
# endif
2023-12-10 20:10:42 +03:00
{
2003-08-21 02:54:39 +04:00
doc = ctxt - > myDoc = xmlNewDoc ( ctxt - > version ) ;
if ( doc ! = NULL ) {
2008-07-31 23:54:59 +04:00
doc - > properties = 0 ;
if ( ctxt - > options & XML_PARSE_OLD10 )
doc - > properties | = XML_DOC_OLD10 ;
doc - > parseFlags = ctxt - > options ;
2003-08-21 02:54:39 +04:00
doc - > standalone = ctxt - > standalone ;
} else {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2004-03-22 18:22:58 +03:00
if ( ( ctxt - > dictNames ) & & ( doc ! = NULL ) ) {
2003-09-25 01:23:56 +04:00
doc - > dict = ctxt - > dict ;
2004-03-22 18:22:58 +03:00
xmlDictReference ( doc - > dict ) ;
}
2003-08-21 02:54:39 +04:00
}
if ( ( ctxt - > myDoc ! = NULL ) & & ( ctxt - > myDoc - > URL = = NULL ) & &
( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ! = NULL ) ) {
2006-10-10 16:37:14 +04:00
ctxt - > myDoc - > URL = xmlPathToURI ( ( const xmlChar * ) ctxt - > input - > filename ) ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > myDoc - > URL = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
}
}
/**
* xmlSAX2EndDocument :
* @ ctx : the user data ( XML parser context )
*
* called when the document end has been detected .
*/
void
xmlSAX2EndDocument ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2023-08-16 20:43:02 +03:00
xmlDocPtr doc ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateDocumentFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
2023-08-16 20:43:02 +03:00
doc = ctxt - > myDoc ;
if ( ( doc ! = NULL ) & & ( doc - > encoding = = NULL ) ) {
2024-02-26 17:14:28 +03:00
const xmlChar * encoding = xmlGetActualEncoding ( ctxt ) ;
2023-08-16 20:43:02 +03:00
if ( encoding ! = NULL ) {
doc - > encoding = xmlStrdup ( encoding ) ;
if ( doc - > encoding = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-08-16 20:43:02 +03:00
}
2003-08-21 02:54:39 +04:00
}
}
2024-03-28 17:42:02 +03:00
static void
xmlSAX2AppendChild ( xmlParserCtxtPtr ctxt , xmlNodePtr node ) {
xmlNodePtr parent ;
xmlNodePtr last ;
if ( ctxt - > inSubset = = 1 ) {
parent = ( xmlNodePtr ) ctxt - > myDoc - > intSubset ;
} else if ( ctxt - > inSubset = = 2 ) {
parent = ( xmlNodePtr ) ctxt - > myDoc - > extSubset ;
} else {
parent = ctxt - > node ;
if ( parent = = NULL )
parent = ( xmlNodePtr ) ctxt - > myDoc ;
}
last = parent - > last ;
if ( last = = NULL ) {
parent - > children = node ;
} else {
last - > next = node ;
node - > prev = last ;
}
parent - > last = node ;
node - > parent = parent ;
if ( ( node - > type ! = XML_TEXT_NODE ) & &
( ctxt - > linenumbers ) & &
( ctxt - > input ! = NULL ) ) {
if ( ( unsigned ) ctxt - > input - > line < ( unsigned ) USHRT_MAX )
node - > line = ctxt - > input - > line ;
else
node - > line = USHRT_MAX ;
}
}
2022-03-04 05:35:57 +03:00
# if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
2022-02-22 21:57:12 +03:00
/**
* xmlNsErrMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
* @ str2 : an error string
*
* Handle a namespace error
*/
static void LIBXML_ATTR_FORMAT ( 3 , 0 )
xmlNsErrMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
2023-12-20 02:33:34 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_NAMESPACE , error , XML_ERR_ERROR ,
str1 , str2 , NULL , 0 , msg , str1 , str2 ) ;
2022-02-22 21:57:12 +03:00
}
2003-08-21 02:54:39 +04:00
/**
* xmlSAX2AttributeInternal :
* @ ctx : the user data ( XML parser context )
* @ fullname : The attribute name , including namespace prefix
* @ value : The attribute value
* @ prefix : the prefix on the element node
*
* Handle an attribute that has been read by the parser .
* The default handling is to convert the attribute into an
* DOM subtree and past it in a new xmlAttr element added to
* the element .
*/
static void
xmlSAX2AttributeInternal ( void * ctx , const xmlChar * fullname ,
2003-09-29 17:20:24 +04:00
const xmlChar * value , const xmlChar * prefix ATTRIBUTE_UNUSED )
2003-08-21 02:54:39 +04:00
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlAttrPtr ret ;
xmlChar * name ;
xmlChar * ns ;
xmlChar * nval ;
xmlNsPtr namespace ;
2007-06-12 19:15:52 +04:00
if ( ctxt - > html ) {
2003-08-21 02:54:39 +04:00
name = xmlStrdup ( fullname ) ;
2007-06-12 19:15:52 +04:00
ns = NULL ;
namespace = NULL ;
} else {
/*
* Split the full name into a namespace prefix and the tag name
*/
name = xmlSplitQName ( ctxt , fullname , & ns ) ;
if ( ( name ! = NULL ) & & ( name [ 0 ] = = 0 ) ) {
if ( xmlStrEqual ( ns , BAD_CAST " xmlns " ) ) {
xmlNsErrMsg ( ctxt , XML_ERR_NS_DECL_ERROR ,
" invalid namespace declaration '%s' \n " ,
fullname , NULL ) ;
} else {
xmlNsWarnMsg ( ctxt , XML_WAR_NS_COLUMN ,
" Avoid attribute ending with ':' like '%s' \n " ,
fullname , NULL ) ;
}
if ( ns ! = NULL )
xmlFree ( ns ) ;
ns = NULL ;
xmlFree ( name ) ;
name = xmlStrdup ( fullname ) ;
}
2003-08-21 02:54:39 +04:00
}
if ( name = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
if ( ns ! = NULL )
xmlFree ( ns ) ;
return ;
}
2010-03-15 17:47:50 +03:00
# ifdef LIBXML_HTML_ENABLED
if ( ( ctxt - > html ) & &
( value = = NULL ) & & ( htmlIsBooleanAttr ( fullname ) ) ) {
2010-03-15 18:08:44 +03:00
nval = xmlStrdup ( fullname ) ;
2023-12-10 20:10:42 +03:00
if ( nval = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2010-03-15 18:08:44 +03:00
value = ( const xmlChar * ) nval ;
2010-03-15 17:47:50 +03:00
} else
# endif
{
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2010-03-15 17:47:50 +03:00
/*
* Do the last stage of the attribute normalization
* Needed for HTML too :
* http : //www.w3.org/TR/html4/types.html#h-6.2
*/
ctxt - > vctxt . valid = 1 ;
nval = xmlValidCtxtNormalizeAttributeValue ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node ,
fullname , value ) ;
if ( ctxt - > vctxt . valid ! = 1 ) {
ctxt - > valid = 0 ;
}
if ( nval ! = NULL )
value = nval ;
2003-09-28 22:58:27 +04:00
# else
2010-03-15 17:47:50 +03:00
nval = NULL ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2010-03-15 17:47:50 +03:00
}
2003-08-21 02:54:39 +04:00
/*
* Check whether it ' s a namespace definition
*/
if ( ( ! ctxt - > html ) & & ( ns = = NULL ) & &
( name [ 0 ] = = ' x ' ) & & ( name [ 1 ] = = ' m ' ) & & ( name [ 2 ] = = ' l ' ) & &
( name [ 3 ] = = ' n ' ) & & ( name [ 4 ] = = ' s ' ) & & ( name [ 5 ] = = 0 ) ) {
xmlNsPtr nsret ;
xmlChar * val ;
2022-02-22 21:57:12 +03:00
/* Avoid unused variable warning if features are disabled. */
( void ) nsret ;
2003-08-21 02:54:39 +04:00
if ( ! ctxt - > replaceEntities ) {
2023-12-30 04:50:34 +03:00
/* TODO: normalize if needed */
val = xmlExpandEntitiesInAttValue ( ctxt , value , /* normalize */ 0 ) ;
2014-06-13 10:45:20 +04:00
if ( val = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2014-06-13 10:45:20 +04:00
if ( name ! = NULL )
xmlFree ( name ) ;
2017-09-06 00:45:04 +03:00
if ( nval ! = NULL )
xmlFree ( nval ) ;
2014-06-13 10:45:20 +04:00
return ;
}
2003-08-21 02:54:39 +04:00
} else {
val = ( xmlChar * ) value ;
}
if ( val [ 0 ] ! = 0 ) {
xmlURIPtr uri ;
2023-12-10 20:10:42 +03:00
if ( xmlParseURISafe ( ( const char * ) val , & uri ) < 0 )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
if ( uri = = NULL ) {
2023-12-10 20:10:42 +03:00
xmlNsWarnMsg ( ctxt , XML_WAR_NS_URI ,
" xmlns:%s: %s not a valid URI \n " , name , value ) ;
2003-08-21 02:54:39 +04:00
} else {
if ( uri - > scheme = = NULL ) {
2023-12-10 20:10:42 +03:00
xmlNsWarnMsg ( ctxt , XML_WAR_NS_URI_RELATIVE ,
" xmlns:%s: URI %s is not absolute \n " ,
name , value ) ;
2003-08-21 02:54:39 +04:00
}
xmlFreeURI ( uri ) ;
}
}
/* a default namespace definition */
nsret = xmlNewNs ( ctxt - > node , val , NULL ) ;
2023-12-10 20:10:42 +03:00
if ( nsret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
/*
* Validate also for namespace decls , they are attributes from
* an XML - 1.0 perspective
*/
2023-12-10 20:10:42 +03:00
else if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
2003-08-21 02:54:39 +04:00
ctxt - > valid & = xmlValidateOneNamespace ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , prefix , nsret , val ) ;
2023-12-10 20:10:42 +03:00
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2012-09-11 09:26:36 +04:00
if ( name ! = NULL )
2003-08-21 02:54:39 +04:00
xmlFree ( name ) ;
if ( nval ! = NULL )
xmlFree ( nval ) ;
if ( val ! = value )
xmlFree ( val ) ;
return ;
}
if ( ( ! ctxt - > html ) & &
( ns ! = NULL ) & & ( ns [ 0 ] = = ' x ' ) & & ( ns [ 1 ] = = ' m ' ) & & ( ns [ 2 ] = = ' l ' ) & &
( ns [ 3 ] = = ' n ' ) & & ( ns [ 4 ] = = ' s ' ) & & ( ns [ 5 ] = = 0 ) ) {
xmlNsPtr nsret ;
xmlChar * val ;
2022-02-22 21:57:12 +03:00
/* Avoid unused variable warning if features are disabled. */
( void ) nsret ;
2003-08-21 02:54:39 +04:00
if ( ! ctxt - > replaceEntities ) {
2023-12-30 04:50:34 +03:00
/* TODO: normalize if needed */
val = xmlExpandEntitiesInAttValue ( ctxt , value , /* normalize */ 0 ) ;
2003-08-21 02:54:39 +04:00
if ( val = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
xmlFree ( ns ) ;
2012-09-11 09:26:36 +04:00
if ( name ! = NULL )
2003-08-21 02:54:39 +04:00
xmlFree ( name ) ;
2017-09-06 00:45:04 +03:00
if ( nval ! = NULL )
xmlFree ( nval ) ;
2003-08-21 02:54:39 +04:00
return ;
}
} else {
val = ( xmlChar * ) value ;
}
if ( val [ 0 ] = = 0 ) {
2005-07-05 18:04:36 +04:00
xmlNsErrMsg ( ctxt , XML_NS_ERR_EMPTY ,
" Empty namespace name for prefix %s \n " , name , NULL ) ;
2003-08-21 02:54:39 +04:00
}
if ( ( ctxt - > pedantic ! = 0 ) & & ( val [ 0 ] ! = 0 ) ) {
xmlURIPtr uri ;
2023-12-10 20:10:42 +03:00
if ( xmlParseURISafe ( ( const char * ) val , & uri ) < 0 )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
if ( uri = = NULL ) {
2005-07-05 18:04:36 +04:00
xmlNsWarnMsg ( ctxt , XML_WAR_NS_URI ,
2003-08-21 02:54:39 +04:00
" xmlns:%s: %s not a valid URI \n " , name , value ) ;
} else {
if ( uri - > scheme = = NULL ) {
2005-07-05 18:04:36 +04:00
xmlNsWarnMsg ( ctxt , XML_WAR_NS_URI_RELATIVE ,
2003-08-21 02:54:39 +04:00
" xmlns:%s: URI %s is not absolute \n " , name , value ) ;
}
xmlFreeURI ( uri ) ;
}
}
/* a standard namespace definition */
nsret = xmlNewNs ( ctxt - > node , val , name ) ;
xmlFree ( ns ) ;
2023-12-10 20:10:42 +03:00
if ( nsret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
/*
* Validate also for namespace decls , they are attributes from
* an XML - 1.0 perspective
*/
2023-12-10 20:10:42 +03:00
else if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
2003-08-21 02:54:39 +04:00
ctxt - > valid & = xmlValidateOneNamespace ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , prefix , nsret , value ) ;
2023-12-10 20:10:42 +03:00
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2012-09-11 09:26:36 +04:00
if ( name ! = NULL )
2003-08-21 02:54:39 +04:00
xmlFree ( name ) ;
if ( nval ! = NULL )
xmlFree ( nval ) ;
if ( val ! = value )
xmlFree ( val ) ;
return ;
}
if ( ns ! = NULL ) {
2024-03-17 19:16:55 +03:00
int res ;
res = xmlSearchNsSafe ( ctxt - > node , ns , & namespace ) ;
if ( res < 0 )
xmlSAX2ErrMemory ( ctxt ) ;
2009-09-07 14:15:08 +04:00
2003-08-29 01:13:25 +04:00
if ( namespace = = NULL ) {
2005-07-05 18:04:36 +04:00
xmlNsErrMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
2003-09-06 22:02:53 +04:00
" Namespace prefix %s of attribute %s is not defined \n " ,
2003-08-29 01:13:25 +04:00
ns , name ) ;
2009-09-07 14:15:08 +04:00
} else {
xmlAttrPtr prop ;
prop = ctxt - > node - > properties ;
while ( prop ! = NULL ) {
if ( prop - > ns ! = NULL ) {
if ( ( xmlStrEqual ( name , prop - > name ) ) & &
( ( namespace = = prop - > ns ) | |
( xmlStrEqual ( namespace - > href , prop - > ns - > href ) ) ) ) {
2024-01-26 13:39:51 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_PARSER ,
XML_ERR_ATTRIBUTE_REDEFINED , XML_ERR_FATAL ,
name , NULL , NULL , 0 ,
" Attribute %s in %s redefined \n " ,
name , namespace - > href ) ;
2017-09-06 00:45:04 +03:00
if ( name ! = NULL )
xmlFree ( name ) ;
2009-09-07 14:15:08 +04:00
goto error ;
}
}
prop = prop - > next ;
}
}
2003-08-21 02:54:39 +04:00
} else {
namespace = NULL ;
}
/* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
ret = xmlNewNsPropEatName ( ctxt - > node , namespace , name , NULL ) ;
2023-12-10 20:10:42 +03:00
if ( ret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-01-22 15:27:41 +03:00
goto error ;
2023-12-10 20:10:42 +03:00
}
2023-01-22 15:27:41 +03:00
if ( ( ctxt - > replaceEntities = = 0 ) & & ( ! ctxt - > html ) ) {
2024-03-11 17:57:14 +03:00
if ( xmlNodeParseContent ( ( xmlNodePtr ) ret , value , INT_MAX ) < 0 )
xmlSAX2ErrMemory ( ctxt ) ;
2023-01-22 15:27:41 +03:00
} else if ( value ! = NULL ) {
ret - > children = xmlNewDocText ( ctxt - > myDoc , value ) ;
2023-12-10 20:10:42 +03:00
if ( ret - > children = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
} else {
ret - > last = ret - > children ;
2023-01-22 15:27:41 +03:00
ret - > children - > parent = ( xmlNodePtr ) ret ;
2023-12-10 20:10:42 +03:00
}
2003-08-21 02:54:39 +04:00
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ( ! ctxt - > html ) & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
2012-09-11 09:26:36 +04:00
2003-08-21 02:54:39 +04:00
/*
* If we don ' t substitute entities , the validation should be
* done on a value with replaced entities anyway .
*/
if ( ! ctxt - > replaceEntities ) {
xmlChar * val ;
2023-12-30 04:50:34 +03:00
/* TODO: normalize if needed */
val = xmlExpandEntitiesInAttValue ( ctxt , value , /* normalize */ 0 ) ;
2012-09-11 09:26:36 +04:00
2003-08-21 02:54:39 +04:00
if ( val = = NULL )
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , value ) ;
else {
xmlChar * nvalnorm ;
/*
* Do the last stage of the attribute normalization
* It need to be done twice . . . it ' s an extra burden related
* to the ability to keep xmlSAX2References in attributes
*/
2023-12-10 20:10:42 +03:00
nvalnorm = xmlValidCtxtNormalizeAttributeValue (
& ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , fullname , val ) ;
2003-08-21 02:54:39 +04:00
if ( nvalnorm ! = NULL ) {
xmlFree ( val ) ;
val = nvalnorm ;
}
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , val ) ;
xmlFree ( val ) ;
}
} else {
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , ret , value ) ;
}
2003-09-28 22:58:27 +04:00
} else
# endif /* LIBXML_VALID_ENABLED */
if ( ( ( ctxt - > loadsubset & XML_SKIP_IDS ) = = 0 ) & &
2022-02-08 04:42:30 +03:00
/* Don't create IDs containing entity references */
( ret - > children ! = NULL ) & &
( ret - > children - > type = = XML_TEXT_NODE ) & &
( ret - > children - > next = = NULL ) ) {
xmlChar * content = ret - > children - > content ;
2003-08-21 02:54:39 +04:00
/*
* when validating , the ID registration is done at the attribute
* validation level . Otherwise we have to do specific handling here .
*/
2005-09-03 17:28:24 +04:00
if ( xmlStrEqual ( fullname , BAD_CAST " xml:id " ) ) {
2004-04-10 01:51:49 +04:00
/*
* Add the xml : id value
*
* Open issue : normalization of the value .
*/
2022-02-08 04:42:30 +03:00
if ( xmlValidateNCName ( content , 1 ) ! = 0 ) {
2004-04-19 00:55:39 +04:00
xmlErrValid ( ctxt , XML_DTD_XMLID_VALUE ,
2023-12-10 20:10:42 +03:00
" xml:id : attribute value %s is not an NCName \n " ,
content , NULL ) ;
2004-04-19 00:55:39 +04:00
}
2022-02-08 04:42:30 +03:00
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , content , ret ) ;
2023-12-10 20:10:42 +03:00
} else {
int res = xmlIsID ( ctxt - > myDoc , ctxt - > node , ret ) ;
if ( res < 0 )
2023-12-18 21:31:29 +03:00
xmlCtxtErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
else if ( res > 0 )
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , content , ret ) ;
else if ( xmlIsRef ( ctxt - > myDoc , ctxt - > node , ret ) )
xmlAddRef ( & ctxt - > vctxt , ctxt - > myDoc , content , ret ) ;
}
2003-08-21 02:54:39 +04:00
}
error :
if ( nval ! = NULL )
xmlFree ( nval ) ;
2012-09-11 09:26:36 +04:00
if ( ns ! = NULL )
2003-08-21 02:54:39 +04:00
xmlFree ( ns ) ;
}
/*
* xmlCheckDefaultedAttributes :
*
* Check defaulted attributes from the DTD
*/
static void
xmlCheckDefaultedAttributes ( xmlParserCtxtPtr ctxt , const xmlChar * name ,
const xmlChar * prefix , const xmlChar * * atts ) {
xmlElementPtr elemDecl ;
const xmlChar * att ;
int internal = 1 ;
int i ;
elemDecl = xmlGetDtdQElementDesc ( ctxt - > myDoc - > intSubset , name , prefix ) ;
if ( elemDecl = = NULL ) {
elemDecl = xmlGetDtdQElementDesc ( ctxt - > myDoc - > extSubset , name , prefix ) ;
internal = 0 ;
}
process_external_subset :
if ( elemDecl ! = NULL ) {
xmlAttributePtr attr = elemDecl - > attributes ;
/*
* Check against defaulted attributes from the external subset
* if the document is stamped as standalone
*/
if ( ( ctxt - > myDoc - > standalone = = 1 ) & &
( ctxt - > myDoc - > extSubset ! = NULL ) & &
( ctxt - > validate ) ) {
while ( attr ! = NULL ) {
if ( ( attr - > defaultValue ! = NULL ) & &
( xmlGetDtdQAttrDesc ( ctxt - > myDoc - > extSubset ,
attr - > elem , attr - > name ,
attr - > prefix ) = = attr ) & &
( xmlGetDtdQAttrDesc ( ctxt - > myDoc - > intSubset ,
attr - > elem , attr - > name ,
attr - > prefix ) = = NULL ) ) {
xmlChar * fulln ;
if ( attr - > prefix ! = NULL ) {
fulln = xmlStrdup ( attr - > prefix ) ;
2024-02-20 14:32:17 +03:00
if ( fulln ! = NULL )
fulln = xmlStrcat ( fulln , BAD_CAST " : " ) ;
if ( fulln ! = NULL )
fulln = xmlStrcat ( fulln , attr - > name ) ;
2003-08-21 02:54:39 +04:00
} else {
fulln = xmlStrdup ( attr - > name ) ;
}
2009-07-29 13:33:32 +04:00
if ( fulln = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2009-07-29 13:33:32 +04:00
break ;
}
2003-08-21 02:54:39 +04:00
/*
* Check that the attribute is not declared in the
* serialization
*/
att = NULL ;
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i ] ;
while ( att ! = NULL ) {
if ( xmlStrEqual ( att , fulln ) )
break ;
i + = 2 ;
att = atts [ i ] ;
}
}
if ( att = = NULL ) {
2003-12-08 13:25:02 +03:00
xmlErrValid ( ctxt , XML_DTD_STANDALONE_DEFAULTED ,
2003-08-21 02:54:39 +04:00
" standalone: attribute %s on %s defaulted from external subset \n " ,
2023-12-10 20:10:42 +03:00
fulln ,
attr - > elem ) ;
2003-08-21 02:54:39 +04:00
}
2009-07-29 13:34:50 +04:00
xmlFree ( fulln ) ;
2003-08-21 02:54:39 +04:00
}
attr = attr - > nexth ;
}
}
/*
* Actually insert defaulted values when needed
*/
attr = elemDecl - > attributes ;
while ( attr ! = NULL ) {
/*
2019-09-30 18:04:54 +03:00
* Make sure that attributes redefinition occurring in the
* internal subset are not overridden by definitions in the
2003-08-21 02:54:39 +04:00
* external subset .
*/
if ( attr - > defaultValue ! = NULL ) {
/*
* the element should be instantiated in the tree if :
* - this is a namespace prefix
* - the user required for completion in the tree
* like XSLT
2012-09-11 09:26:36 +04:00
* - there isn ' t already an attribute definition
2003-08-21 02:54:39 +04:00
* in the internal subset overriding it .
*/
if ( ( ( attr - > prefix ! = NULL ) & &
( xmlStrEqual ( attr - > prefix , BAD_CAST " xmlns " ) ) ) | |
( ( attr - > prefix = = NULL ) & &
( xmlStrEqual ( attr - > name , BAD_CAST " xmlns " ) ) ) | |
( ctxt - > loadsubset & XML_COMPLETE_ATTRS ) ) {
xmlAttributePtr tst ;
tst = xmlGetDtdQAttrDesc ( ctxt - > myDoc - > intSubset ,
attr - > elem , attr - > name ,
attr - > prefix ) ;
if ( ( tst = = attr ) | | ( tst = = NULL ) ) {
xmlChar fn [ 50 ] ;
xmlChar * fulln ;
fulln = xmlBuildQName ( attr - > name , attr - > prefix , fn , 50 ) ;
if ( fulln = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
return ;
}
/*
* Check that the attribute is not declared in the
* serialization
*/
att = NULL ;
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i ] ;
while ( att ! = NULL ) {
if ( xmlStrEqual ( att , fulln ) )
break ;
i + = 2 ;
att = atts [ i ] ;
}
}
if ( att = = NULL ) {
xmlSAX2AttributeInternal ( ctxt , fulln ,
attr - > defaultValue , prefix ) ;
}
if ( ( fulln ! = fn ) & & ( fulln ! = attr - > name ) )
xmlFree ( fulln ) ;
}
}
}
attr = attr - > nexth ;
}
if ( internal = = 1 ) {
elemDecl = xmlGetDtdQElementDesc ( ctxt - > myDoc - > extSubset ,
name , prefix ) ;
internal = 0 ;
goto process_external_subset ;
}
}
}
/**
* xmlSAX2StartElement :
* @ ctx : the user data ( XML parser context )
* @ fullname : The element name , including namespace prefix
* @ atts : An array of name / value attributes pairs , NULL terminated
*
* called when an opening tag has been processed .
*/
void
xmlSAX2StartElement ( void * ctx , const xmlChar * fullname , const xmlChar * * atts )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-08 17:02:18 +03:00
xmlNodePtr parent ;
2003-08-21 02:54:39 +04:00
xmlNsPtr ns ;
xmlChar * name ;
xmlChar * prefix ;
const xmlChar * att ;
const xmlChar * value ;
int i ;
2004-11-09 17:59:59 +03:00
if ( ( ctx = = NULL ) | | ( fullname = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ;
2003-08-21 02:54:39 +04:00
/*
* First check on validity :
*/
2012-09-11 09:26:36 +04:00
if ( ctxt - > validate & & ( ctxt - > myDoc - > extSubset = = NULL ) & &
2003-08-21 02:54:39 +04:00
( ( ctxt - > myDoc - > intSubset = = NULL ) | |
2012-09-11 09:26:36 +04:00
( ( ctxt - > myDoc - > intSubset - > notations = = NULL ) & &
2003-08-21 02:54:39 +04:00
( ctxt - > myDoc - > intSubset - > elements = = NULL ) & &
2012-09-11 09:26:36 +04:00
( ctxt - > myDoc - > intSubset - > attributes = = NULL ) & &
2003-08-21 02:54:39 +04:00
( ctxt - > myDoc - > intSubset - > entities = = NULL ) ) ) ) {
2003-12-08 13:25:02 +03:00
xmlErrValid ( ctxt , XML_ERR_NO_DTD ,
" Validation failed: no DTD found ! " , NULL , NULL ) ;
2003-08-21 02:54:39 +04:00
ctxt - > validate = 0 ;
}
2012-09-11 09:26:36 +04:00
2023-03-31 17:47:48 +03:00
if ( ctxt - > html ) {
prefix = NULL ;
name = xmlStrdup ( fullname ) ;
} else {
/*
* Split the full name into a namespace prefix and the tag name
*/
name = xmlSplitQName ( ctxt , fullname , & prefix ) ;
2023-12-10 20:10:42 +03:00
if ( name = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
2023-03-31 17:47:48 +03:00
}
2003-08-21 02:54:39 +04:00
/*
* Note : the namespace resolution is deferred until the end of the
* attributes parsing , since local namespace can be defined as
* an attribute at this level .
*/
ret = xmlNewDocNodeEatName ( ctxt - > myDoc , NULL , name , NULL ) ;
if ( ret = = NULL ) {
2023-12-10 20:10:42 +03:00
xmlFree ( prefix ) ;
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
return ;
}
ctxt - > nodemem = - 1 ;
2023-08-27 17:35:23 +03:00
/* Initialize parent before pushing node */
parent = ctxt - > node ;
if ( parent = = NULL )
parent = ( xmlNodePtr ) ctxt - > myDoc ;
2024-03-28 17:42:02 +03:00
/*
* Link the child element
*/
xmlSAX2AppendChild ( ctxt , ret ) ;
2003-08-21 02:54:39 +04:00
/*
* We are parsing a new node .
*/
2018-09-12 14:42:27 +03:00
if ( nodePush ( ctxt , ret ) < 0 ) {
2018-09-22 16:41:01 +03:00
xmlUnlinkNode ( ret ) ;
2018-09-12 14:42:27 +03:00
xmlFreeNode ( ret ) ;
2019-01-07 19:14:21 +03:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
2018-09-12 14:42:27 +03:00
return ;
}
2003-08-21 02:54:39 +04:00
2020-07-25 18:57:29 +03:00
if ( ! ctxt - > html ) {
2024-03-17 19:16:55 +03:00
int res ;
2020-07-25 18:57:29 +03:00
/*
* Insert all the defaulted attributes from the DTD especially
* namespaces
*/
if ( ( ctxt - > myDoc - > intSubset ! = NULL ) | |
( ctxt - > myDoc - > extSubset ! = NULL ) ) {
xmlCheckDefaultedAttributes ( ctxt , name , prefix , atts ) ;
}
2003-08-21 02:54:39 +04:00
2020-07-25 18:57:29 +03:00
/*
* process all the attributes whose name start with " xmlns "
*/
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
2003-08-21 02:54:39 +04:00
while ( ( att ! = NULL ) & & ( value ! = NULL ) ) {
if ( ( att [ 0 ] = = ' x ' ) & & ( att [ 1 ] = = ' m ' ) & & ( att [ 2 ] = = ' l ' ) & &
( att [ 3 ] = = ' n ' ) & & ( att [ 4 ] = = ' s ' ) )
xmlSAX2AttributeInternal ( ctxt , att , value , prefix ) ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
2020-07-25 18:57:29 +03:00
}
2003-08-21 02:54:39 +04:00
2020-07-25 18:57:29 +03:00
/*
* Search the namespace , note that since the attributes have been
* processed , the local namespaces are available .
*/
2024-03-17 19:16:55 +03:00
res = xmlSearchNsSafe ( ret , prefix , & ns ) ;
if ( res < 0 )
xmlSAX2ErrMemory ( ctxt ) ;
if ( ( ns = = NULL ) & & ( parent ! = NULL ) ) {
res = xmlSearchNsSafe ( parent , prefix , & ns ) ;
if ( res < 0 )
xmlSAX2ErrMemory ( ctxt ) ;
}
2020-07-25 18:57:29 +03:00
if ( ( prefix ! = NULL ) & & ( ns = = NULL ) ) {
xmlNsWarnMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
" Namespace prefix %s is not defined \n " ,
prefix , NULL ) ;
2023-12-10 20:10:42 +03:00
ns = xmlNewNs ( ret , NULL , prefix ) ;
if ( ns = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2020-07-25 18:57:29 +03:00
}
2003-08-21 02:54:39 +04:00
2020-07-25 18:57:29 +03:00
/*
* set the namespace node , making sure that if the default namespace
* is unbound on a parent we simply keep it NULL
*/
if ( ( ns ! = NULL ) & & ( ns - > href ! = NULL ) & &
( ( ns - > href [ 0 ] ! = 0 ) | | ( ns - > prefix ! = NULL ) ) )
xmlSetNs ( ret , ns ) ;
}
2003-08-21 02:54:39 +04:00
/*
* process all the other attributes
*/
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
if ( ctxt - > html ) {
while ( att ! = NULL ) {
xmlSAX2AttributeInternal ( ctxt , att , value , NULL ) ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
} else {
while ( ( att ! = NULL ) & & ( value ! = NULL ) ) {
if ( ( att [ 0 ] ! = ' x ' ) | | ( att [ 1 ] ! = ' m ' ) | | ( att [ 2 ] ! = ' l ' ) | |
( att [ 3 ] ! = ' n ' ) | | ( att [ 4 ] ! = ' s ' ) )
xmlSAX2AttributeInternal ( ctxt , att , value , NULL ) ;
/*
* Next ones
*/
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
}
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
/*
* If it ' s the Document root , finish the DTD validation and
* check the document root element for validity
*/
2022-01-13 19:06:14 +03:00
if ( ( ctxt - > validate ) & &
( ( ctxt - > vctxt . flags & XML_VCTXT_DTD_VALIDATED ) = = 0 ) ) {
2003-08-21 02:54:39 +04:00
int chk ;
chk = xmlValidateDtdFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
if ( chk < = 0 )
ctxt - > valid = 0 ;
if ( chk < 0 )
ctxt - > wellFormed = 0 ;
ctxt - > valid & = xmlValidateRoot ( & ctxt - > vctxt , ctxt - > myDoc ) ;
2022-01-13 19:06:14 +03:00
ctxt - > vctxt . flags | = XML_VCTXT_DTD_VALIDATED ;
2003-08-21 02:54:39 +04:00
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
}
/**
* xmlSAX2EndElement :
* @ ctx : the user data ( XML parser context )
* @ name : The element name
*
* called when the end of an element has been detected .
*/
void
xmlSAX2EndElement ( void * ctx , const xmlChar * name ATTRIBUTE_UNUSED )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2012-09-11 09:26:36 +04:00
2003-08-21 02:54:39 +04:00
ctxt - > nodemem = - 1 ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateOneElement ( & ctxt - > vctxt , ctxt - > myDoc ,
2023-09-21 02:29:40 +03:00
ctxt - > node ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
2012-09-11 09:26:36 +04:00
2003-08-21 02:54:39 +04:00
/*
* end of parsing of this node .
*/
nodePop ( ctxt ) ;
}
2024-06-16 00:57:39 +03:00
# else /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
/** DOC_DISABLE */
void
xmlSAX2StartElement ( void * ctx ATTRIBUTE_UNUSED ,
const xmlChar * fullname ATTRIBUTE_UNUSED ,
const xmlChar * * atts ATTRIBUTE_UNUSED ) {
}
void
xmlSAX2EndElement ( void * ctx ATTRIBUTE_UNUSED ,
const xmlChar * name ATTRIBUTE_UNUSED ) {
}
/** DOC_ENABLE */
2014-02-10 06:32:45 +04:00
# endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
2003-08-21 02:54:39 +04:00
2003-09-17 17:59:32 +04:00
/*
* xmlSAX2TextNode :
* @ ctxt : the parser context
* @ str : the input string
* @ len : the string length
2012-09-11 09:26:36 +04:00
*
2012-08-13 08:41:33 +04:00
* Callback for a text node
2003-09-17 17:59:32 +04:00
*
* Returns the newly allocated string or NULL if not needed or error
*/
static xmlNodePtr
xmlSAX2TextNode ( xmlParserCtxtPtr ctxt , const xmlChar * str , int len ) {
xmlNodePtr ret ;
2003-09-25 01:23:56 +04:00
const xmlChar * intern = NULL ;
2003-09-17 17:59:32 +04:00
2003-09-25 01:23:56 +04:00
/*
* Allocate
*/
2003-09-17 17:59:32 +04:00
if ( ctxt - > freeElems ! = NULL ) {
ret = ctxt - > freeElems ;
ctxt - > freeElems = ret - > next ;
ctxt - > freeElemsNr - - ;
} else {
2003-09-25 01:23:56 +04:00
ret = ( xmlNodePtr ) xmlMalloc ( sizeof ( xmlNode ) ) ;
2003-09-17 17:59:32 +04:00
}
if ( ret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlCtxtErrMemory ( ctxt ) ;
2003-09-17 17:59:32 +04:00
return ( NULL ) ;
}
2005-08-25 17:19:21 +04:00
memset ( ret , 0 , sizeof ( xmlNode ) ) ;
2003-09-25 01:23:56 +04:00
/*
* intern the formatting blanks found between tags , or the
* very short strings
*/
if ( ctxt - > dictNames ) {
xmlChar cur = str [ len ] ;
2005-08-25 17:19:21 +04:00
if ( ( len < ( int ) ( 2 * sizeof ( void * ) ) ) & &
( ctxt - > options & XML_PARSE_COMPACT ) ) {
2012-08-13 08:41:33 +04:00
/* store the string in the node overriding properties and nsDef */
2005-08-25 17:19:21 +04:00
xmlChar * tmp = ( xmlChar * ) & ( ret - > properties ) ;
memcpy ( tmp , str , len ) ;
tmp [ len ] = 0 ;
intern = tmp ;
} else if ( ( len < = 3 ) & & ( ( cur = = ' " ' ) | | ( cur = = ' \' ' ) | |
2003-09-26 17:53:14 +04:00
( ( cur = = ' < ' ) & & ( str [ len + 1 ] ! = ' ! ' ) ) ) ) {
2003-09-25 01:23:56 +04:00
intern = xmlDictLookup ( ctxt - > dict , str , len ) ;
2023-12-10 20:10:42 +03:00
if ( intern = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
2003-10-18 20:20:14 +04:00
} else if ( IS_BLANK_CH ( * str ) & & ( len < 60 ) & & ( cur = = ' < ' ) & &
2003-09-26 17:53:14 +04:00
( str [ len + 1 ] ! = ' ! ' ) ) {
2003-09-25 01:23:56 +04:00
int i ;
for ( i = 1 ; i < len ; i + + ) {
2004-01-02 13:42:01 +03:00
if ( ! IS_BLANK_CH ( str [ i ] ) ) goto skip ;
2003-09-25 01:23:56 +04:00
}
intern = xmlDictLookup ( ctxt - > dict , str , len ) ;
2023-12-10 20:10:42 +03:00
if ( intern = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
2003-09-25 01:23:56 +04:00
}
}
skip :
ret - > type = XML_TEXT_NODE ;
ret - > name = xmlStringText ;
2004-07-28 11:40:12 +04:00
if ( intern = = NULL ) {
2003-09-25 01:23:56 +04:00
ret - > content = xmlStrndup ( str , len ) ;
2004-07-28 11:40:12 +04:00
if ( ret - > content = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2004-07-29 11:07:16 +04:00
xmlFree ( ret ) ;
2004-07-28 11:40:12 +04:00
return ( NULL ) ;
}
} else
2003-09-25 01:23:56 +04:00
ret - > content = ( xmlChar * ) intern ;
if ( ( __xmlRegisterCallbacks ) & & ( xmlRegisterNodeDefaultValue ) )
xmlRegisterNodeDefaultValue ( ret ) ;
2003-09-17 17:59:32 +04:00
return ( ret ) ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
/*
* xmlSAX2DecodeAttrEntities :
* @ ctxt : the parser context
* @ str : the input string
* @ len : the string length
2012-09-11 09:26:36 +04:00
*
2003-09-10 14:50:59 +04:00
* Remove the entities from an attribute value
*
* Returns the newly allocated string or NULL if not needed or error
*/
static xmlChar *
xmlSAX2DecodeAttrEntities ( xmlParserCtxtPtr ctxt , const xmlChar * str ,
const xmlChar * end ) {
const xmlChar * in ;
in = str ;
while ( in < end )
if ( * in + + = = ' & ' )
goto decode ;
return ( NULL ) ;
decode :
2023-12-30 04:50:34 +03:00
/*
* If the value contains ' & ' , we can be sure it was allocated and is
* zero - terminated .
*/
/* TODO: normalize if needed */
return ( xmlExpandEntitiesInAttValue ( ctxt , str , /* normalize */ 0 ) ) ;
2003-09-10 14:50:59 +04:00
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
/**
* xmlSAX2AttributeNs :
* @ ctx : the user data ( XML parser context )
2003-09-15 16:56:36 +04:00
* @ localname : the local name of the attribute
* @ prefix : the attribute namespace prefix if available
* @ URI : the attribute namespace name if available
2003-09-10 14:50:59 +04:00
* @ value : Start of the attribute value
* @ valueend : end of the attribute value
*
* Handle an attribute that has been read by the parser .
* The default handling is to convert the attribute into an
* DOM subtree and past it in a new xmlAttr element added to
* the element .
2023-11-04 22:21:54 +03:00
*
* Returns the new attribute or NULL in case of error .
2003-09-10 14:50:59 +04:00
*/
2023-11-04 22:21:54 +03:00
static xmlAttrPtr
2003-09-10 14:50:59 +04:00
xmlSAX2AttributeNs ( xmlParserCtxtPtr ctxt ,
const xmlChar * localname ,
const xmlChar * prefix ,
const xmlChar * value ,
const xmlChar * valueend )
{
xmlAttrPtr ret ;
xmlNsPtr namespace = NULL ;
xmlChar * dup = NULL ;
/*
* Note : if prefix = = NULL , the attribute is not in the default namespace
*/
2023-09-29 01:18:44 +03:00
if ( prefix ! = NULL ) {
namespace = xmlParserNsLookupSax ( ctxt , prefix ) ;
if ( ( namespace = = NULL ) & & ( xmlStrEqual ( prefix , BAD_CAST " xml " ) ) ) {
2024-03-17 19:16:55 +03:00
int res ;
res = xmlSearchNsSafe ( ctxt - > node , prefix , & namespace ) ;
if ( res < 0 )
xmlSAX2ErrMemory ( ctxt ) ;
2023-09-29 01:18:44 +03:00
}
}
2003-09-10 14:50:59 +04:00
2003-09-15 18:50:06 +04:00
/*
* allocate the node
*/
if ( ctxt - > freeAttrs ! = NULL ) {
ret = ctxt - > freeAttrs ;
ctxt - > freeAttrs = ret - > next ;
2003-09-17 17:59:32 +04:00
ctxt - > freeAttrsNr - - ;
2023-11-04 22:21:54 +03:00
} else {
ret = xmlMalloc ( sizeof ( * ret ) ) ;
if ( ret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-11-04 22:21:54 +03:00
return ( NULL ) ;
}
}
2003-09-15 18:50:06 +04:00
2023-11-04 22:21:54 +03:00
memset ( ret , 0 , sizeof ( xmlAttr ) ) ;
ret - > type = XML_ATTRIBUTE_NODE ;
2003-09-15 18:50:06 +04:00
2023-12-01 21:21:17 +03:00
/*
* xmlParseBalancedChunkMemoryRecover had a bug that could result in
* a mismatch between ctxt - > node - > doc and ctxt - > myDoc . We use
* ctxt - > node - > doc here , but we should somehow make sure that the
* document pointers match .
*/
/* assert(ctxt->node->doc == ctxt->myDoc); */
2023-11-04 22:21:54 +03:00
ret - > parent = ctxt - > node ;
2023-12-01 21:21:17 +03:00
ret - > doc = ctxt - > node - > doc ;
2023-11-04 22:21:54 +03:00
ret - > ns = namespace ;
2003-09-17 14:26:25 +04:00
2023-12-10 20:10:42 +03:00
if ( ctxt - > dictNames ) {
2023-11-04 22:21:54 +03:00
ret - > name = localname ;
2023-12-10 20:10:42 +03:00
} else {
2023-11-04 22:21:54 +03:00
ret - > name = xmlStrdup ( localname ) ;
2023-12-10 20:10:42 +03:00
if ( ret - > name = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
}
2003-09-17 14:26:25 +04:00
2023-11-04 22:21:54 +03:00
if ( ( __xmlRegisterCallbacks ) & & ( xmlRegisterNodeDefaultValue ) )
xmlRegisterNodeDefaultValue ( ( xmlNodePtr ) ret ) ;
2003-09-10 14:50:59 +04:00
2003-09-15 18:50:06 +04:00
if ( ( ctxt - > replaceEntities = = 0 ) & & ( ! ctxt - > html ) ) {
xmlNodePtr tmp ;
2003-09-17 17:59:32 +04:00
/*
* We know that if there is an entity reference , then
* the string has been dup ' ed and terminates with 0
* otherwise with ' or "
*/
if ( * valueend ! = 0 ) {
tmp = xmlSAX2TextNode ( ctxt , value , valueend - value ) ;
ret - > children = tmp ;
ret - > last = tmp ;
if ( tmp ! = NULL ) {
tmp - > doc = ret - > doc ;
tmp - > parent = ( xmlNodePtr ) ret ;
}
2023-12-10 20:10:42 +03:00
} else if ( valueend > value ) {
2024-03-11 17:57:14 +03:00
if ( xmlNodeParseContent ( ( xmlNodePtr ) ret , value ,
valueend - value ) < 0 )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-09-10 14:50:59 +04:00
}
2003-09-15 18:50:06 +04:00
} else if ( value ! = NULL ) {
2003-09-17 17:59:32 +04:00
xmlNodePtr tmp ;
tmp = xmlSAX2TextNode ( ctxt , value , valueend - value ) ;
ret - > children = tmp ;
ret - > last = tmp ;
if ( tmp ! = NULL ) {
tmp - > doc = ret - > doc ;
tmp - > parent = ( xmlNodePtr ) ret ;
}
2003-09-10 14:50:59 +04:00
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
if ( ( ! ctxt - > html ) & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
/*
* If we don ' t substitute entities , the validation should be
* done on a value with replaced entities anyway .
*/
if ( ! ctxt - > replaceEntities ) {
dup = xmlSAX2DecodeAttrEntities ( ctxt , value , valueend ) ;
if ( dup = = NULL ) {
2003-09-15 16:56:36 +04:00
if ( * valueend = = 0 ) {
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , value ) ;
} else {
/*
* That should already be normalized .
* cheaper to finally allocate here than duplicate
* entry points in the full validation code
*/
dup = xmlStrndup ( value , valueend - value ) ;
2023-12-10 20:10:42 +03:00
if ( dup = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-09-10 14:50:59 +04:00
2003-09-15 16:56:36 +04:00
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , dup ) ;
}
2003-09-10 14:50:59 +04:00
} else {
2003-09-15 16:56:36 +04:00
/*
* dup now contains a string of the flattened attribute
2019-09-30 18:04:54 +03:00
* content with entities substituted . Check if we need to
2003-09-15 16:56:36 +04:00
* apply an extra layer of normalization .
2003-09-10 14:50:59 +04:00
* It need to be done twice . . . it ' s an extra burden related
* to the ability to keep references in attributes
*/
2003-09-15 16:56:36 +04:00
if ( ctxt - > attsSpecial ! = NULL ) {
xmlChar * nvalnorm ;
xmlChar fn [ 50 ] ;
xmlChar * fullname ;
2012-09-11 09:26:36 +04:00
2003-09-15 16:56:36 +04:00
fullname = xmlBuildQName ( localname , prefix , fn , 50 ) ;
2024-03-22 15:03:37 +03:00
if ( fullname = = NULL ) {
xmlSAX2ErrMemory ( ctxt ) ;
} else {
2003-09-15 16:56:36 +04:00
ctxt - > vctxt . valid = 1 ;
nvalnorm = xmlValidCtxtNormalizeAttributeValue (
& ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , fullname , dup ) ;
if ( ctxt - > vctxt . valid ! = 1 )
ctxt - > valid = 0 ;
if ( ( fullname ! = fn ) & & ( fullname ! = localname ) )
xmlFree ( fullname ) ;
if ( nvalnorm ! = NULL ) {
xmlFree ( dup ) ;
dup = nvalnorm ;
}
}
2003-09-10 14:50:59 +04:00
}
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , dup ) ;
}
} else {
2003-09-10 14:50:59 +04:00
/*
2019-09-30 18:04:54 +03:00
* if entities already have been substituted , then
2003-09-10 14:50:59 +04:00
* the attribute as passed is already normalized
*/
2003-09-10 14:50:59 +04:00
dup = xmlStrndup ( value , valueend - value ) ;
2023-12-10 20:10:42 +03:00
if ( dup = = NULL )
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-09-10 14:50:59 +04:00
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , dup ) ;
}
2003-09-28 22:58:27 +04:00
} else
# endif /* LIBXML_VALID_ENABLED */
if ( ( ( ctxt - > loadsubset & XML_SKIP_IDS ) = = 0 ) & &
2022-02-08 04:42:30 +03:00
/* Don't create IDs containing entity references */
( ret - > children ! = NULL ) & &
( ret - > children - > type = = XML_TEXT_NODE ) & &
( ret - > children - > next = = NULL ) ) {
xmlChar * content = ret - > children - > content ;
2003-09-10 14:50:59 +04:00
/*
* when validating , the ID registration is done at the attribute
* validation level . Otherwise we have to do specific handling here .
*/
2005-09-03 17:28:24 +04:00
if ( ( prefix = = ctxt - > str_xml ) & &
2004-04-10 01:51:49 +04:00
( localname [ 0 ] = = ' i ' ) & & ( localname [ 1 ] = = ' d ' ) & &
( localname [ 2 ] = = 0 ) ) {
/*
* Add the xml : id value
*
* Open issue : normalization of the value .
*/
2022-02-08 04:42:30 +03:00
if ( xmlValidateNCName ( content , 1 ) ! = 0 ) {
2004-04-19 00:55:39 +04:00
xmlErrValid ( ctxt , XML_DTD_XMLID_VALUE ,
2023-12-10 20:10:42 +03:00
" xml:id : attribute value %s is not an NCName \n " ,
content , NULL ) ;
2004-04-19 00:55:39 +04:00
}
2022-02-08 04:42:30 +03:00
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , content , ret ) ;
2023-12-10 20:10:42 +03:00
} else {
int res = xmlIsID ( ctxt - > myDoc , ctxt - > node , ret ) ;
if ( res < 0 )
2023-12-18 21:31:29 +03:00
xmlCtxtErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
else if ( res > 0 )
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , content , ret ) ;
else if ( xmlIsRef ( ctxt - > myDoc , ctxt - > node , ret ) )
xmlAddRef ( & ctxt - > vctxt , ctxt - > myDoc , content , ret ) ;
2004-04-10 01:51:49 +04:00
}
2003-09-10 14:50:59 +04:00
}
if ( dup ! = NULL )
xmlFree ( dup ) ;
2023-11-04 22:21:54 +03:00
return ( ret ) ;
2003-09-10 14:50:59 +04:00
}
/**
* xmlSAX2StartElementNs :
* @ ctx : the user data ( XML parser context )
* @ localname : the local name of the element
* @ prefix : the element namespace prefix if available
* @ URI : the element namespace name if available
* @ nb_namespaces : number of namespace definitions on that node
* @ namespaces : pointer to the array of prefix / URI pairs namespace definitions
* @ nb_attributes : the number of attributes on that node
2003-09-25 16:18:34 +04:00
* @ nb_defaulted : the number of defaulted attributes .
2003-09-10 14:50:59 +04:00
* @ attributes : pointer to the array of ( localname / prefix / URI / value / end )
* attribute values .
*
* SAX2 callback when an element start has been detected by the parser .
2020-03-08 19:19:42 +03:00
* It provides the namespace information for the element , as well as
2003-09-10 14:50:59 +04:00
* the new namespace declarations on the element .
*/
void
xmlSAX2StartElementNs ( void * ctx ,
const xmlChar * localname ,
const xmlChar * prefix ,
const xmlChar * URI ,
int nb_namespaces ,
const xmlChar * * namespaces ,
int nb_attributes ,
int nb_defaulted ,
const xmlChar * * attributes )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
xmlNsPtr last = NULL , ns ;
const xmlChar * uri , * pref ;
2012-01-26 15:11:02 +04:00
xmlChar * lname = NULL ;
2003-09-10 14:50:59 +04:00
int i , j ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-09-10 14:50:59 +04:00
/*
* First check on validity :
*/
2012-09-11 09:26:36 +04:00
if ( ctxt - > validate & & ( ctxt - > myDoc - > extSubset = = NULL ) & &
2003-09-10 14:50:59 +04:00
( ( ctxt - > myDoc - > intSubset = = NULL ) | |
2012-09-11 09:26:36 +04:00
( ( ctxt - > myDoc - > intSubset - > notations = = NULL ) & &
2003-09-10 14:50:59 +04:00
( ctxt - > myDoc - > intSubset - > elements = = NULL ) & &
2012-09-11 09:26:36 +04:00
( ctxt - > myDoc - > intSubset - > attributes = = NULL ) & &
2003-09-10 14:50:59 +04:00
( ctxt - > myDoc - > intSubset - > entities = = NULL ) ) ) ) {
2012-10-25 11:33:59 +04:00
xmlErrValid ( ctxt , XML_DTD_NO_DTD ,
2003-12-08 13:25:02 +03:00
" Validation failed: no DTD found ! " , NULL , NULL ) ;
2003-09-10 14:50:59 +04:00
ctxt - > validate = 0 ;
}
2012-01-26 15:11:02 +04:00
/*
* Take care of the rare case of an undefined namespace prefix
*/
if ( ( prefix ! = NULL ) & & ( URI = = NULL ) ) {
if ( ctxt - > dictNames ) {
const xmlChar * fullname ;
fullname = xmlDictQLookup ( ctxt - > dict , prefix , localname ) ;
2023-12-10 20:10:42 +03:00
if ( fullname = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
localname = fullname ;
2012-01-26 15:11:02 +04:00
} else {
lname = xmlBuildQName ( localname , prefix , NULL , 0 ) ;
2023-12-10 20:10:42 +03:00
if ( lname = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
2012-01-26 15:11:02 +04:00
}
}
2003-09-15 18:50:06 +04:00
/*
* allocate the node
*/
if ( ctxt - > freeElems ! = NULL ) {
ret = ctxt - > freeElems ;
ctxt - > freeElems = ret - > next ;
2003-09-17 17:59:32 +04:00
ctxt - > freeElemsNr - - ;
2003-09-15 18:50:06 +04:00
memset ( ret , 0 , sizeof ( xmlNode ) ) ;
2018-11-22 16:28:58 +03:00
ret - > doc = ctxt - > myDoc ;
2003-09-15 18:50:06 +04:00
ret - > type = XML_ELEMENT_NODE ;
if ( ctxt - > dictNames )
ret - > name = localname ;
2004-07-28 11:40:12 +04:00
else {
2012-01-26 15:11:02 +04:00
if ( lname = = NULL )
ret - > name = xmlStrdup ( localname ) ;
else
ret - > name = lname ;
2004-07-28 11:40:12 +04:00
if ( ret - > name = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-02-14 20:10:14 +03:00
xmlFree ( ret ) ;
2004-07-28 11:40:12 +04:00
return ;
}
}
2003-09-15 18:50:06 +04:00
if ( ( __xmlRegisterCallbacks ) & & ( xmlRegisterNodeDefaultValue ) )
xmlRegisterNodeDefaultValue ( ret ) ;
} else {
if ( ctxt - > dictNames )
2012-09-11 09:26:36 +04:00
ret = xmlNewDocNodeEatName ( ctxt - > myDoc , NULL ,
2003-09-15 18:50:06 +04:00
( xmlChar * ) localname , NULL ) ;
2012-01-26 15:11:02 +04:00
else if ( lname = = NULL )
2003-09-15 18:50:06 +04:00
ret = xmlNewDocNode ( ctxt - > myDoc , NULL , localname , NULL ) ;
2012-01-26 15:11:02 +04:00
else
2012-09-11 09:26:36 +04:00
ret = xmlNewDocNodeEatName ( ctxt - > myDoc , NULL ,
2012-01-26 15:11:02 +04:00
( xmlChar * ) lname , NULL ) ;
2003-09-15 18:50:06 +04:00
if ( ret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-09-15 18:50:06 +04:00
return ;
}
2003-09-10 14:50:59 +04:00
}
2003-09-15 18:50:06 +04:00
2003-09-10 14:50:59 +04:00
/*
* Build the namespace list
*/
for ( i = 0 , j = 0 ; j < nb_namespaces ; j + + ) {
pref = namespaces [ i + + ] ;
uri = namespaces [ i + + ] ;
ns = xmlNewNs ( NULL , uri , pref ) ;
if ( ns ! = NULL ) {
if ( last = = NULL ) {
ret - > nsDef = last = ns ;
} else {
last - > next = ns ;
last = ns ;
}
if ( ( URI ! = NULL ) & & ( prefix = = pref ) )
ret - > ns = ns ;
} else {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2010-09-09 20:17:47 +04:00
continue ;
2003-09-10 14:50:59 +04:00
}
2023-09-29 01:18:44 +03:00
xmlParserNsUpdateSax ( ctxt , pref , ns ) ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-19 02:03:46 +04:00
if ( ( ! ctxt - > html ) & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
ctxt - > valid & = xmlValidateOneNamespace ( & ctxt - > vctxt , ctxt - > myDoc ,
ret , prefix , ns , uri ) ;
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
}
ctxt - > nodemem = - 1 ;
2024-03-28 17:42:02 +03:00
/*
* Link the child element
*/
xmlSAX2AppendChild ( ctxt , ret ) ;
2023-08-27 17:35:23 +03:00
2003-09-10 14:50:59 +04:00
/*
* We are parsing a new node .
*/
2018-09-12 14:42:27 +03:00
if ( nodePush ( ctxt , ret ) < 0 ) {
2018-09-22 16:41:01 +03:00
xmlUnlinkNode ( ret ) ;
2018-09-12 14:42:27 +03:00
xmlFreeNode ( ret ) ;
return ;
}
2003-09-10 14:50:59 +04:00
/*
* Insert the defaulted attributes from the DTD only if requested :
*/
if ( ( nb_defaulted ! = 0 ) & &
( ( ctxt - > loadsubset & XML_COMPLETE_ATTRS ) = = 0 ) )
nb_attributes - = nb_defaulted ;
/*
* Search the namespace if it wasn ' t already found
2004-08-31 10:47:17 +04:00
* Note that , if prefix is NULL , this searches for the default Ns
2003-09-10 14:50:59 +04:00
*/
if ( ( URI ! = NULL ) & & ( ret - > ns = = NULL ) ) {
2023-09-29 01:18:44 +03:00
ret - > ns = xmlParserNsLookupSax ( ctxt , prefix ) ;
2006-01-04 17:03:10 +03:00
if ( ( ret - > ns = = NULL ) & & ( xmlStrEqual ( prefix , BAD_CAST " xml " ) ) ) {
2024-03-17 19:16:55 +03:00
int res ;
res = xmlSearchNsSafe ( ret , prefix , & ret - > ns ) ;
if ( res < 0 )
xmlSAX2ErrMemory ( ctxt ) ;
2006-01-04 17:03:10 +03:00
}
2003-09-10 14:50:59 +04:00
if ( ret - > ns = = NULL ) {
ns = xmlNewNs ( ret , NULL , prefix ) ;
2004-07-28 11:40:12 +04:00
if ( ns = = NULL ) {
2006-01-04 17:03:10 +03:00
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2004-07-28 11:40:12 +04:00
return ;
}
2009-08-26 17:57:20 +04:00
if ( prefix ! = NULL )
xmlNsWarnMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
" Namespace prefix %s was not found \n " ,
prefix , NULL ) ;
else
xmlNsWarnMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
" Namespace default prefix was not found \n " ,
NULL , NULL ) ;
2003-09-10 14:50:59 +04:00
}
}
/*
* process all the other attributes
*/
if ( nb_attributes > 0 ) {
2023-11-04 22:21:54 +03:00
xmlAttrPtr prev = NULL ;
2003-09-10 14:50:59 +04:00
for ( j = 0 , i = 0 ; i < nb_attributes ; i + + , j + = 5 ) {
2023-11-04 22:21:54 +03:00
xmlAttrPtr attr = NULL ;
2012-01-26 15:43:06 +04:00
/*
2019-09-30 18:04:54 +03:00
* Handle the rare case of an undefined attribute prefix
2012-01-26 15:43:06 +04:00
*/
if ( ( attributes [ j + 1 ] ! = NULL ) & & ( attributes [ j + 2 ] = = NULL ) ) {
if ( ctxt - > dictNames ) {
const xmlChar * fullname ;
fullname = xmlDictQLookup ( ctxt - > dict , attributes [ j + 1 ] ,
attributes [ j ] ) ;
2023-12-10 20:10:42 +03:00
if ( fullname = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
attr = xmlSAX2AttributeNs ( ctxt , fullname , NULL ,
attributes [ j + 3 ] ,
attributes [ j + 4 ] ) ;
goto have_attr ;
2012-01-26 15:43:06 +04:00
} else {
lname = xmlBuildQName ( attributes [ j ] , attributes [ j + 1 ] ,
NULL , 0 ) ;
2023-12-10 20:10:42 +03:00
if ( lname = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
attr = xmlSAX2AttributeNs ( ctxt , lname , NULL ,
attributes [ j + 3 ] ,
attributes [ j + 4 ] ) ;
xmlFree ( lname ) ;
goto have_attr ;
2012-01-26 15:43:06 +04:00
}
}
2023-11-04 22:21:54 +03:00
attr = xmlSAX2AttributeNs ( ctxt , attributes [ j ] , attributes [ j + 1 ] ,
attributes [ j + 3 ] , attributes [ j + 4 ] ) ;
have_attr :
if ( attr = = NULL )
continue ;
/* link at the end to preserve order */
if ( prev = = NULL ) {
ctxt - > node - > properties = attr ;
} else {
prev - > next = attr ;
attr - > prev = prev ;
}
prev = attr ;
2003-09-10 14:50:59 +04:00
}
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
/*
* If it ' s the Document root , finish the DTD validation and
* check the document root element for validity
*/
2022-01-13 19:06:14 +03:00
if ( ( ctxt - > validate ) & &
( ( ctxt - > vctxt . flags & XML_VCTXT_DTD_VALIDATED ) = = 0 ) ) {
2003-09-10 14:50:59 +04:00
int chk ;
chk = xmlValidateDtdFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
if ( chk < = 0 )
ctxt - > valid = 0 ;
if ( chk < 0 )
ctxt - > wellFormed = 0 ;
ctxt - > valid & = xmlValidateRoot ( & ctxt - > vctxt , ctxt - > myDoc ) ;
2022-01-13 19:06:14 +03:00
ctxt - > vctxt . flags | = XML_VCTXT_DTD_VALIDATED ;
2003-09-10 14:50:59 +04:00
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
}
/**
* xmlSAX2EndElementNs :
* @ ctx : the user data ( XML parser context )
* @ localname : the local name of the element
* @ prefix : the element namespace prefix if available
* @ URI : the element namespace name if available
*
* SAX2 callback when an element end has been detected by the parser .
2020-03-08 19:19:42 +03:00
* It provides the namespace information for the element .
2003-09-10 14:50:59 +04:00
*/
void
xmlSAX2EndElementNs ( void * ctx ,
const xmlChar * localname ATTRIBUTE_UNUSED ,
const xmlChar * prefix ATTRIBUTE_UNUSED ,
const xmlChar * URI ATTRIBUTE_UNUSED )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-09-10 14:50:59 +04:00
ctxt - > nodemem = - 1 ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
2023-04-20 13:35:21 +03:00
ctxt - > valid & = xmlValidateOneElement ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
/*
* end of parsing of this node .
*/
nodePop ( ctxt ) ;
}
2003-08-21 02:54:39 +04:00
/**
* xmlSAX2Reference :
* @ ctx : the user data ( XML parser context )
* @ name : The entity name
*
2012-09-11 09:26:36 +04:00
* called when an entity xmlSAX2Reference is detected .
2003-08-21 02:54:39 +04:00
*/
void
xmlSAX2Reference ( void * ctx , const xmlChar * name )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2023-08-08 16:19:44 +03:00
ret = xmlNewReference ( ctxt - > myDoc , name ) ;
2023-12-10 20:10:42 +03:00
if ( ret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
2024-03-28 17:42:02 +03:00
xmlSAX2AppendChild ( ctxt , ret ) ;
2003-08-21 02:54:39 +04:00
}
/**
2021-02-03 15:48:40 +03:00
* xmlSAX2Text :
2003-08-21 02:54:39 +04:00
* @ ctx : the user data ( XML parser context )
* @ ch : a xmlChar string
* @ len : the number of xmlChar
2021-02-03 15:48:40 +03:00
* @ type : text or cdata
2003-08-21 02:54:39 +04:00
*
2021-02-03 15:48:40 +03:00
* Append characters .
2003-08-21 02:54:39 +04:00
*/
2021-02-03 15:48:40 +03:00
static void
xmlSAX2Text ( xmlParserCtxtPtr ctxt , const xmlChar * ch , int len ,
xmlElementType type )
2003-08-21 02:54:39 +04:00
{
xmlNodePtr lastChild ;
2021-02-03 15:48:40 +03:00
if ( ctxt = = NULL ) return ;
2003-08-21 02:54:39 +04:00
/*
* Handle the data if any . If there is no child
* add it as content , otherwise if the last child is text ,
* concatenate it , else create a new node of type text .
*/
if ( ctxt - > node = = NULL ) {
return ;
}
2003-09-17 17:59:32 +04:00
lastChild = ctxt - > node - > last ;
2003-08-21 02:54:39 +04:00
/*
* Here we needed an accelerator mechanism in case of very large
* elements . Use an attribute in the structure ! ! !
*/
if ( lastChild = = NULL ) {
2021-02-03 15:48:40 +03:00
if ( type = = XML_TEXT_NODE )
lastChild = xmlSAX2TextNode ( ctxt , ch , len ) ;
else
lastChild = xmlNewCDataBlock ( ctxt - > myDoc , ch , len ) ;
2003-09-17 17:59:32 +04:00
if ( lastChild ! = NULL ) {
ctxt - > node - > children = lastChild ;
ctxt - > node - > last = lastChild ;
lastChild - > parent = ctxt - > node ;
lastChild - > doc = ctxt - > node - > doc ;
2003-08-21 02:54:39 +04:00
ctxt - > nodelen = len ;
ctxt - > nodemem = len + 1 ;
2004-07-31 20:24:01 +04:00
} else {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2004-07-31 20:24:01 +04:00
return ;
2003-08-21 02:54:39 +04:00
}
} else {
int coalesceText = ( lastChild ! = NULL ) & &
2021-02-03 15:48:40 +03:00
( lastChild - > type = = type ) & &
( ( type ! = XML_TEXT_NODE ) | |
( lastChild - > name = = xmlStringText ) ) ;
2003-08-21 02:54:39 +04:00
if ( ( coalesceText ) & & ( ctxt - > nodemem ! = 0 ) ) {
2024-01-02 19:23:59 +03:00
int maxLength = ( ctxt - > options & XML_PARSE_HUGE ) ?
XML_MAX_HUGE_LENGTH :
XML_MAX_TEXT_LENGTH ;
2003-08-21 02:54:39 +04:00
/*
* The whole point of maintaining nodelen and nodemem ,
* xmlTextConcat is too costly , i . e . compute length ,
* reallocate a new buffer , move data , append ch . Here
2019-09-30 18:04:54 +03:00
* We try to minimize realloc ( ) uses and avoid copying
2003-08-21 02:54:39 +04:00
* and recomputing length over and over .
*/
2005-08-25 17:19:21 +04:00
if ( lastChild - > content = = ( xmlChar * ) & ( lastChild - > properties ) ) {
lastChild - > content = xmlStrdup ( lastChild - > content ) ;
lastChild - > properties = NULL ;
} else if ( ( ctxt - > nodemem = = ctxt - > nodelen + 1 ) & &
( xmlDictOwns ( ctxt - > dict , lastChild - > content ) ) ) {
2003-10-10 23:36:36 +04:00
lastChild - > content = xmlStrdup ( lastChild - > content ) ;
}
2014-06-13 10:45:20 +04:00
if ( lastChild - > content = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2014-07-14 16:29:34 +04:00
return ;
2014-06-13 10:45:20 +04:00
}
2024-01-02 19:23:59 +03:00
if ( ( len > maxLength ) | | ( ctxt - > nodelen > maxLength - len ) ) {
2023-12-28 21:05:51 +03:00
xmlFatalErr ( ctxt , XML_ERR_RESOURCE_LIMIT ,
" Text node too long, try XML_PARSE_HUGE " ) ;
xmlHaltParser ( ctxt ) ;
2009-01-18 17:08:36 +03:00
return ;
}
2003-08-21 02:54:39 +04:00
if ( ctxt - > nodelen + len > = ctxt - > nodemem ) {
xmlChar * newbuf ;
2022-09-01 03:33:16 +03:00
int size ;
2003-08-21 02:54:39 +04:00
2022-09-01 03:33:16 +03:00
size = ctxt - > nodemem > INT_MAX - len ?
INT_MAX :
ctxt - > nodemem + len ;
size = size > INT_MAX / 2 ? INT_MAX : size * 2 ;
2003-08-21 02:54:39 +04:00
newbuf = ( xmlChar * ) xmlRealloc ( lastChild - > content , size ) ;
if ( newbuf = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
return ;
}
ctxt - > nodemem = size ;
lastChild - > content = newbuf ;
}
memcpy ( & lastChild - > content [ ctxt - > nodelen ] , ch , len ) ;
ctxt - > nodelen + = len ;
lastChild - > content [ ctxt - > nodelen ] = 0 ;
} else if ( coalesceText ) {
if ( xmlTextConcat ( lastChild , ch , len ) ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2003-08-21 02:54:39 +04:00
}
if ( ctxt - > node - > children ! = NULL ) {
ctxt - > nodelen = xmlStrlen ( lastChild - > content ) ;
ctxt - > nodemem = ctxt - > nodelen + 1 ;
}
} else {
/* Mixed content, first time */
2022-05-21 00:28:25 +03:00
if ( type = = XML_TEXT_NODE ) {
2021-02-03 15:48:40 +03:00
lastChild = xmlSAX2TextNode ( ctxt , ch , len ) ;
2023-01-22 13:28:46 +03:00
if ( lastChild ! = NULL )
lastChild - > doc = ctxt - > myDoc ;
2022-05-21 00:28:25 +03:00
} else
2021-02-03 15:48:40 +03:00
lastChild = xmlNewCDataBlock ( ctxt - > myDoc , ch , len ) ;
2023-12-10 20:10:42 +03:00
if ( lastChild = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
} else {
2024-03-28 17:42:02 +03:00
xmlSAX2AppendChild ( ctxt , lastChild ) ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > node - > children ! = NULL ) {
ctxt - > nodelen = len ;
ctxt - > nodemem = len + 1 ;
}
}
}
}
2023-08-09 17:52:02 +03:00
if ( ( lastChild ! = NULL ) & &
( type = = XML_TEXT_NODE ) & &
( ctxt - > linenumbers ) & &
( ctxt - > input ! = NULL ) ) {
if ( ( unsigned ) ctxt - > input - > line < ( unsigned ) USHRT_MAX )
lastChild - > line = ctxt - > input - > line ;
else {
lastChild - > line = USHRT_MAX ;
if ( ctxt - > options & XML_PARSE_BIG_LINES )
lastChild - > psvi = ( void * ) ( ptrdiff_t ) ctxt - > input - > line ;
}
}
2003-08-21 02:54:39 +04:00
}
2021-02-03 15:48:40 +03:00
/**
* xmlSAX2Characters :
* @ ctx : the user data ( XML parser context )
* @ ch : a xmlChar string
* @ len : the number of xmlChar
*
* receiving some chars from the parser .
*/
void
xmlSAX2Characters ( void * ctx , const xmlChar * ch , int len )
{
xmlSAX2Text ( ( xmlParserCtxtPtr ) ctx , ch , len , XML_TEXT_NODE ) ;
}
2003-08-21 02:54:39 +04:00
/**
* xmlSAX2IgnorableWhitespace :
* @ ctx : the user data ( XML parser context )
* @ ch : a xmlChar string
* @ len : the number of xmlChar
*
* receiving some ignorable whitespaces from the parser .
* UNUSED : by default the DOM building will use xmlSAX2Characters
*/
void
xmlSAX2IgnorableWhitespace ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * ch ATTRIBUTE_UNUSED , int len ATTRIBUTE_UNUSED )
{
}
/**
* xmlSAX2ProcessingInstruction :
* @ ctx : the user data ( XML parser context )
* @ target : the target name
* @ data : the PI data ' s
*
* A processing instruction has been parsed .
*/
void
xmlSAX2ProcessingInstruction ( void * ctx , const xmlChar * target ,
const xmlChar * data )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
2004-10-26 20:06:51 +04:00
ret = xmlNewDocPI ( ctxt - > myDoc , target , data ) ;
2023-12-10 20:10:42 +03:00
if ( ret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
2003-08-21 02:54:39 +04:00
2024-03-28 17:42:02 +03:00
xmlSAX2AppendChild ( ctxt , ret ) ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2Comment :
* @ ctx : the user data ( XML parser context )
* @ value : the xmlSAX2Comment content
*
* A xmlSAX2Comment has been parsed .
*/
void
xmlSAX2Comment ( void * ctx , const xmlChar * value )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2024-03-28 17:42:02 +03:00
2003-08-21 02:54:39 +04:00
ret = xmlNewDocComment ( ctxt - > myDoc , value ) ;
2023-12-10 20:10:42 +03:00
if ( ret = = NULL ) {
2023-12-18 21:31:29 +03:00
xmlSAX2ErrMemory ( ctxt ) ;
2023-12-10 20:10:42 +03:00
return ;
}
2003-08-21 02:54:39 +04:00
2024-03-28 17:42:02 +03:00
xmlSAX2AppendChild ( ctxt , ret ) ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2CDataBlock :
* @ ctx : the user data ( XML parser context )
* @ value : The pcdata content
* @ len : the block length
*
* called when a pcdata block has been parsed
*/
void
xmlSAX2CDataBlock ( void * ctx , const xmlChar * value , int len )
{
2021-02-03 15:48:40 +03:00
xmlSAX2Text ( ( xmlParserCtxtPtr ) ctx , value , len , XML_CDATA_SECTION_NODE ) ;
2003-08-21 02:54:39 +04:00
}
2003-09-15 16:56:36 +04:00
static int xmlSAX2DefaultVersionValue = 2 ;
2003-09-10 14:50:59 +04:00
2003-09-30 04:43:48 +04:00
# ifdef LIBXML_SAX1_ENABLED
2003-08-21 02:54:39 +04:00
/**
2003-09-10 14:50:59 +04:00
* xmlSAXDefaultVersion :
* @ version : the version , 1 or 2
2003-08-21 02:54:39 +04:00
*
2022-08-24 06:25:37 +03:00
* DEPRECATED : Use parser option XML_PARSE_SAX1 .
*
2003-09-10 14:50:59 +04:00
* Set the default version of SAX used globally by the library .
2004-06-30 15:48:47 +04:00
* By default , during initialization the default is set to 2.
* Note that it is generally a better coding style to use
* xmlSAXVersion ( ) to set up the version explicitly for a given
* parsing context .
2003-09-10 14:50:59 +04:00
*
* Returns the previous value in case of success and - 1 in case of error .
2003-08-21 02:54:39 +04:00
*/
2003-09-10 14:50:59 +04:00
int
xmlSAXDefaultVersion ( int version )
2003-08-21 02:54:39 +04:00
{
2003-09-10 14:50:59 +04:00
int ret = xmlSAX2DefaultVersionValue ;
if ( ( version ! = 1 ) & & ( version ! = 2 ) )
return ( - 1 ) ;
xmlSAX2DefaultVersionValue = version ;
return ( ret ) ;
}
2003-09-30 04:43:48 +04:00
# endif /* LIBXML_SAX1_ENABLED */
2003-08-21 02:54:39 +04:00
2003-09-10 14:50:59 +04:00
/**
* xmlSAXVersion :
* @ hdlr : the SAX handler
* @ version : the version , 1 or 2
*
* Initialize the default XML SAX handler according to the version
*
* Returns 0 in case of success and - 1 in case of error .
*/
int
xmlSAXVersion ( xmlSAXHandler * hdlr , int version )
{
if ( hdlr = = NULL ) return ( - 1 ) ;
2003-09-30 04:43:48 +04:00
if ( version = = 2 ) {
2003-09-10 14:50:59 +04:00
hdlr - > startElementNs = xmlSAX2StartElementNs ;
hdlr - > endElementNs = xmlSAX2EndElementNs ;
2003-10-10 18:46:54 +04:00
hdlr - > serror = NULL ;
2003-09-25 18:29:29 +04:00
hdlr - > initialized = XML_SAX2_MAGIC ;
2003-09-30 04:43:48 +04:00
# ifdef LIBXML_SAX1_ENABLED
} else if ( version = = 1 ) {
hdlr - > initialized = 1 ;
# endif /* LIBXML_SAX1_ENABLED */
2003-09-10 14:50:59 +04:00
} else
return ( - 1 ) ;
2023-05-08 18:58:02 +03:00
# ifdef LIBXML_SAX1_ENABLED
hdlr - > startElement = xmlSAX2StartElement ;
hdlr - > endElement = xmlSAX2EndElement ;
# else
hdlr - > startElement = NULL ;
hdlr - > endElement = NULL ;
# endif /* LIBXML_SAX1_ENABLED */
2003-08-21 02:54:39 +04:00
hdlr - > internalSubset = xmlSAX2InternalSubset ;
hdlr - > externalSubset = xmlSAX2ExternalSubset ;
hdlr - > isStandalone = xmlSAX2IsStandalone ;
hdlr - > hasInternalSubset = xmlSAX2HasInternalSubset ;
hdlr - > hasExternalSubset = xmlSAX2HasExternalSubset ;
hdlr - > resolveEntity = xmlSAX2ResolveEntity ;
hdlr - > getEntity = xmlSAX2GetEntity ;
hdlr - > getParameterEntity = xmlSAX2GetParameterEntity ;
hdlr - > entityDecl = xmlSAX2EntityDecl ;
hdlr - > attributeDecl = xmlSAX2AttributeDecl ;
hdlr - > elementDecl = xmlSAX2ElementDecl ;
hdlr - > notationDecl = xmlSAX2NotationDecl ;
hdlr - > unparsedEntityDecl = xmlSAX2UnparsedEntityDecl ;
hdlr - > setDocumentLocator = xmlSAX2SetDocumentLocator ;
hdlr - > startDocument = xmlSAX2StartDocument ;
hdlr - > endDocument = xmlSAX2EndDocument ;
hdlr - > reference = xmlSAX2Reference ;
hdlr - > characters = xmlSAX2Characters ;
hdlr - > cdataBlock = xmlSAX2CDataBlock ;
hdlr - > ignorableWhitespace = xmlSAX2Characters ;
hdlr - > processingInstruction = xmlSAX2ProcessingInstruction ;
hdlr - > comment = xmlSAX2Comment ;
2003-09-10 14:50:59 +04:00
hdlr - > warning = xmlParserWarning ;
2003-08-21 02:54:39 +04:00
hdlr - > error = xmlParserError ;
hdlr - > fatalError = xmlParserError ;
2003-09-10 14:50:59 +04:00
return ( 0 ) ;
}
/**
* xmlSAX2InitDefaultSAXHandler :
* @ hdlr : the SAX handler
* @ warning : flag if non - zero sets the handler warning procedure
*
* Initialize the default XML SAX2 handler
*/
void
xmlSAX2InitDefaultSAXHandler ( xmlSAXHandler * hdlr , int warning )
{
if ( ( hdlr = = NULL ) | | ( hdlr - > initialized ! = 0 ) )
return ;
xmlSAXVersion ( hdlr , xmlSAX2DefaultVersionValue ) ;
if ( warning = = 0 )
hdlr - > warning = NULL ;
else
hdlr - > warning = xmlParserWarning ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlDefaultSAXHandlerInit :
*
2022-11-24 18:38:47 +03:00
* DEPRECATED : This function is a no - op . Call xmlInitParser to
2022-03-06 15:55:48 +03:00
* initialize the library .
*
2003-08-21 02:54:39 +04:00
* Initialize the default SAX2 handler
*/
void
xmlDefaultSAXHandlerInit ( void )
{
}
# ifdef LIBXML_HTML_ENABLED
/**
* xmlSAX2InitHtmlDefaultSAXHandler :
* @ hdlr : the SAX handler
*
* Initialize the default HTML SAX2 handler
*/
void
xmlSAX2InitHtmlDefaultSAXHandler ( xmlSAXHandler * hdlr )
{
2004-11-08 17:02:18 +03:00
if ( ( hdlr = = NULL ) | | ( hdlr - > initialized ! = 0 ) )
2003-08-21 02:54:39 +04:00
return ;
hdlr - > internalSubset = xmlSAX2InternalSubset ;
hdlr - > externalSubset = NULL ;
hdlr - > isStandalone = NULL ;
hdlr - > hasInternalSubset = NULL ;
hdlr - > hasExternalSubset = NULL ;
hdlr - > resolveEntity = NULL ;
hdlr - > getEntity = xmlSAX2GetEntity ;
hdlr - > getParameterEntity = NULL ;
hdlr - > entityDecl = NULL ;
hdlr - > attributeDecl = NULL ;
hdlr - > elementDecl = NULL ;
hdlr - > notationDecl = NULL ;
hdlr - > unparsedEntityDecl = NULL ;
hdlr - > setDocumentLocator = xmlSAX2SetDocumentLocator ;
hdlr - > startDocument = xmlSAX2StartDocument ;
hdlr - > endDocument = xmlSAX2EndDocument ;
hdlr - > startElement = xmlSAX2StartElement ;
hdlr - > endElement = xmlSAX2EndElement ;
hdlr - > reference = NULL ;
hdlr - > characters = xmlSAX2Characters ;
hdlr - > cdataBlock = xmlSAX2CDataBlock ;
hdlr - > ignorableWhitespace = xmlSAX2IgnorableWhitespace ;
2004-10-22 18:34:23 +04:00
hdlr - > processingInstruction = xmlSAX2ProcessingInstruction ;
2003-08-21 02:54:39 +04:00
hdlr - > comment = xmlSAX2Comment ;
hdlr - > warning = xmlParserWarning ;
hdlr - > error = xmlParserError ;
hdlr - > fatalError = xmlParserError ;
2003-09-25 18:29:29 +04:00
hdlr - > initialized = 1 ;
2003-08-21 02:54:39 +04:00
}
/**
* htmlDefaultSAXHandlerInit :
*
2022-11-24 18:38:47 +03:00
* DEPRECATED : This function is a no - op . Call xmlInitParser to
2022-03-06 15:55:48 +03:00
* initialize the library .
2003-08-21 02:54:39 +04:00
*/
void
htmlDefaultSAXHandlerInit ( void )
{
}
# endif /* LIBXML_HTML_ENABLED */