2001-02-23 20:55:21 +03:00
/*
2001-12-31 19:16:02 +03:00
* parserInternals . c : Internal routines ( and obsolete ones ) needed for the
* XML and HTML parsers .
2001-02-23 20:55:21 +03:00
*
* See Copyright for the status of this software .
*
2001-06-24 16:13:24 +04:00
* daniel @ veillard . com
2001-02-23 20:55:21 +03:00
*/
2002-03-18 22:37:11 +03:00
# define IN_LIBXML
2001-04-21 20:57:29 +04:00
# include "libxml.h"
2022-03-01 00:42:10 +03:00
# if defined(_WIN32)
2001-02-23 20:55:21 +03:00
# define XML_DIR_SEP '\\'
# else
# define XML_DIR_SEP ' / '
# endif
# include <string.h>
# include <ctype.h>
# include <stdlib.h>
2022-03-02 02:29:17 +03:00
2001-02-23 20:55:21 +03:00
# include <libxml/xmlmemory.h>
# include <libxml/tree.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/entities.h>
# include <libxml/xmlerror.h>
# include <libxml/encoding.h>
# include <libxml/xmlIO.h>
# include <libxml/uri.h>
2003-08-18 16:15:38 +04:00
# include <libxml/dict.h>
2023-09-20 19:54:39 +03:00
# include <libxml/xmlsave.h>
2001-08-22 18:29:45 +04:00
# ifdef LIBXML_CATALOG_ENABLED
# include <libxml/catalog.h>
# endif
2003-10-11 19:22:13 +04:00
# include <libxml/chvalid.h>
2023-12-23 02:35:30 +03:00
# include <libxml/nanohttp.h>
2001-02-23 20:55:21 +03:00
2016-03-02 02:18:04 +03:00
# define CUR(ctxt) ctxt->input->cur
# define END(ctxt) ctxt->input->end
2022-08-26 02:22:33 +03:00
# include "private/buf.h"
# include "private/enc.h"
# include "private/error.h"
# include "private/io.h"
# include "private/parser.h"
2012-07-16 10:19:49 +04:00
2023-12-10 19:50:22 +03:00
# define XML_MAX_ERRORS 100
2023-08-20 21:48:10 +03:00
/*
* XML_MAX_AMPLIFICATION_DEFAULT is the default maximum allowed amplification
* factor of serialized output after entity expansion .
*/
# define XML_MAX_AMPLIFICATION_DEFAULT 5
2001-07-25 21:18:57 +04:00
/*
* Various global defaults for parsing
*/
2001-02-23 20:55:21 +03:00
2001-07-18 23:30:27 +04:00
/**
2001-02-23 20:55:21 +03:00
* xmlCheckVersion :
* @ version : the include version number
*
* check the compiled lib version against the include one .
*/
void
xmlCheckVersion ( int version ) {
2022-09-01 02:18:30 +03:00
int myversion = LIBXML_VERSION ;
2001-02-23 20:55:21 +03:00
2001-10-14 13:56:15 +04:00
xmlInitParser ( ) ;
2001-05-08 00:50:47 +04:00
2001-02-23 20:55:21 +03:00
if ( ( myversion / 10000 ) ! = ( version / 10000 ) ) {
2012-09-11 09:26:36 +04:00
fprintf ( stderr ,
2001-11-20 11:35:07 +03:00
" Fatal: program compiled against libxml %d using libxml %d \n " ,
( version / 10000 ) , ( myversion / 10000 ) ) ;
2023-12-18 21:31:29 +03:00
} else if ( ( myversion / 100 ) < ( version / 100 ) ) {
fprintf ( stderr ,
2001-02-23 20:55:21 +03:00
" Warning: program compiled against libxml %d using older %d \n " ,
( version / 100 ) , ( myversion / 100 ) ) ;
}
}
2003-10-06 01:33:18 +04:00
/************************************************************************
* *
2012-09-11 09:26:36 +04:00
* Some factorized error routines *
2003-10-06 01:33:18 +04:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
2023-12-18 21:31:29 +03:00
* xmlCtxtSetErrorHandler :
2003-10-06 01:33:18 +04:00
* @ ctxt : an XML parser context
2023-12-18 21:31:29 +03:00
* @ handler : error handler
* @ data : data for error handler
2003-10-06 01:33:18 +04:00
*
2023-12-21 19:30:38 +03:00
* Register a callback function that will be called on errors and
* warnings . If handler is NULL , the error handler will be deactivated .
*
* This is the recommended way to collect errors from the parser and
* takes precedence over all other error reporting mechanisms .
* These are ( in order of precedence ) :
*
* - per - context structured handler ( xmlCtxtSetErrorHandler )
* - per - context structured " serror " SAX handler
* - global structured handler ( xmlSetStructuredErrorFunc )
* - per - context generic " error " and " warning " SAX handlers
* - global generic handler ( xmlSetGenericErrorFunc )
* - print to stderr
*
* Available since 2.13 .0 .
2003-10-06 01:33:18 +04:00
*/
void
2023-12-18 21:31:29 +03:00
xmlCtxtSetErrorHandler ( xmlParserCtxtPtr ctxt , xmlStructuredErrorFunc handler ,
void * data )
2023-12-10 19:50:22 +03:00
{
2023-12-18 21:31:29 +03:00
if ( ctxt = = NULL )
return ;
ctxt - > errorHandler = handler ;
ctxt - > errorCtxt = data ;
}
2023-12-10 19:50:22 +03:00
2023-12-18 21:31:29 +03:00
/**
* xmlCtxtErrMemory :
* @ ctxt : an XML parser context
*
2024-05-20 14:58:22 +03:00
* Handle an out - of - memory error .
*
* Available since 2.13 .0 .
2023-12-18 21:31:29 +03:00
*/
void
xmlCtxtErrMemory ( xmlParserCtxtPtr ctxt )
{
xmlStructuredErrorFunc schannel = NULL ;
xmlGenericErrorFunc channel = NULL ;
void * data ;
2023-12-10 19:50:22 +03:00
2024-06-12 14:32:32 +03:00
if ( ctxt = = NULL )
return ;
2023-12-10 19:50:22 +03:00
ctxt - > errNo = XML_ERR_NO_MEMORY ;
ctxt - > instate = XML_PARSER_EOF ; /* TODO: Remove after refactoring */
ctxt - > wellFormed = 0 ;
ctxt - > disableSAX = 2 ;
2023-12-18 21:31:29 +03:00
if ( ctxt - > errorHandler ) {
schannel = ctxt - > errorHandler ;
data = ctxt - > errorCtxt ;
} else if ( ( ctxt - > sax - > initialized = = XML_SAX2_MAGIC ) & &
2023-12-10 19:50:22 +03:00
( ctxt - > sax - > serror ! = NULL ) ) {
2023-12-18 21:31:29 +03:00
schannel = ctxt - > sax - > serror ;
data = ctxt - > userData ;
2023-12-10 19:50:22 +03:00
} else {
2023-12-18 21:31:29 +03:00
channel = ctxt - > sax - > error ;
data = ctxt - > userData ;
2023-12-10 19:50:22 +03:00
}
2023-12-18 21:31:29 +03:00
xmlRaiseMemoryError ( schannel , channel , data , XML_FROM_PARSER ,
& ctxt - > lastError ) ;
2023-12-10 19:50:22 +03:00
}
2023-12-23 02:35:30 +03:00
/**
* xmlCtxtErrIO :
* @ ctxt : parser context
* @ code : xmlParserErrors code
* @ uri : filename or URI ( optional )
*
* If filename is empty , use the one from context input if available .
*
* Report an IO error to the parser context .
*/
void
xmlCtxtErrIO ( xmlParserCtxtPtr ctxt , int code , const char * uri )
{
const char * errstr , * msg , * str1 , * str2 ;
xmlErrorLevel level ;
if ( ctxt = = NULL )
return ;
2024-01-22 23:02:16 +03:00
/*
2024-06-14 20:42:40 +03:00
* Only report a warning if a file could not be found . This should
* only be done for external entities , but the external entity loader
* of xsltproc can try multiple paths and assumes that ENOENT doesn ' t
* raise an error and aborts parsing .
2024-01-22 23:02:16 +03:00
*/
2024-06-14 20:42:40 +03:00
if ( ( ( code = = XML_IO_ENOENT ) | |
2024-01-22 23:02:16 +03:00
( code = = XML_IO_NETWORK_ATTEMPT ) | |
( code = = XML_IO_UNKNOWN ) ) ) {
2023-12-23 02:35:30 +03:00
if ( ctxt - > validate = = 0 )
level = XML_ERR_WARNING ;
else
level = XML_ERR_ERROR ;
} else {
level = XML_ERR_FATAL ;
}
errstr = xmlErrString ( code ) ;
if ( uri = = NULL ) {
msg = " %s \n " ;
str1 = errstr ;
str2 = NULL ;
} else {
msg = " failed to load \" %s \" : %s \n " ;
str1 = uri ;
str2 = errstr ;
}
xmlCtxtErr ( ctxt , NULL , XML_FROM_IO , code , level ,
( const xmlChar * ) uri , NULL , NULL , 0 ,
msg , str1 , str2 ) ;
}
2024-05-20 14:58:22 +03:00
/**
* xmlCtxtVErr :
* @ ctxt : a parser context
* @ node : the current node or NULL
* @ domain : the domain for the error
* @ code : the code for the error
* @ level : the xmlErrorLevel for the error
* @ str1 : extra string info
* @ str2 : extra string info
* @ str3 : extra string info
* @ int1 : extra int info
* @ msg : the message to display / transmit
* @ ap : extra parameters for the message display
*
* Raise a parser error .
*/
2023-12-10 19:50:22 +03:00
void
2023-12-20 02:33:34 +03:00
xmlCtxtVErr ( xmlParserCtxtPtr ctxt , xmlNodePtr node , xmlErrorDomain domain ,
xmlParserErrors code , xmlErrorLevel level ,
const xmlChar * str1 , const xmlChar * str2 , const xmlChar * str3 ,
int int1 , const char * msg , va_list ap )
2003-10-06 01:33:18 +04:00
{
2023-12-10 19:50:22 +03:00
xmlStructuredErrorFunc schannel = NULL ;
2023-12-18 21:31:29 +03:00
xmlGenericErrorFunc channel = NULL ;
2023-12-19 00:48:24 +03:00
void * data = NULL ;
2023-12-10 19:50:22 +03:00
const char * file = NULL ;
int line = 0 ;
int col = 0 ;
int res ;
if ( code = = XML_ERR_NO_MEMORY ) {
2023-12-20 02:33:34 +03:00
xmlCtxtErrMemory ( ctxt ) ;
2023-12-10 19:50:22 +03:00
return ;
}
2024-02-13 14:22:28 +03:00
if ( PARSER_STOPPED ( ctxt ) )
return ;
2023-12-10 19:50:22 +03:00
if ( level = = XML_ERR_WARNING ) {
if ( ctxt - > nbWarnings > = XML_MAX_ERRORS )
return ;
ctxt - > nbWarnings + = 1 ;
} else {
if ( ctxt - > nbErrors > = XML_MAX_ERRORS )
return ;
ctxt - > nbErrors + = 1 ;
}
2023-12-19 00:48:24 +03:00
if ( ( ( ctxt - > options & XML_PARSE_NOERROR ) = = 0 ) & &
( ( level ! = XML_ERR_WARNING ) | |
( ( ctxt - > options & XML_PARSE_NOWARNING ) = = 0 ) ) ) {
if ( ctxt - > errorHandler ) {
schannel = ctxt - > errorHandler ;
data = ctxt - > errorCtxt ;
} else if ( ( ctxt - > sax - > initialized = = XML_SAX2_MAGIC ) & &
( ctxt - > sax - > serror ! = NULL ) ) {
schannel = ctxt - > sax - > serror ;
data = ctxt - > userData ;
} else if ( ( domain = = XML_FROM_VALID ) | | ( domain = = XML_FROM_DTD ) ) {
if ( level = = XML_ERR_WARNING )
channel = ctxt - > vctxt . warning ;
else
channel = ctxt - > vctxt . error ;
data = ctxt - > vctxt . userData ;
} else {
if ( level = = XML_ERR_WARNING )
channel = ctxt - > sax - > warning ;
else
channel = ctxt - > sax - > error ;
data = ctxt - > userData ;
}
2023-12-10 19:50:22 +03:00
}
if ( ctxt - > input ! = NULL ) {
xmlParserInputPtr input = ctxt - > input ;
if ( ( input - > filename = = NULL ) & &
( ctxt - > inputNr > 1 ) ) {
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
}
file = input - > filename ;
line = input - > line ;
col = input - > col ;
}
res = xmlVRaiseError ( schannel , channel , data , ctxt , node , domain , code ,
level , file , line , ( const char * ) str1 ,
( const char * ) str2 , ( const char * ) str3 , int1 , col ,
msg , ap ) ;
if ( res < 0 ) {
2023-12-20 02:33:34 +03:00
xmlCtxtErrMemory ( ctxt ) ;
2023-12-10 19:50:22 +03:00
return ;
}
if ( level > = XML_ERR_ERROR )
ctxt - > errNo = code ;
if ( level = = XML_ERR_FATAL ) {
ctxt - > wellFormed = 0 ;
if ( ctxt - > recovery = = 0 )
ctxt - > disableSAX = 1 ;
}
return ;
}
2024-05-20 14:58:22 +03:00
/**
* xmlCtxtErr :
* @ ctxt : a parser context
* @ node : the current node or NULL
* @ domain : the domain for the error
* @ code : the code for the error
* @ level : the xmlErrorLevel for the error
* @ str1 : extra string info
* @ str2 : extra string info
* @ str3 : extra string info
* @ int1 : extra int info
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Raise a parser error .
*/
2023-12-10 19:50:22 +03:00
void
2023-12-20 02:33:34 +03:00
xmlCtxtErr ( xmlParserCtxtPtr ctxt , xmlNodePtr node , xmlErrorDomain domain ,
xmlParserErrors code , xmlErrorLevel level ,
const xmlChar * str1 , const xmlChar * str2 , const xmlChar * str3 ,
int int1 , const char * msg , . . . )
2023-12-10 19:50:22 +03:00
{
va_list ap ;
va_start ( ap , msg ) ;
2023-12-20 02:33:34 +03:00
xmlCtxtVErr ( ctxt , node , domain , code , level ,
str1 , str2 , str3 , int1 , msg , ap ) ;
2023-12-10 19:50:22 +03:00
va_end ( ap ) ;
2003-10-06 01:33:18 +04:00
}
2023-04-30 18:51:29 +03:00
/**
* xmlFatalErr :
* @ ctxt : an XML parser context
2024-05-20 14:58:22 +03:00
* @ code : the error number
2023-09-21 23:57:33 +03:00
* @ info : extra information string
2023-04-30 18:51:29 +03:00
*
* Handle a fatal parser error , i . e . violating Well - Formedness constraints
*/
void
2023-12-29 20:47:30 +03:00
xmlFatalErr ( xmlParserCtxtPtr ctxt , xmlParserErrors code , const char * info )
2023-04-30 18:51:29 +03:00
{
const char * errmsg ;
2023-12-29 20:47:30 +03:00
xmlErrorLevel level ;
if ( code = = XML_ERR_UNSUPPORTED_ENCODING )
level = XML_ERR_WARNING ;
else
level = XML_ERR_FATAL ;
2023-04-30 18:51:29 +03:00
2023-12-29 20:47:30 +03:00
errmsg = xmlErrString ( code ) ;
2023-12-10 19:50:22 +03:00
2023-04-30 18:51:29 +03:00
if ( info = = NULL ) {
2023-12-29 20:47:30 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_PARSER , code , level ,
2023-12-20 02:33:34 +03:00
NULL , NULL , NULL , 0 , " %s \n " , errmsg ) ;
2023-04-30 18:51:29 +03:00
} else {
2023-12-29 20:47:30 +03:00
xmlCtxtErr ( ctxt , NULL , XML_FROM_PARSER , code , level ,
2023-12-20 02:33:34 +03:00
( const xmlChar * ) info , NULL , NULL , 0 ,
" %s: %s \n " , errmsg , info ) ;
2023-04-30 18:51:29 +03:00
}
}
2001-02-23 20:55:21 +03:00
/**
* xmlIsLetter :
* @ c : an unicode character ( int )
*
* Check whether the character is allowed by the production
* [ 84 ] Letter : : = BaseChar | Ideographic
*
* Returns 0 if not , non - zero otherwise
*/
int
xmlIsLetter ( int c ) {
return ( IS_BASECHAR ( c ) | | IS_IDEOGRAPHIC ( c ) ) ;
}
/************************************************************************
* *
2012-07-16 10:19:49 +04:00
* Input handling functions for progressive parsing *
2001-02-23 20:55:21 +03:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* we need to keep enough input to show errors in context */
# define LINE_LEN 80
2023-03-14 16:42:36 +03:00
/**
* xmlHaltParser :
* @ ctxt : an XML parser context
*
* Blocks further parser processing don ' t override error
* for internal use
*/
void
xmlHaltParser ( xmlParserCtxtPtr ctxt ) {
if ( ctxt = = NULL )
return ;
2023-12-10 19:50:22 +03:00
ctxt - > instate = XML_PARSER_EOF ; /* TODO: Remove after refactoring */
ctxt - > disableSAX = 2 ;
2023-03-14 16:42:36 +03:00
}
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputRead :
* @ in : an XML parser input
* @ len : an indicative size for the lookahead
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : This function was internal and is deprecated .
2001-02-23 20:55:21 +03:00
*
2012-07-16 10:19:49 +04:00
* Returns - 1 as this is an error to use it .
2001-02-23 20:55:21 +03:00
*/
int
2012-07-16 10:19:49 +04:00
xmlParserInputRead ( xmlParserInputPtr in ATTRIBUTE_UNUSED , int len ATTRIBUTE_UNUSED ) {
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
}
2023-03-12 18:47:15 +03:00
/**
* xmlParserGrow :
* @ ctxt : an XML parser context
2023-09-21 23:57:33 +03:00
*
* Grow the input buffer .
*
* Returns the number of bytes read or - 1 in case of error .
2023-03-12 18:47:15 +03:00
*/
int
xmlParserGrow ( xmlParserCtxtPtr ctxt ) {
xmlParserInputPtr in = ctxt - > input ;
xmlParserInputBufferPtr buf = in - > buf ;
2024-01-02 19:52:43 +03:00
size_t curEnd = in - > end - in - > cur ;
size_t curBase = in - > cur - in - > base ;
size_t maxLength = ( ctxt - > options & XML_PARSE_HUGE ) ?
XML_MAX_HUGE_LENGTH :
XML_MAX_LOOKUP_LIMIT ;
2023-03-12 18:47:15 +03:00
int ret ;
if ( buf = = NULL )
return ( 0 ) ;
2023-04-12 14:43:28 +03:00
/* Don't grow push parser buffer. */
2023-12-26 05:13:05 +03:00
if ( PARSER_PROGRESSIVE ( ctxt ) )
2023-04-12 14:43:28 +03:00
return ( 0 ) ;
2023-12-13 19:25:37 +03:00
/* Don't grow memory buffers. */
if ( ( buf - > encoder = = NULL ) & & ( buf - > readcallback = = NULL ) )
return ( 0 ) ;
2023-06-07 15:05:34 +03:00
if ( buf - > error ! = 0 )
return ( - 1 ) ;
2023-03-12 18:47:15 +03:00
2024-01-02 19:52:43 +03:00
if ( curBase > maxLength ) {
2023-12-10 19:50:22 +03:00
xmlFatalErr ( ctxt , XML_ERR_RESOURCE_LIMIT ,
" Buffer size limit exceeded, try XML_PARSE_HUGE \n " ) ;
2023-03-16 19:48:57 +03:00
xmlHaltParser ( ctxt ) ;
2023-03-12 18:47:15 +03:00
return ( - 1 ) ;
}
if ( curEnd > = INPUT_CHUNK )
return ( 0 ) ;
ret = xmlParserInputBufferGrow ( buf , INPUT_CHUNK ) ;
2023-08-08 16:21:14 +03:00
xmlBufUpdateInput ( buf - > buffer , in , curBase ) ;
2023-03-12 18:47:15 +03:00
2023-06-08 22:53:05 +03:00
if ( ret < 0 ) {
2023-12-19 21:52:28 +03:00
xmlCtxtErrIO ( ctxt , buf - > error , NULL ) ;
2023-06-08 22:53:05 +03:00
}
2023-03-12 18:47:15 +03:00
return ( ret ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputGrow :
* @ in : an XML parser input
* @ len : an indicative size for the lookahead
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Don ' t use .
*
2001-02-23 20:55:21 +03:00
* This function increase the input for the parser . It tries to
* preserve pointers to the input buffer , and keep already read data
*
2012-07-16 10:19:49 +04:00
* Returns the amount of char read , or - 1 in case of error , 0 indicate the
2001-02-23 20:55:21 +03:00
* end of this entity
*/
int
xmlParserInputGrow ( xmlParserInputPtr in , int len ) {
2016-05-19 00:52:59 +03:00
int ret ;
2012-07-16 10:19:49 +04:00
size_t indx ;
2001-02-23 20:55:21 +03:00
2012-07-16 10:19:49 +04:00
if ( ( in = = NULL ) | | ( len < 0 ) ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
if ( in - > buf = = NULL ) return ( - 1 ) ;
if ( in - > base = = NULL ) return ( - 1 ) ;
if ( in - > cur = = NULL ) return ( - 1 ) ;
if ( in - > buf - > buffer = = NULL ) return ( - 1 ) ;
2023-12-13 19:25:37 +03:00
/* Don't grow memory buffers. */
if ( ( in - > buf - > encoder = = NULL ) & & ( in - > buf - > readcallback = = NULL ) )
return ( 0 ) ;
2001-03-24 20:00:36 +03:00
indx = in - > cur - in - > base ;
2012-07-16 10:19:49 +04:00
if ( xmlBufUse ( in - > buf - > buffer ) > ( unsigned int ) indx + INPUT_CHUNK ) {
2001-02-23 20:55:21 +03:00
return ( 0 ) ;
}
2022-11-13 18:56:10 +03:00
ret = xmlParserInputBufferGrow ( in - > buf , len ) ;
2001-02-23 20:55:21 +03:00
2022-03-06 04:29:00 +03:00
in - > base = xmlBufContent ( in - > buf - > buffer ) ;
2023-01-22 16:52:06 +03:00
if ( in - > base = = NULL ) {
in - > base = BAD_CAST " " ;
in - > cur = in - > base ;
in - > end = in - > base ;
return ( - 1 ) ;
}
2022-03-06 04:29:00 +03:00
in - > cur = in - > base + indx ;
2012-07-16 10:19:49 +04:00
in - > end = xmlBufEnd ( in - > buf - > buffer ) ;
2001-02-23 20:55:21 +03:00
return ( ret ) ;
}
2023-03-13 19:51:13 +03:00
/**
* xmlParserShrink :
* @ ctxt : an XML parser context
2023-09-21 23:57:33 +03:00
*
* Shrink the input buffer .
2023-03-13 19:51:13 +03:00
*/
2023-03-21 15:08:44 +03:00
void
2023-03-13 19:51:13 +03:00
xmlParserShrink ( xmlParserCtxtPtr ctxt ) {
xmlParserInputPtr in = ctxt - > input ;
xmlParserInputBufferPtr buf = in - > buf ;
size_t used ;
2023-10-22 14:59:55 +03:00
if ( buf = = NULL )
2023-03-21 15:08:44 +03:00
return ;
2023-12-13 19:25:37 +03:00
/* Don't shrink pull parser memory buffers. */
2023-12-26 05:13:05 +03:00
if ( ( ! PARSER_PROGRESSIVE ( ctxt ) ) & &
2023-12-13 19:25:37 +03:00
( buf - > encoder = = NULL ) & &
( buf - > readcallback = = NULL ) )
return ;
2023-03-13 19:51:13 +03:00
used = in - > cur - in - > base ;
/*
* Do not shrink on large buffers whose only a tiny fraction
* was consumed
*/
if ( used > INPUT_CHUNK ) {
size_t res = xmlBufShrink ( buf - > buffer , used - LINE_LEN ) ;
if ( res > 0 ) {
used - = res ;
if ( ( res > ULONG_MAX ) | |
( in - > consumed > ULONG_MAX - ( unsigned long ) res ) )
in - > consumed = ULONG_MAX ;
else
in - > consumed + = res ;
}
}
2023-08-08 16:21:14 +03:00
xmlBufUpdateInput ( buf - > buffer , in , used ) ;
2023-03-13 19:51:13 +03:00
}
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputShrink :
* @ in : an XML parser input
*
2023-03-13 21:19:46 +03:00
* DEPRECATED : Don ' t use .
*
2001-02-23 20:55:21 +03:00
* This function removes used input for the parser .
*/
void
xmlParserInputShrink ( xmlParserInputPtr in ) {
2012-07-16 10:19:49 +04:00
size_t used ;
size_t ret ;
2001-02-23 20:55:21 +03:00
2004-11-08 17:02:18 +03:00
if ( in = = NULL ) return ;
2001-02-23 20:55:21 +03:00
if ( in - > buf = = NULL ) return ;
if ( in - > base = = NULL ) return ;
if ( in - > cur = = NULL ) return ;
if ( in - > buf - > buffer = = NULL ) return ;
2022-03-06 04:29:00 +03:00
used = in - > cur - in - > base ;
2001-02-23 20:55:21 +03:00
/*
* Do not shrink on large buffers whose only a tiny fraction
2001-12-31 19:16:02 +03:00
* was consumed
2001-02-23 20:55:21 +03:00
*/
if ( used > INPUT_CHUNK ) {
2012-07-16 10:19:49 +04:00
ret = xmlBufShrink ( in - > buf - > buffer , used - LINE_LEN ) ;
2001-02-23 20:55:21 +03:00
if ( ret > 0 ) {
2022-03-06 04:29:00 +03:00
used - = ret ;
2022-11-13 22:19:13 +03:00
if ( ( ret > ULONG_MAX ) | |
( in - > consumed > ULONG_MAX - ( unsigned long ) ret ) )
in - > consumed = ULONG_MAX ;
else
in - > consumed + = ret ;
2001-02-23 20:55:21 +03:00
}
}
2022-03-06 04:29:00 +03:00
if ( xmlBufUse ( in - > buf - > buffer ) < = INPUT_CHUNK ) {
xmlParserInputBufferRead ( in - > buf , 2 * INPUT_CHUNK ) ;
2001-02-23 20:55:21 +03:00
}
2022-03-06 04:29:00 +03:00
in - > base = xmlBufContent ( in - > buf - > buffer ) ;
2023-03-13 18:51:14 +03:00
if ( in - > base = = NULL ) {
/* TODO: raise error */
in - > base = BAD_CAST " " ;
in - > cur = in - > base ;
in - > end = in - > base ;
return ;
}
2022-03-06 04:29:00 +03:00
in - > cur = in - > base + used ;
2012-07-16 10:19:49 +04:00
in - > end = xmlBufEnd ( in - > buf - > buffer ) ;
2001-02-23 20:55:21 +03:00
}
/************************************************************************
* *
2012-09-11 09:26:36 +04:00
* UTF8 character input and related functions *
2001-02-23 20:55:21 +03:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlNextChar :
* @ ctxt : the XML parser context
*
2023-03-13 21:38:41 +03:00
* DEPRECATED : Internal function , do not use .
*
2001-02-23 20:55:21 +03:00
* Skip to the next char input char .
*/
void
2003-03-22 03:04:05 +03:00
xmlNextChar ( xmlParserCtxtPtr ctxt )
{
2023-08-09 17:59:36 +03:00
const unsigned char * cur ;
size_t avail ;
int c ;
2023-12-10 19:50:22 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > input = = NULL ) )
2003-03-22 03:04:05 +03:00
return ;
2001-02-23 20:55:21 +03:00
2023-08-09 17:59:36 +03:00
avail = ctxt - > input - > end - ctxt - > input - > cur ;
2016-03-02 02:18:04 +03:00
2023-08-09 17:59:36 +03:00
if ( avail < INPUT_CHUNK ) {
2023-06-07 15:05:34 +03:00
xmlParserGrow ( ctxt ) ;
2023-12-10 19:50:22 +03:00
if ( ctxt - > input - > cur > = ctxt - > input - > end )
2023-03-15 18:18:11 +03:00
return ;
2023-08-09 17:59:36 +03:00
avail = ctxt - > input - > end - ctxt - > input - > cur ;
2016-03-02 02:18:04 +03:00
}
2023-08-09 17:59:36 +03:00
cur = ctxt - > input - > cur ;
c = * cur ;
2023-09-25 15:35:43 +03:00
2023-08-09 17:59:36 +03:00
if ( c < 0x80 ) {
if ( c = = ' \n ' ) {
ctxt - > input - > cur + + ;
2023-09-25 15:35:43 +03:00
ctxt - > input - > line + + ;
ctxt - > input - > col = 1 ;
2023-08-09 17:59:36 +03:00
} else if ( c = = ' \r ' ) {
/*
* 2.11 End - of - Line Handling
* the literal two - character sequence " #xD#xA " or a standalone
* literal # xD , an XML processor must pass to the application
* the single character # xA .
*/
ctxt - > input - > cur + = ( ( cur [ 1 ] = = ' \n ' ) ? 2 : 1 ) ;
ctxt - > input - > line + + ;
ctxt - > input - > col = 1 ;
return ;
2023-09-25 15:35:43 +03:00
} else {
2023-08-09 17:59:36 +03:00
ctxt - > input - > cur + + ;
2016-03-02 02:18:04 +03:00
ctxt - > input - > col + + ;
2023-09-25 15:35:43 +03:00
}
2023-08-09 17:59:36 +03:00
} else {
ctxt - > input - > col + + ;
2016-03-02 02:18:04 +03:00
2023-08-09 17:59:36 +03:00
if ( ( avail < 2 ) | | ( cur [ 1 ] & 0xc0 ) ! = 0x80 )
goto encoding_error ;
2023-03-15 18:18:11 +03:00
2023-08-09 17:59:36 +03:00
if ( c < 0xe0 ) {
/* 2-byte code */
if ( c < 0xc2 )
goto encoding_error ;
ctxt - > input - > cur + = 2 ;
} else {
unsigned int val = ( c < < 8 ) | cur [ 1 ] ;
2023-03-15 18:18:11 +03:00
2023-08-09 17:59:36 +03:00
if ( ( avail < 3 ) | | ( cur [ 2 ] & 0xc0 ) ! = 0x80 )
2016-03-02 02:18:04 +03:00
goto encoding_error ;
2023-08-09 17:59:36 +03:00
if ( c < 0xf0 ) {
/* 3-byte code */
if ( ( val < 0xe0a0 ) | | ( ( val > = 0xeda0 ) & & ( val < 0xee00 ) ) )
goto encoding_error ;
ctxt - > input - > cur + = 3 ;
} else {
if ( ( avail < 4 ) | | ( ( cur [ 3 ] & 0xc0 ) ! = 0x80 ) )
2003-03-22 03:04:05 +03:00
goto encoding_error ;
2023-09-25 15:35:43 +03:00
2023-08-09 17:59:36 +03:00
/* 4-byte code */
if ( ( val < 0xf090 ) | | ( val > = 0xf490 ) )
goto encoding_error ;
ctxt - > input - > cur + = 4 ;
2023-09-25 15:35:43 +03:00
}
}
2001-02-23 20:55:21 +03:00
}
2023-08-09 17:59:36 +03:00
2001-02-23 20:55:21 +03:00
return ;
2023-08-09 17:59:36 +03:00
2003-10-05 17:51:35 +04:00
encoding_error :
2023-08-09 17:59:36 +03:00
/* Only report the first error */
if ( ( ctxt - > input - > flags & XML_INPUT_ENCODING_ERROR ) = = 0 ) {
2023-12-19 22:47:36 +03:00
xmlCtxtErrIO ( ctxt , XML_ERR_INVALID_ENCODING , NULL ) ;
2023-08-09 17:59:36 +03:00
ctxt - > input - > flags | = XML_INPUT_ENCODING_ERROR ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
}
2002-03-21 00:55:57 +03:00
ctxt - > input - > cur + + ;
2001-02-23 20:55:21 +03:00
return ;
}
/**
* xmlCurrentChar :
* @ ctxt : the XML parser context
* @ len : pointer to the length of the char read
*
2023-03-13 21:38:41 +03:00
* DEPRECATED : Internal function , do not use .
*
2001-12-31 19:16:02 +03:00
* The current char value , if using UTF - 8 this may actually span multiple
2001-02-23 20:55:21 +03:00
* bytes in the input buffer . Implement the end of line normalization :
* 2.11 End - of - Line Handling
* Wherever an external parsed entity or the literal entity value
* of an internal parsed entity contains either the literal two - character
* sequence " #xD#xA " or a standalone literal # xD , an XML processor
* must pass to the application the single character # xA .
* This behavior can conveniently be produced by normalizing all
* line breaks to # xA on input , before parsing . )
*
2001-10-10 13:45:09 +04:00
* Returns the current char value and its length
2001-02-23 20:55:21 +03:00
*/
int
xmlCurrentChar ( xmlParserCtxtPtr ctxt , int * len ) {
2023-08-09 17:59:36 +03:00
const unsigned char * cur ;
size_t avail ;
int c ;
2004-11-08 17:02:18 +03:00
if ( ( ctxt = = NULL ) | | ( len = = NULL ) | | ( ctxt - > input = = NULL ) ) return ( 0 ) ;
2001-02-23 20:55:21 +03:00
2023-08-09 17:59:36 +03:00
avail = ctxt - > input - > end - ctxt - > input - > cur ;
if ( avail < INPUT_CHUNK ) {
2023-06-07 15:05:34 +03:00
xmlParserGrow ( ctxt ) ;
2023-08-09 17:59:36 +03:00
avail = ctxt - > input - > end - ctxt - > input - > cur ;
2023-06-07 15:05:34 +03:00
}
2023-03-15 18:18:11 +03:00
2023-08-09 17:59:36 +03:00
cur = ctxt - > input - > cur ;
c = * cur ;
if ( c < 0x80 ) {
/* 1-byte code */
if ( c < 0x20 ) {
/*
* 2.11 End - of - Line Handling
* the literal two - character sequence " #xD#xA " or a standalone
* literal # xD , an XML processor must pass to the application
* the single character # xA .
*/
if ( c = = ' \r ' ) {
2023-11-26 16:31:39 +03:00
/*
* TODO : This function shouldn ' t change the ' cur ' pointer
* as side effect , but the NEXTL macro in parser . c relies
* on this behavior when incrementing line numbers .
*/
if ( cur [ 1 ] = = ' \n ' )
ctxt - > input - > cur + + ;
* len = 1 ;
2023-08-09 17:59:36 +03:00
c = ' \n ' ;
} else if ( c = = 0 ) {
if ( ctxt - > input - > cur > = ctxt - > input - > end ) {
* len = 0 ;
} else {
* len = 1 ;
2023-10-22 16:56:46 +03:00
/*
* TODO : Null bytes should be handled by callers ,
* but this can be tricky .
*/
2024-01-03 20:12:29 +03:00
xmlFatalErr ( ctxt , XML_ERR_INVALID_CHAR ,
" Char 0x0 out of allowed range \n " ) ;
2023-08-09 17:59:36 +03:00
}
} else {
* len = 1 ;
}
} else {
* len = 1 ;
}
2023-03-15 18:18:11 +03:00
2023-08-09 17:59:36 +03:00
return ( c ) ;
} else {
int val ;
2023-03-15 18:18:11 +03:00
2023-08-09 17:59:36 +03:00
if ( avail < 2 )
goto incomplete_sequence ;
if ( ( cur [ 1 ] & 0xc0 ) ! = 0x80 )
goto encoding_error ;
2023-03-15 18:18:11 +03:00
2023-08-09 17:59:36 +03:00
if ( c < 0xe0 ) {
/* 2-byte code */
if ( c < 0xc2 )
goto encoding_error ;
val = ( c & 0x1f ) < < 6 ;
val | = cur [ 1 ] & 0x3f ;
* len = 2 ;
} else {
if ( avail < 3 )
2023-05-18 18:31:44 +03:00
goto incomplete_sequence ;
2023-08-09 17:59:36 +03:00
if ( ( cur [ 2 ] & 0xc0 ) ! = 0x80 )
goto encoding_error ;
if ( c < 0xf0 ) {
/* 3-byte code */
val = ( c & 0xf ) < < 12 ;
val | = ( cur [ 1 ] & 0x3f ) < < 6 ;
val | = cur [ 2 ] & 0x3f ;
if ( ( val < 0x800 ) | | ( ( val > = 0xd800 ) & & ( val < 0xe000 ) ) )
goto encoding_error ;
* len = 3 ;
} else {
if ( avail < 4 )
2023-05-18 18:31:44 +03:00
goto incomplete_sequence ;
2023-08-09 17:59:36 +03:00
if ( ( cur [ 3 ] & 0xc0 ) ! = 0x80 )
goto encoding_error ;
/* 4-byte code */
val = ( c & 0x0f ) < < 18 ;
val | = ( cur [ 1 ] & 0x3f ) < < 12 ;
val | = ( cur [ 2 ] & 0x3f ) < < 6 ;
val | = cur [ 3 ] & 0x3f ;
if ( ( val < 0x10000 ) | | ( val > = 0x110000 ) )
goto encoding_error ;
* len = 4 ;
}
}
return ( val ) ;
2001-02-23 20:55:21 +03:00
}
2017-08-30 15:16:01 +03:00
2023-05-18 18:31:44 +03:00
encoding_error :
2023-08-09 17:59:36 +03:00
/* Only report the first error */
if ( ( ctxt - > input - > flags & XML_INPUT_ENCODING_ERROR ) = = 0 ) {
2023-12-19 22:47:36 +03:00
xmlCtxtErrIO ( ctxt , XML_ERR_INVALID_ENCODING , NULL ) ;
2023-08-09 17:59:36 +03:00
ctxt - > input - > flags | = XML_INPUT_ENCODING_ERROR ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
}
2001-02-23 20:55:21 +03:00
* len = 1 ;
2023-08-09 17:59:36 +03:00
return ( 0xFFFD ) ; /* U+FFFD Replacement Character */
2023-05-18 18:31:44 +03:00
incomplete_sequence :
/*
* An encoding problem may arise from a truncated input buffer
* splitting a character in the middle . In that case do not raise
* an error but return 0. This should only happen when push parsing
* char data .
*/
* len = 0 ;
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlStringCurrentChar :
* @ ctxt : the XML parser context
* @ cur : pointer to the beginning of the char
* @ len : pointer to the length of the char read
*
2023-03-13 21:38:41 +03:00
* DEPRECATED : Internal function , do not use .
*
2001-12-31 19:16:02 +03:00
* The current char value , if using UTF - 8 this may actually span multiple
2001-02-23 20:55:21 +03:00
* bytes in the input buffer .
*
2001-10-10 13:45:09 +04:00
* Returns the current char value and its length
2001-02-23 20:55:21 +03:00
*/
int
2023-09-22 16:45:20 +03:00
xmlStringCurrentChar ( xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED ,
const xmlChar * cur , int * len ) {
int c ;
2002-01-13 18:43:22 +03:00
2023-09-22 16:45:20 +03:00
if ( ( cur = = NULL ) | | ( len = = NULL ) )
return ( 0 ) ;
2017-08-30 15:16:01 +03:00
2023-09-22 16:45:20 +03:00
/* cur is zero-terminated, so we can lie about its length. */
* len = 4 ;
c = xmlGetUTF8Char ( cur , len ) ;
2004-11-09 17:59:59 +03:00
2023-09-22 16:45:20 +03:00
return ( ( c < 0 ) ? 0 : c ) ;
2001-02-23 20:55:21 +03:00
}
/**
2001-03-24 20:00:36 +03:00
* xmlCopyCharMultiByte :
2001-12-31 19:16:02 +03:00
* @ out : pointer to an array of xmlChar
2001-02-23 20:55:21 +03:00
* @ val : the char value
*
2012-09-11 09:26:36 +04:00
* append the char value in the array
2001-02-23 20:55:21 +03:00
*
* Returns the number of xmlChar written
*/
int
2001-03-24 20:00:36 +03:00
xmlCopyCharMultiByte ( xmlChar * out , int val ) {
2022-09-01 03:58:00 +03:00
if ( ( out = = NULL ) | | ( val < 0 ) ) return ( 0 ) ;
2001-02-23 20:55:21 +03:00
/*
* We are supposed to handle UTF8 , check it ' s valid
* From rfc2044 : encoding of the Unicode values on UTF - 8 :
*
* UCS - 4 range ( hex . ) UTF - 8 octet sequence ( binary )
* 0000 0000 - 0000 007F 0 xxxxxxx
* 0000 00 80 - 0000 07FF 110 xxxxx 10 xxxxxx
2012-09-11 09:26:36 +04:00
* 0000 0800 - 0000 FFFF 1110 xxxx 10 xxxxxx 10 xxxxxx
2001-02-23 20:55:21 +03:00
*/
2001-03-24 20:00:36 +03:00
if ( val > = 0x80 ) {
xmlChar * savedout = out ;
int bits ;
if ( val < 0x800 ) { * out + + = ( val > > 6 ) | 0xC0 ; bits = 0 ; }
else if ( val < 0x10000 ) { * out + + = ( val > > 12 ) | 0xE0 ; bits = 6 ; }
else if ( val < 0x110000 ) { * out + + = ( val > > 18 ) | 0xF0 ; bits = 12 ; }
else {
2024-01-03 20:11:44 +03:00
# ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
fprintf ( stderr , " xmlCopyCharMultiByte: codepoint out of range \n " ) ;
abort ( ) ;
# endif
2001-02-23 20:55:21 +03:00
return ( 0 ) ;
}
2001-03-24 20:00:36 +03:00
for ( ; bits > = 0 ; bits - = 6 )
* out + + = ( ( val > > bits ) & 0x3F ) | 0x80 ;
return ( out - savedout ) ;
2001-02-23 20:55:21 +03:00
}
2022-09-01 03:58:00 +03:00
* out = val ;
2001-03-24 20:00:36 +03:00
return 1 ;
}
2001-02-23 20:55:21 +03:00
2001-03-24 20:00:36 +03:00
/**
* xmlCopyChar :
* @ len : Ignored , compatibility
2001-12-31 19:16:02 +03:00
* @ out : pointer to an array of xmlChar
2001-03-24 20:00:36 +03:00
* @ val : the char value
*
2012-09-11 09:26:36 +04:00
* append the char value in the array
2001-03-24 20:00:36 +03:00
*
* Returns the number of xmlChar written
*/
2001-02-23 20:55:21 +03:00
2001-03-24 20:00:36 +03:00
int
2001-03-26 20:28:29 +04:00
xmlCopyChar ( int len ATTRIBUTE_UNUSED , xmlChar * out , int val ) {
2022-09-01 03:58:00 +03:00
if ( ( out = = NULL ) | | ( val < 0 ) ) return ( 0 ) ;
2001-03-24 20:00:36 +03:00
/* the len parameter is ignored */
if ( val > = 0x80 ) {
return ( xmlCopyCharMultiByte ( out , val ) ) ;
2001-02-23 20:55:21 +03:00
}
2022-09-01 03:58:00 +03:00
* out = val ;
2001-03-24 20:00:36 +03:00
return 1 ;
2001-02-23 20:55:21 +03:00
}
/************************************************************************
* *
* Commodity functions to switch encodings *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2023-12-10 19:50:22 +03:00
static int
xmlDetectEBCDIC ( xmlParserInputPtr input , xmlCharEncodingHandlerPtr * hout ) {
2023-03-21 21:07:12 +03:00
xmlChar out [ 200 ] ;
xmlCharEncodingHandlerPtr handler ;
int inlen , outlen , res , i ;
2023-12-10 19:50:22 +03:00
* hout = NULL ;
2023-03-21 21:07:12 +03:00
/*
* To detect the EBCDIC code page , we convert the first 200 bytes
* to EBCDIC - US and try to find the encoding declaration .
*/
2023-12-10 19:50:22 +03:00
res = xmlLookupCharEncodingHandler ( XML_CHAR_ENCODING_EBCDIC , & handler ) ;
if ( res ! = 0 )
return ( res ) ;
2023-03-26 15:11:31 +03:00
outlen = sizeof ( out ) - 1 ;
2023-03-21 21:07:12 +03:00
inlen = input - > end - input - > cur ;
2023-08-08 16:21:31 +03:00
res = xmlEncInputChunk ( handler , out , & outlen , input - > cur , & inlen ) ;
2023-12-10 19:50:22 +03:00
/*
* Return the EBCDIC handler if decoding failed . The error will
* be reported later .
*/
2023-03-21 21:07:12 +03:00
if ( res < 0 )
2023-12-10 19:50:22 +03:00
goto done ;
2023-03-26 15:11:31 +03:00
out [ outlen ] = 0 ;
2023-03-21 21:07:12 +03:00
for ( i = 0 ; i < outlen ; i + + ) {
if ( out [ i ] = = ' > ' )
break ;
if ( ( out [ i ] = = ' e ' ) & &
( xmlStrncmp ( out + i , BAD_CAST " encoding " , 8 ) = = 0 ) ) {
int start , cur , quote ;
i + = 8 ;
while ( IS_BLANK_CH ( out [ i ] ) )
i + = 1 ;
if ( out [ i + + ] ! = ' = ' )
break ;
while ( IS_BLANK_CH ( out [ i ] ) )
i + = 1 ;
quote = out [ i + + ] ;
if ( ( quote ! = ' \' ' ) & & ( quote ! = ' " ' ) )
break ;
start = i ;
cur = out [ i ] ;
while ( ( ( cur > = ' a ' ) & & ( cur < = ' z ' ) ) | |
( ( cur > = ' A ' ) & & ( cur < = ' Z ' ) ) | |
( ( cur > = ' 0 ' ) & & ( cur < = ' 9 ' ) ) | |
( cur = = ' . ' ) | | ( cur = = ' _ ' ) | |
( cur = = ' - ' ) )
cur = out [ + + i ] ;
if ( cur ! = quote )
break ;
out [ i ] = 0 ;
xmlCharEncCloseFunc ( handler ) ;
2024-01-02 20:33:57 +03:00
res = xmlOpenCharEncodingHandler ( ( char * ) out + start ,
/* output */ 0 , & handler ) ;
2023-12-10 19:50:22 +03:00
if ( res ! = 0 )
return ( res ) ;
* hout = handler ;
return ( 0 ) ;
2023-03-21 21:07:12 +03:00
}
}
2023-12-10 19:50:22 +03:00
done :
2023-08-08 16:21:31 +03:00
/*
2023-12-10 19:50:22 +03:00
* Encoding handlers are stateful , so we have to recreate them .
2023-08-08 16:21:31 +03:00
*/
xmlCharEncCloseFunc ( handler ) ;
2023-12-10 19:50:22 +03:00
res = xmlLookupCharEncodingHandler ( XML_CHAR_ENCODING_EBCDIC , & handler ) ;
if ( res ! = 0 )
return ( res ) ;
* hout = handler ;
return ( 0 ) ;
2023-03-21 21:07:12 +03:00
}
2001-02-23 20:55:21 +03:00
/**
* xmlSwitchEncoding :
* @ ctxt : the parser context
* @ enc : the encoding value ( number )
*
2023-12-10 19:50:22 +03:00
* Use encoding specified by enum to decode input data . This overrides
* the encoding found in the XML declaration .
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
*
2023-12-10 19:50:22 +03:00
* This function can also be used to override the encoding of chunks
* passed to xmlParseChunk .
2001-02-23 20:55:21 +03:00
*
* Returns 0 in case of success , - 1 otherwise
*/
int
xmlSwitchEncoding ( xmlParserCtxtPtr ctxt , xmlCharEncoding enc )
{
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
xmlCharEncodingHandlerPtr handler = NULL ;
2015-11-09 13:07:18 +03:00
int ret ;
2023-12-10 19:50:22 +03:00
int res ;
2001-02-23 20:55:21 +03:00
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > input = = NULL ) )
return ( - 1 ) ;
2023-06-22 19:06:53 +03:00
2001-02-23 20:55:21 +03:00
switch ( enc ) {
case XML_CHAR_ENCODING_NONE :
case XML_CHAR_ENCODING_UTF8 :
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
case XML_CHAR_ENCODING_ASCII :
2023-12-10 19:50:22 +03:00
res = 0 ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
break ;
2023-03-21 21:07:12 +03:00
case XML_CHAR_ENCODING_EBCDIC :
2023-12-10 19:50:22 +03:00
res = xmlDetectEBCDIC ( ctxt - > input , & handler ) ;
2023-03-21 21:07:12 +03:00
break ;
default :
2023-12-10 19:50:22 +03:00
res = xmlLookupCharEncodingHandler ( enc , & handler ) ;
2023-03-21 21:07:12 +03:00
break ;
2001-02-23 20:55:21 +03:00
}
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
2023-12-10 19:50:22 +03:00
if ( res ! = 0 ) {
2023-12-19 22:47:36 +03:00
const char * name = xmlGetCharEncodingName ( enc ) ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
2023-12-19 22:47:36 +03:00
xmlFatalErr ( ctxt , res , ( name ? name : " <null> " ) ) ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
return ( - 1 ) ;
2015-11-09 13:07:18 +03:00
}
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
ret = xmlSwitchInputEncoding ( ctxt , ctxt - > input , handler ) ;
if ( ( ret > = 0 ) & & ( enc = = XML_CHAR_ENCODING_NONE ) ) {
ctxt - > input - > flags & = ~ XML_INPUT_HAS_ENCODING ;
}
2015-11-09 13:07:18 +03:00
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2023-12-10 19:50:22 +03:00
/**
2024-06-11 17:19:58 +03:00
* xmlSwitchInputEncodingName :
2023-12-27 20:33:30 +03:00
* @ ctxt : the parser context , only for error reporting
* @ input : the input strea ,
2023-12-10 19:50:22 +03:00
* @ encoding : the encoding name
*
* Returns 0 in case of success , - 1 otherwise
*/
2023-12-27 20:33:30 +03:00
static int
xmlSwitchInputEncodingName ( xmlParserCtxtPtr ctxt , xmlParserInputPtr input ,
const char * encoding ) {
2023-12-10 19:50:22 +03:00
xmlCharEncodingHandlerPtr handler ;
int res ;
2023-12-19 22:47:36 +03:00
if ( encoding = = NULL )
return ( - 1 ) ;
2024-01-02 20:33:57 +03:00
res = xmlOpenCharEncodingHandler ( encoding , /* output */ 0 , & handler ) ;
2023-12-10 19:50:22 +03:00
if ( res ! = 0 ) {
2023-12-19 22:47:36 +03:00
xmlFatalErr ( ctxt , res , encoding ) ;
2023-12-10 19:50:22 +03:00
return ( - 1 ) ;
}
2023-12-27 20:33:30 +03:00
return ( xmlSwitchInputEncoding ( ctxt , input , handler ) ) ;
2023-12-10 19:50:22 +03:00
}
2001-02-23 20:55:21 +03:00
/**
2023-12-27 20:33:30 +03:00
* xmlSwitchEncodingName :
2001-02-23 20:55:21 +03:00
* @ ctxt : the parser context
2023-12-27 20:33:30 +03:00
* @ encoding : the encoding name
*
* Use specified encoding to decode input data . This overrides the
* encoding found in the XML declaration .
*
* This function can also be used to override the encoding of chunks
* passed to xmlParseChunk .
*
* Available since 2.13 .0 .
*
* Returns 0 in case of success , - 1 otherwise
*/
int
xmlSwitchEncodingName ( xmlParserCtxtPtr ctxt , const char * encoding ) {
2024-06-12 14:32:32 +03:00
if ( ctxt = = NULL )
return ( - 1 ) ;
2023-12-27 20:33:30 +03:00
return ( xmlSwitchInputEncodingName ( ctxt , ctxt - > input , encoding ) ) ;
}
/**
2024-06-11 03:15:18 +03:00
* xmlInputSetEncodingHandler :
2003-10-19 17:35:37 +04:00
* @ input : the input stream
2001-02-23 20:55:21 +03:00
* @ handler : the encoding handler
*
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
* Use encoding handler to decode input data .
2001-02-23 20:55:21 +03:00
*
2024-06-11 03:15:18 +03:00
* Closes the handler on error .
*
* Returns an xmlParserErrors code .
2001-02-23 20:55:21 +03:00
*/
2024-06-11 03:15:18 +03:00
static int
xmlInputSetEncodingHandler ( xmlParserInputPtr input ,
xmlCharEncodingHandlerPtr handler ) {
2001-02-23 20:55:21 +03:00
int nbchars ;
2022-11-13 21:44:00 +03:00
xmlParserInputBufferPtr in ;
2001-02-23 20:55:21 +03:00
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
if ( ( input = = NULL ) | | ( input - > buf = = NULL ) ) {
2022-11-13 21:44:00 +03:00
xmlCharEncCloseFunc ( handler ) ;
2024-06-11 03:15:18 +03:00
return ( XML_ERR_ARGUMENT ) ;
2022-11-13 21:44:00 +03:00
}
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
in = input - > buf ;
2001-02-23 20:55:21 +03:00
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
input - > flags | = XML_INPUT_HAS_ENCODING ;
2023-08-16 20:20:47 +03:00
/*
* UTF - 8 requires no encoding handler .
*/
if ( ( handler ! = NULL ) & &
( xmlStrcasecmp ( BAD_CAST handler - > name , BAD_CAST " UTF-8 " ) = = 0 ) ) {
xmlCharEncCloseFunc ( handler ) ;
handler = NULL ;
}
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
if ( in - > encoder = = handler )
2024-06-11 03:15:18 +03:00
return ( XML_ERR_OK ) ;
2023-04-13 16:11:47 +03:00
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
if ( in - > encoder ! = NULL ) {
2022-11-13 21:44:00 +03:00
/*
2023-04-13 16:11:47 +03:00
* Switching encodings during parsing is a really bad idea ,
2023-06-22 19:06:53 +03:00
* but Chromium can switch between ISO - 8859 - 1 and UTF - 16 before
* separate calls to xmlParseChunk .
2023-04-13 16:11:47 +03:00
*
* TODO : We should check whether the " raw " input buffer is empty and
* convert the old content using the old encoder .
2003-10-19 17:35:37 +04:00
*/
2023-04-13 16:11:47 +03:00
xmlCharEncCloseFunc ( in - > encoder ) ;
in - > encoder = handler ;
2024-06-11 03:15:18 +03:00
return ( XML_ERR_OK ) ;
2022-11-13 21:44:00 +03:00
}
2023-03-21 21:07:12 +03:00
2022-11-13 21:44:00 +03:00
in - > encoder = handler ;
2003-10-19 17:35:37 +04:00
2022-11-13 21:44:00 +03:00
/*
* Is there already some content down the pipe to convert ?
*/
if ( xmlBufIsEmpty ( in - > buffer ) = = 0 ) {
2023-12-15 16:46:35 +03:00
xmlBufPtr buf ;
2023-08-08 16:19:51 +03:00
size_t processed ;
2022-11-13 21:44:00 +03:00
2023-12-15 16:46:35 +03:00
buf = xmlBufCreate ( ) ;
2024-06-11 03:15:18 +03:00
if ( buf = = NULL )
return ( XML_ERR_NO_MEMORY ) ;
2023-12-15 16:46:35 +03:00
2022-11-13 21:44:00 +03:00
/*
* Shrink the current input buffer .
* Move it as the raw buffer and create a new input buffer
*/
processed = input - > cur - input - > base ;
xmlBufShrink ( in - > buffer , processed ) ;
2022-11-20 21:55:12 +03:00
input - > consumed + = processed ;
2022-11-13 21:44:00 +03:00
in - > raw = in - > buffer ;
2023-12-15 16:46:35 +03:00
in - > buffer = buf ;
2022-11-13 21:44:00 +03:00
in - > rawconsumed = processed ;
2023-08-08 16:21:31 +03:00
nbchars = xmlCharEncInput ( in ) ;
2022-11-13 21:44:00 +03:00
xmlBufResetInput ( in - > buffer , input ) ;
2024-06-11 03:15:18 +03:00
if ( nbchars < 0 )
return ( in - > error ) ;
}
return ( XML_ERR_OK ) ;
}
/**
* xmlInputSetEncoding :
* @ input : the input stream
* @ encoding : the encoding name
*
* Use specified encoding to decode input data . This overrides the
* encoding found in the XML declaration .
*
* Available since 2.14 .0 .
*
* Returns an xmlParserErrors code .
*/
int
xmlInputSetEncoding ( xmlParserInputPtr input , const char * encoding ) {
xmlCharEncodingHandlerPtr handler ;
int res ;
if ( encoding = = NULL )
return ( XML_ERR_ARGUMENT ) ;
res = xmlOpenCharEncodingHandler ( encoding , /* output */ 0 , & handler ) ;
if ( res ! = 0 )
return ( res ) ;
return ( xmlInputSetEncodingHandler ( input , handler ) ) ;
}
/**
* xmlSwitchInputEncoding :
* @ ctxt : the parser context , only for error reporting
* @ input : the input stream
* @ handler : the encoding handler
*
* DEPRECATED : Internal function , don ' t use .
*
* Use encoding handler to decode input data .
*
* Returns 0 in case of success , - 1 otherwise
*/
int
xmlSwitchInputEncoding ( xmlParserCtxtPtr ctxt , xmlParserInputPtr input ,
xmlCharEncodingHandlerPtr handler ) {
int code = xmlInputSetEncodingHandler ( input , handler ) ;
if ( code ! = XML_ERR_OK ) {
xmlCtxtErrIO ( ctxt , code , NULL ) ;
return ( - 1 ) ;
2003-10-19 17:35:37 +04:00
}
2024-06-11 03:15:18 +03:00
return ( 0 ) ;
2003-10-19 17:35:37 +04:00
}
2009-08-26 13:38:49 +04:00
/**
* xmlSwitchToEncoding :
* @ ctxt : the parser context
* @ handler : the encoding handler
*
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
* Use encoding handler to decode input data .
*
* This function can be used to enforce the encoding of chunks passed
* to xmlParseChunk .
2009-08-26 13:38:49 +04:00
*
* Returns 0 in case of success , - 1 otherwise
*/
int
2012-09-11 09:26:36 +04:00
xmlSwitchToEncoding ( xmlParserCtxtPtr ctxt , xmlCharEncodingHandlerPtr handler )
2009-08-26 13:38:49 +04:00
{
2022-03-07 01:23:43 +03:00
if ( ctxt = = NULL )
return ( - 1 ) ;
2023-03-21 21:07:12 +03:00
return ( xmlSwitchInputEncoding ( ctxt , ctxt - > input , handler ) ) ;
2009-08-26 13:38:49 +04:00
}
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
/**
* xmlDetectEncoding :
* @ ctxt : the parser context
*
* Handle optional BOM , detect and switch to encoding .
*
* Assumes that there are at least four bytes in the input buffer .
*/
void
xmlDetectEncoding ( xmlParserCtxtPtr ctxt ) {
2023-08-09 19:37:20 +03:00
const xmlChar * in ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
xmlCharEncoding enc ;
int bomSize ;
int autoFlag = 0 ;
if ( xmlParserGrow ( ctxt ) < 0 )
return ;
2023-08-09 19:37:20 +03:00
in = ctxt - > input - > cur ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
if ( ctxt - > input - > end - in < 4 )
return ;
if ( ctxt - > input - > flags & XML_INPUT_HAS_ENCODING ) {
/*
* If the encoding was already set , only skip the BOM which was
* possibly decoded to UTF - 8.
*/
if ( ( in [ 0 ] = = 0xEF ) & & ( in [ 1 ] = = 0xBB ) & & ( in [ 2 ] = = 0xBF ) ) {
ctxt - > input - > cur + = 3 ;
}
return ;
}
enc = XML_CHAR_ENCODING_NONE ;
bomSize = 0 ;
switch ( in [ 0 ] ) {
case 0x00 :
if ( ( in [ 1 ] = = 0x00 ) & & ( in [ 2 ] = = 0x00 ) & & ( in [ 3 ] = = 0x3C ) ) {
enc = XML_CHAR_ENCODING_UCS4BE ;
autoFlag = XML_INPUT_AUTO_OTHER ;
} else if ( ( in [ 1 ] = = 0x3C ) & & ( in [ 2 ] = = 0x00 ) & & ( in [ 3 ] = = 0x3F ) ) {
enc = XML_CHAR_ENCODING_UTF16BE ;
autoFlag = XML_INPUT_AUTO_UTF16BE ;
}
break ;
case 0x3C :
if ( in [ 1 ] = = 0x00 ) {
if ( ( in [ 2 ] = = 0x00 ) & & ( in [ 3 ] = = 0x00 ) ) {
enc = XML_CHAR_ENCODING_UCS4LE ;
autoFlag = XML_INPUT_AUTO_OTHER ;
} else if ( ( in [ 2 ] = = 0x3F ) & & ( in [ 3 ] = = 0x00 ) ) {
enc = XML_CHAR_ENCODING_UTF16LE ;
autoFlag = XML_INPUT_AUTO_UTF16LE ;
}
}
break ;
case 0x4C :
if ( ( in [ 1 ] = = 0x6F ) & & ( in [ 2 ] = = 0xA7 ) & & ( in [ 3 ] = = 0x94 ) ) {
enc = XML_CHAR_ENCODING_EBCDIC ;
autoFlag = XML_INPUT_AUTO_OTHER ;
}
break ;
case 0xEF :
if ( ( in [ 1 ] = = 0xBB ) & & ( in [ 2 ] = = 0xBF ) ) {
enc = XML_CHAR_ENCODING_UTF8 ;
autoFlag = XML_INPUT_AUTO_UTF8 ;
bomSize = 3 ;
}
break ;
case 0xFE :
if ( in [ 1 ] = = 0xFF ) {
enc = XML_CHAR_ENCODING_UTF16BE ;
autoFlag = XML_INPUT_AUTO_UTF16BE ;
bomSize = 2 ;
}
break ;
case 0xFF :
if ( in [ 1 ] = = 0xFE ) {
enc = XML_CHAR_ENCODING_UTF16LE ;
autoFlag = XML_INPUT_AUTO_UTF16LE ;
bomSize = 2 ;
}
break ;
}
if ( bomSize > 0 ) {
ctxt - > input - > cur + = bomSize ;
}
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
ctxt - > input - > flags | = autoFlag ;
xmlSwitchEncoding ( ctxt , enc ) ;
}
}
/**
* xmlSetDeclaredEncoding :
* @ ctxt : the parser context
* @ encoding : declared encoding
*
* Set the encoding from a declaration in the document .
*
* If no encoding was set yet , switch the encoding . Otherwise , only warn
* about encoding mismatches .
*
* Takes ownership of ' encoding ' .
*/
void
xmlSetDeclaredEncoding ( xmlParserCtxtPtr ctxt , xmlChar * encoding ) {
if ( ( ( ctxt - > input - > flags & XML_INPUT_HAS_ENCODING ) = = 0 ) & &
( ( ctxt - > options & XML_PARSE_IGNORE_ENC ) = = 0 ) ) {
2023-12-10 19:50:22 +03:00
xmlSwitchEncodingName ( ctxt , ( const char * ) encoding ) ;
2023-08-16 20:43:02 +03:00
ctxt - > input - > flags | = XML_INPUT_USES_ENC_DECL ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
} else if ( ctxt - > input - > flags & XML_INPUT_AUTO_ENCODING ) {
static const char * allowedUTF8 [ ] = {
" UTF-8 " , " UTF8 " , NULL
} ;
static const char * allowedUTF16LE [ ] = {
" UTF-16 " , " UTF-16LE " , " UTF16 " , NULL
} ;
static const char * allowedUTF16BE [ ] = {
" UTF-16 " , " UTF-16BE " , " UTF16 " , NULL
} ;
const char * * allowed = NULL ;
const char * autoEnc = NULL ;
switch ( ctxt - > input - > flags & XML_INPUT_AUTO_ENCODING ) {
case XML_INPUT_AUTO_UTF8 :
allowed = allowedUTF8 ;
autoEnc = " UTF-8 " ;
break ;
case XML_INPUT_AUTO_UTF16LE :
allowed = allowedUTF16LE ;
autoEnc = " UTF-16LE " ;
break ;
case XML_INPUT_AUTO_UTF16BE :
allowed = allowedUTF16BE ;
autoEnc = " UTF-16BE " ;
break ;
}
if ( allowed ! = NULL ) {
const char * * p ;
int match = 0 ;
for ( p = allowed ; * p ! = NULL ; p + + ) {
if ( xmlStrcasecmp ( encoding , BAD_CAST * p ) = = 0 ) {
match = 1 ;
break ;
}
}
if ( match = = 0 ) {
xmlWarningMsg ( ctxt , XML_WAR_ENCODING_MISMATCH ,
" Encoding '%s' doesn't match "
" auto-detected '%s' \n " ,
encoding , BAD_CAST autoEnc ) ;
2023-12-10 19:50:22 +03:00
xmlFree ( encoding ) ;
encoding = xmlStrdup ( BAD_CAST autoEnc ) ;
if ( encoding = = NULL )
2023-12-20 02:33:34 +03:00
xmlCtxtErrMemory ( ctxt ) ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
}
}
}
2023-12-10 19:50:22 +03:00
if ( ctxt - > encoding ! = NULL )
xmlFree ( ( xmlChar * ) ctxt - > encoding ) ;
ctxt - > encoding = encoding ;
parser: Rework encoding detection
Introduce XML_INPUT_HAS_ENCODING flag for xmlParserInput which is set
when xmlSwitchEncoding is called. The parser can use the flag to
reliably detect whether an encoding was already set via user override,
BOM or other auto-detection. In this case, the encoding declaration
won't be used to switch the encoding.
Before, an inscrutable mix of ctxt->charset, ctxt->input->encoding
and ctxt->input->buf->encoder was used.
Introduce private helper functions to switch encodings used by both the
XML and HTML parser:
- xmlDetectEncoding which skips over the BOM, allowing to remove the
BOM checks from other encoding functions.
- xmlSetDeclaredEncoding, replacing htmlCheckEncodingDirect, which warns
about encoding mismatches.
If users override the encoding, store the declared instead of the actual
encoding in xmlDoc. In this case, the actual encoding is known and the
raw value from the doc is more useful.
Also use the input flags to store the ISO-8859-1 fallback state.
Restrict the fallback to cases where no encoding was specified. (The
fallback is only useful in recovery mode and these days broken UTF-8 is
probably more likely than ISO-8859-1, so it might eventually be removed
completely.)
The 'charset' member of xmlParserCtxt is now unused. The 'encoding'
member of xmlParserInput is now unused.
The 'standalone' member of xmlParserInput is renamed to 'flags'.
A new parser state XML_PARSER_XML_DECL is added for the push parser.
2023-08-08 16:19:46 +03:00
}
2024-02-26 17:14:28 +03:00
/**
* xmlGetActualEncoding :
* @ ctxt : the parser context
*
* Returns the actual used to parse the document . This can differ from
* the declared encoding .
*/
const xmlChar *
xmlGetActualEncoding ( xmlParserCtxtPtr ctxt ) {
const xmlChar * encoding = NULL ;
if ( ( ctxt - > input - > flags & XML_INPUT_USES_ENC_DECL ) | |
( ctxt - > input - > flags & XML_INPUT_AUTO_ENCODING ) ) {
/* Preserve encoding exactly */
encoding = ctxt - > encoding ;
} else if ( ( ctxt - > input - > buf ) & & ( ctxt - > input - > buf - > encoder ) ) {
encoding = BAD_CAST ctxt - > input - > buf - > encoder - > name ;
} else if ( ctxt - > input - > flags & XML_INPUT_HAS_ENCODING ) {
encoding = BAD_CAST " UTF-8 " ;
}
return ( encoding ) ;
}
2001-02-23 20:55:21 +03:00
/************************************************************************
* *
* Commodity functions to handle entities processing *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlFreeInputStream :
* @ input : an xmlParserInputPtr
*
* Free up an input stream .
*/
void
xmlFreeInputStream ( xmlParserInputPtr input ) {
if ( input = = NULL ) return ;
if ( input - > filename ! = NULL ) xmlFree ( ( char * ) input - > filename ) ;
if ( input - > version ! = NULL ) xmlFree ( ( char * ) input - > version ) ;
if ( ( input - > free ! = NULL ) & & ( input - > base ! = NULL ) )
input - > free ( ( xmlChar * ) input - > base ) ;
2012-09-11 09:26:36 +04:00
if ( input - > buf ! = NULL )
2001-02-23 20:55:21 +03:00
xmlFreeParserInputBuffer ( input - > buf ) ;
xmlFree ( input ) ;
}
/**
* xmlNewInputStream :
* @ ctxt : an XML parser context
*
2012-05-15 07:18:40 +04:00
* Create a new input stream structure .
*
2001-02-23 20:55:21 +03:00
* Returns the new input stream or NULL
*/
xmlParserInputPtr
xmlNewInputStream ( xmlParserCtxtPtr ctxt ) {
xmlParserInputPtr input ;
input = ( xmlParserInputPtr ) xmlMalloc ( sizeof ( xmlParserInput ) ) ;
if ( input = = NULL ) {
2023-12-20 02:33:34 +03:00
xmlCtxtErrMemory ( ctxt ) ;
2001-02-23 20:55:21 +03:00
return ( NULL ) ;
}
memset ( input , 0 , sizeof ( xmlParserInput ) ) ;
input - > line = 1 ;
input - > col = 1 ;
2012-05-15 07:18:40 +04:00
2001-02-23 20:55:21 +03:00
return ( input ) ;
}
2023-12-27 20:33:30 +03:00
/**
* xmlNewInputURL :
* @ ctxt : parser context
* @ url : filename or URL
* @ publicId : publid ID from doctype ( optional )
* @ encoding : character encoding ( optional )
* @ flags : unused , pass 0
*
* Creates a new parser input from the filesystem , the network or
* a user - defined resource loader .
*
* Returns a new parser input .
*/
xmlParserInputPtr
xmlNewInputURL ( xmlParserCtxtPtr ctxt , const char * url , const char * publicId ,
const char * encoding , int flags ATTRIBUTE_UNUSED ) {
xmlParserInputPtr input ;
if ( ( ctxt = = NULL ) | | ( url = = NULL ) )
return ( NULL ) ;
2024-06-11 20:10:41 +03:00
input = xmlLoadResource ( ctxt , url , publicId , XML_RESOURCE_MAIN_DOCUMENT ) ;
2023-12-27 20:33:30 +03:00
if ( input = = NULL )
return ( NULL ) ;
if ( encoding ! = NULL )
xmlSwitchInputEncodingName ( ctxt , input , encoding ) ;
return ( input ) ;
}
/**
* xmlNewInputInternal :
* @ buf : parser input buffer
* @ filename : filename or URL
*
* Internal helper function .
*
* Returns a new parser input .
*/
static xmlParserInputPtr
2024-06-11 03:15:18 +03:00
xmlNewInputInternal ( xmlParserInputBufferPtr buf , const char * filename ) {
2023-12-27 20:33:30 +03:00
xmlParserInputPtr input ;
2024-06-11 03:15:18 +03:00
input = ( xmlParserInputPtr ) xmlMalloc ( sizeof ( xmlParserInput ) ) ;
2023-12-27 20:33:30 +03:00
if ( input = = NULL ) {
xmlFreeParserInputBuffer ( buf ) ;
return ( NULL ) ;
}
2024-06-11 03:15:18 +03:00
memset ( input , 0 , sizeof ( xmlParserInput ) ) ;
input - > line = 1 ;
input - > col = 1 ;
2023-12-27 20:33:30 +03:00
input - > buf = buf ;
xmlBufResetInput ( input - > buf - > buffer , input ) ;
if ( filename ! = NULL ) {
input - > filename = xmlMemStrdup ( filename ) ;
if ( input - > filename = = NULL ) {
xmlFreeInputStream ( input ) ;
return ( NULL ) ;
}
}
return ( input ) ;
}
/**
2024-06-11 03:15:18 +03:00
* xmlInputCreateMemory :
2023-12-27 20:33:30 +03:00
* @ url : base URL ( optional )
* @ mem : pointer to char array
* @ size : size of array
* @ flags : optimization hints
*
* Creates a new parser input to read from a memory area .
*
* @ url is used as base to resolve external entities and for
* error reporting .
*
* If the XML_INPUT_BUF_STATIC flag is set , the memory area must
* stay unchanged until parsing has finished . This can avoid
* temporary copies .
*
* If the XML_INPUT_BUF_ZERO_TERMINATED flag is set , the memory
* area must contain a zero byte after the buffer at position @ size .
* This can avoid temporary copies .
*
2024-06-11 03:15:18 +03:00
* Available since 2.14 .0 .
*
* Returns a new parser input or NULL if a memory allocation failed .
*/
xmlParserInputPtr
xmlInputCreateMemory ( const char * url , const void * mem , size_t size ,
int flags ) {
xmlParserInputBufferPtr buf ;
if ( mem = = NULL )
return ( NULL ) ;
buf = xmlNewInputBufferMemory ( mem , size , flags , XML_CHAR_ENCODING_NONE ) ;
if ( buf = = NULL )
return ( NULL ) ;
return ( xmlNewInputInternal ( buf , url ) ) ;
}
/**
* xmlNewInputMemory :
* @ ctxt : parser context
* @ url : base URL ( optional )
* @ mem : pointer to char array
* @ size : size of array
* @ encoding : character encoding ( optional )
* @ flags : optimization hints
*
* Returns a new parser input or NULL in case of error .
2023-12-27 20:33:30 +03:00
*/
xmlParserInputPtr
xmlNewInputMemory ( xmlParserCtxtPtr ctxt , const char * url ,
const void * mem , size_t size ,
const char * encoding , int flags ) {
2024-06-11 03:15:18 +03:00
xmlParserInputPtr input ;
2023-12-27 20:33:30 +03:00
if ( ( ctxt = = NULL ) | | ( mem = = NULL ) )
return ( NULL ) ;
2024-06-11 03:15:18 +03:00
input = xmlInputCreateMemory ( url , mem , size , flags ) ;
if ( input = = NULL ) {
xmlCtxtErrMemory ( ctxt ) ;
2023-12-27 20:33:30 +03:00
return ( NULL ) ;
}
2024-06-11 03:15:18 +03:00
if ( encoding ! = NULL )
xmlSwitchInputEncodingName ( ctxt , input , encoding ) ;
return ( input ) ;
2023-12-27 20:33:30 +03:00
}
/**
2024-06-11 03:15:18 +03:00
* xmlInputCreateString :
2023-12-27 20:33:30 +03:00
* @ url : base URL ( optional )
* @ str : zero - terminated string
* @ flags : optimization hints
*
* Creates a new parser input to read from a zero - terminated string .
*
* @ url is used as base to resolve external entities and for
* error reporting .
*
* If the XML_INPUT_BUF_STATIC flag is set , the string must
* stay unchanged until parsing has finished . This can avoid
* temporary copies .
*
2024-06-11 03:15:18 +03:00
* Available since 2.14 .0 .
*
* Returns a new parser input or NULL if a memory allocation failed .
*/
xmlParserInputPtr
xmlInputCreateString ( const char * url , const char * str , int flags ) {
xmlParserInputBufferPtr buf ;
if ( str = = NULL )
return ( NULL ) ;
buf = xmlNewInputBufferString ( str , flags ) ;
if ( buf = = NULL )
return ( NULL ) ;
return ( xmlNewInputInternal ( buf , url ) ) ;
}
/**
* xmlNewInputString :
* @ ctxt : parser context
* @ url : base URL ( optional )
* @ str : zero - terminated string
* @ encoding : character encoding ( optional )
* @ flags : optimization hints
*
2023-12-27 20:33:30 +03:00
* Returns a new parser input .
*/
xmlParserInputPtr
xmlNewInputString ( xmlParserCtxtPtr ctxt , const char * url ,
const char * str , const char * encoding , int flags ) {
2024-06-11 03:15:18 +03:00
xmlParserInputPtr input ;
2023-12-27 20:33:30 +03:00
if ( ( ctxt = = NULL ) | | ( str = = NULL ) )
return ( NULL ) ;
2024-06-11 03:15:18 +03:00
input = xmlInputCreateString ( url , str , flags ) ;
if ( input = = NULL ) {
xmlCtxtErrMemory ( ctxt ) ;
2023-12-27 20:33:30 +03:00
return ( NULL ) ;
}
2024-06-11 03:15:18 +03:00
if ( encoding ! = NULL )
xmlSwitchInputEncodingName ( ctxt , input , encoding ) ;
return ( input ) ;
2023-12-27 20:33:30 +03:00
}
/**
2024-06-11 03:15:18 +03:00
* xmlInputCreateFd :
2023-12-27 20:33:30 +03:00
* @ url : base URL ( optional )
* @ fd : file descriptor
* @ flags : unused , pass 0
*
* Creates a new parser input to read from a zero - terminated string .
*
* @ url is used as base to resolve external entities and for
* error reporting .
*
* @ fd is closed after parsing has finished .
*
2024-06-11 03:15:18 +03:00
* Available since 2.14 .0 .
*
* Returns a new parser input or NULL if a memory allocation failed .
*/
xmlParserInputPtr
xmlInputCreateFd ( const char * url , int fd , int flags ATTRIBUTE_UNUSED ) {
xmlParserInputBufferPtr buf ;
if ( fd < 0 )
return ( NULL ) ;
buf = xmlParserInputBufferCreateFd ( fd , XML_CHAR_ENCODING_NONE ) ;
if ( buf = = NULL )
return ( NULL ) ;
return ( xmlNewInputInternal ( buf , url ) ) ;
}
/**
* xmlNewInputFd :
* @ ctxt : parser context
* @ url : base URL ( optional )
* @ fd : file descriptor
* @ encoding : character encoding ( optional )
* @ flags : unused , pass 0
*
2023-12-27 20:33:30 +03:00
* Returns a new parser input .
*/
xmlParserInputPtr
xmlNewInputFd ( xmlParserCtxtPtr ctxt , const char * url ,
2024-06-11 03:15:18 +03:00
int fd , const char * encoding , int flags ) {
xmlParserInputPtr input ;
2023-12-27 20:33:30 +03:00
if ( ( ctxt = = NULL ) | | ( fd < 0 ) )
return ( NULL ) ;
2024-06-11 03:15:18 +03:00
input = xmlInputCreateFd ( url , fd , flags ) ;
if ( input = = NULL ) {
2023-12-27 20:33:30 +03:00
xmlCtxtErrMemory ( ctxt ) ;
return ( NULL ) ;
}
2024-06-11 03:15:18 +03:00
if ( encoding ! = NULL )
xmlSwitchInputEncodingName ( ctxt , input , encoding ) ;
return ( input ) ;
2023-12-27 20:33:30 +03:00
}
/**
2024-06-11 03:15:18 +03:00
* xmlInputCreateIO :
2023-12-27 20:33:30 +03:00
* @ url : base URL ( optional )
* @ ioRead : read callback
* @ ioClose : close callback ( optional )
* @ ioCtxt : IO context
* @ flags : unused , pass 0
*
* Creates a new parser input to read from input callbacks and
* cintext .
*
* @ url is used as base to resolve external entities and for
* error reporting .
*
* @ ioRead is called to read new data into a provided buffer .
* It must return the number of bytes written into the buffer
* ot a negative xmlParserErrors code on failure .
*
* @ ioClose is called after parsing has finished .
*
* @ ioCtxt is an opaque pointer passed to the callbacks .
*
2024-06-11 03:15:18 +03:00
* Available since 2.14 .0 .
*
* Returns a new parser input or NULL if a memory allocation failed .
2023-12-27 20:33:30 +03:00
*/
xmlParserInputPtr
2024-06-11 03:15:18 +03:00
xmlInputCreateIO ( const char * url , xmlInputReadCallback ioRead ,
xmlInputCloseCallback ioClose , void * ioCtxt ,
int flags ATTRIBUTE_UNUSED ) {
2023-12-27 20:33:30 +03:00
xmlParserInputBufferPtr buf ;
2024-06-11 03:15:18 +03:00
if ( ioRead = = NULL )
2023-12-27 20:33:30 +03:00
return ( NULL ) ;
buf = xmlAllocParserInputBuffer ( XML_CHAR_ENCODING_NONE ) ;
if ( buf = = NULL ) {
2024-01-05 01:25:06 +03:00
if ( ioClose ! = NULL )
ioClose ( ioCtxt ) ;
2023-12-27 20:33:30 +03:00
return ( NULL ) ;
}
buf - > context = ioCtxt ;
buf - > readcallback = ioRead ;
buf - > closecallback = ioClose ;
2024-06-11 03:15:18 +03:00
return ( xmlNewInputInternal ( buf , url ) ) ;
}
/**
* xmlNewInputIO :
* @ ctxt : parser context
* @ url : base URL ( optional )
* @ ioRead : read callback
* @ ioClose : close callback ( optional )
* @ ioCtxt : IO context
* @ encoding : character encoding ( optional )
* @ flags : unused , pass 0
*
* Returns a new parser input .
*/
xmlParserInputPtr
xmlNewInputIO ( xmlParserCtxtPtr ctxt , const char * url ,
xmlInputReadCallback ioRead , xmlInputCloseCallback ioClose ,
void * ioCtxt , const char * encoding , int flags ) {
xmlParserInputPtr input ;
if ( ( ctxt = = NULL ) | | ( ioRead = = NULL ) )
return ( NULL ) ;
input = xmlInputCreateIO ( url , ioRead , ioClose , ioCtxt , flags ) ;
if ( input = = NULL ) {
xmlCtxtErrMemory ( ctxt ) ;
return ( NULL ) ;
}
if ( encoding ! = NULL )
xmlSwitchInputEncodingName ( ctxt , input , encoding ) ;
return ( input ) ;
2023-12-27 20:33:30 +03:00
}
/**
2024-06-11 17:19:58 +03:00
* xmlInputCreatePush :
2023-12-27 20:33:30 +03:00
* @ url : base URL ( optional )
* @ chunk : pointer to char array
* @ size : size of array
*
* Creates a new parser input for a push parser .
*
2024-06-11 17:19:58 +03:00
* Returns a new parser input or NULL if a memory allocation failed .
2023-12-27 20:33:30 +03:00
*/
xmlParserInputPtr
2024-06-11 17:19:58 +03:00
xmlInputCreatePush ( const char * url , const char * chunk , int size ) {
2023-12-27 20:33:30 +03:00
xmlParserInputBufferPtr buf ;
xmlParserInputPtr input ;
buf = xmlAllocParserInputBuffer ( XML_CHAR_ENCODING_NONE ) ;
2024-06-11 17:19:58 +03:00
if ( buf = = NULL )
2023-12-27 20:33:30 +03:00
return ( NULL ) ;
2024-06-11 03:15:18 +03:00
input = xmlNewInputInternal ( buf , url ) ;
2024-06-11 17:19:58 +03:00
if ( input = = NULL )
2023-12-27 20:33:30 +03:00
return ( NULL ) ;
input - > flags | = XML_INPUT_PROGRESSIVE ;
if ( ( size > 0 ) & & ( chunk ! = NULL ) ) {
int res ;
res = xmlParserInputBufferPush ( input - > buf , size , chunk ) ;
xmlBufResetInput ( input - > buf - > buffer , input ) ;
if ( res < 0 ) {
xmlFreeInputStream ( input ) ;
return ( NULL ) ;
}
}
return ( input ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlNewIOInputStream :
* @ ctxt : an XML parser context
2024-05-20 14:58:22 +03:00
* @ buf : an input buffer
2001-02-23 20:55:21 +03:00
* @ enc : the charset encoding if known
*
* Create a new input stream structure encapsulating the @ input into
* a stream suitable for the parser .
*
* Returns the new input stream or NULL
*/
xmlParserInputPtr
2023-12-27 20:33:30 +03:00
xmlNewIOInputStream ( xmlParserCtxtPtr ctxt , xmlParserInputBufferPtr buf ,
2001-02-23 20:55:21 +03:00
xmlCharEncoding enc ) {
2024-06-11 03:15:18 +03:00
xmlParserInputPtr input ;
2023-12-27 20:33:30 +03:00
const char * encoding ;
2012-07-16 12:28:47 +04:00
2023-12-27 20:33:30 +03:00
if ( buf = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
2024-06-11 03:15:18 +03:00
input = xmlNewInputInternal ( buf , NULL ) ;
if ( input = = NULL ) {
xmlCtxtErrMemory ( ctxt ) ;
return ( NULL ) ;
}
2023-12-27 20:33:30 +03:00
encoding = xmlGetCharEncodingName ( enc ) ;
2024-06-11 03:15:18 +03:00
if ( encoding ! = NULL )
xmlSwitchInputEncodingName ( ctxt , input , encoding ) ;
return ( input ) ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlNewEntityInputStream :
* @ ctxt : an XML parser context
2024-05-20 14:58:22 +03:00
* @ ent : an Entity pointer
2001-02-23 20:55:21 +03:00
*
2023-03-13 21:38:41 +03:00
* DEPRECATED : Internal function , do not use .
*
2001-02-23 20:55:21 +03:00
* Create a new input stream based on an xmlEntityPtr
*
* Returns the new input stream or NULL
*/
xmlParserInputPtr
2023-12-27 17:50:58 +03:00
xmlNewEntityInputStream ( xmlParserCtxtPtr ctxt , xmlEntityPtr ent ) {
2001-02-23 20:55:21 +03:00
xmlParserInputPtr input ;
2023-12-27 17:50:58 +03:00
if ( ( ctxt = = NULL ) | | ( ent = = NULL ) )
2001-02-23 20:55:21 +03:00
return ( NULL ) ;
2023-12-23 03:09:17 +03:00
2023-12-27 17:50:58 +03:00
if ( ent - > content ! = NULL ) {
2023-12-27 20:33:30 +03:00
input = xmlNewInputString ( ctxt , NULL , ( const char * ) ent - > content ,
NULL , XML_INPUT_BUF_STATIC ) ;
2023-12-27 17:50:58 +03:00
} else if ( ent - > URI ! = NULL ) {
2024-06-11 20:10:41 +03:00
xmlResourceType rtype ;
if ( ent - > etype = = XML_EXTERNAL_PARAMETER_ENTITY )
rtype = XML_RESOURCE_PARAMETER_ENTITY ;
else
rtype = XML_RESOURCE_GENERAL_ENTITY ;
input = xmlLoadResource ( ctxt , ( char * ) ent - > URI ,
( char * ) ent - > ExternalID , rtype ) ;
2023-12-27 17:50:58 +03:00
} else {
2024-05-10 03:04:52 +03:00
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
}
2023-12-27 17:50:58 +03:00
2023-12-27 20:33:30 +03:00
if ( input = = NULL )
return ( NULL ) ;
2023-12-27 17:50:58 +03:00
input - > entity = ent ;
2023-12-23 03:09:17 +03:00
2001-02-23 20:55:21 +03:00
return ( input ) ;
}
/**
* xmlNewStringInputStream :
* @ ctxt : an XML parser context
* @ buffer : an memory buffer
*
* Create a new input stream based on a memory buffer .
2023-12-27 20:33:30 +03:00
*
2001-02-23 20:55:21 +03:00
* Returns the new input stream
*/
xmlParserInputPtr
xmlNewStringInputStream ( xmlParserCtxtPtr ctxt , const xmlChar * buffer ) {
2023-12-27 20:33:30 +03:00
return ( xmlNewInputString ( ctxt , NULL , ( const char * ) buffer , NULL , 0 ) ) ;
2001-02-23 20:55:21 +03:00
}
2023-12-27 20:33:30 +03:00
2023-12-23 02:35:30 +03:00
/****************************************************************
* *
* External entities loading *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef LIBXML_CATALOG_ENABLED
/**
* xmlResolveResourceFromCatalog :
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
* @ ctxt : the context in which the entity is called or NULL
*
* Resolves the URL and ID against the appropriate catalog .
* This function is used by xmlDefaultExternalEntityLoader and
* xmlNoNetExternalEntityLoader .
*
* Returns a new allocated URL , or NULL .
*/
static xmlChar *
xmlResolveResourceFromCatalog ( const char * URL , const char * ID ,
xmlParserCtxtPtr ctxt ) {
xmlChar * resource = NULL ;
xmlCatalogAllow pref ;
/*
* If the resource doesn ' t exists as a file ,
* try to load it from the resource pointed in the catalogs
*/
pref = xmlCatalogGetDefaults ( ) ;
if ( ( pref ! = XML_CATA_ALLOW_NONE ) & & ( ! xmlNoNetExists ( URL ) ) ) {
/*
* Do a local lookup
*/
if ( ( ctxt ! = NULL ) & & ( ctxt - > catalogs ! = NULL ) & &
( ( pref = = XML_CATA_ALLOW_ALL ) | |
( pref = = XML_CATA_ALLOW_DOCUMENT ) ) ) {
resource = xmlCatalogLocalResolve ( ctxt - > catalogs ,
( const xmlChar * ) ID ,
( const xmlChar * ) URL ) ;
}
/*
* Try a global lookup
*/
if ( ( resource = = NULL ) & &
( ( pref = = XML_CATA_ALLOW_ALL ) | |
( pref = = XML_CATA_ALLOW_GLOBAL ) ) ) {
resource = xmlCatalogResolve ( ( const xmlChar * ) ID ,
( const xmlChar * ) URL ) ;
}
if ( ( resource = = NULL ) & & ( URL ! = NULL ) )
resource = xmlStrdup ( ( const xmlChar * ) URL ) ;
/*
* TODO : do an URI lookup on the reference
*/
if ( ( resource ! = NULL ) & & ( ! xmlNoNetExists ( ( const char * ) resource ) ) ) {
xmlChar * tmp = NULL ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > catalogs ! = NULL ) & &
( ( pref = = XML_CATA_ALLOW_ALL ) | |
( pref = = XML_CATA_ALLOW_DOCUMENT ) ) ) {
tmp = xmlCatalogLocalResolveURI ( ctxt - > catalogs , resource ) ;
}
if ( ( tmp = = NULL ) & &
( ( pref = = XML_CATA_ALLOW_ALL ) | |
( pref = = XML_CATA_ALLOW_GLOBAL ) ) ) {
tmp = xmlCatalogResolveURI ( resource ) ;
}
if ( tmp ! = NULL ) {
xmlFree ( resource ) ;
resource = tmp ;
}
}
}
return resource ;
}
# endif
/**
* xmlCheckHTTPInput :
* @ ctxt : an XML parser context
* @ ret : an XML parser input
*
* DEPRECATED : Internal function , don ' t use .
*
* Check an input in case it was created from an HTTP stream , in that
* case it will handle encoding and update of the base URL in case of
* redirection . It also checks for HTTP errors in which case the input
* is cleanly freed up and an appropriate error is raised in context
*
* Returns the input or NULL in case of HTTP error .
*/
xmlParserInputPtr
xmlCheckHTTPInput ( xmlParserCtxtPtr ctxt , xmlParserInputPtr ret ) {
/* Avoid unused variable warning if features are disabled. */
( void ) ctxt ;
# ifdef LIBXML_HTTP_ENABLED
if ( ( ret ! = NULL ) & & ( ret - > buf ! = NULL ) & &
( ret - > buf - > readcallback = = xmlIOHTTPRead ) & &
( ret - > buf - > context ! = NULL ) ) {
const char * encoding ;
const char * redir ;
const char * mime ;
int code ;
code = xmlNanoHTTPReturnCode ( ret - > buf - > context ) ;
if ( code > = 400 ) {
/* fatal error */
if ( ret - > filename ! = NULL )
xmlCtxtErrIO ( ctxt , XML_IO_LOAD_ERROR , ret - > filename ) ;
else
xmlCtxtErrIO ( ctxt , XML_IO_LOAD_ERROR , " <null> " ) ;
xmlFreeInputStream ( ret ) ;
ret = NULL ;
} else {
mime = xmlNanoHTTPMimeType ( ret - > buf - > context ) ;
if ( ( xmlStrstr ( BAD_CAST mime , BAD_CAST " /xml " ) ) | |
( xmlStrstr ( BAD_CAST mime , BAD_CAST " +xml " ) ) ) {
encoding = xmlNanoHTTPEncoding ( ret - > buf - > context ) ;
if ( encoding ! = NULL )
xmlSwitchEncodingName ( ctxt , encoding ) ;
#if 0
} else if ( xmlStrstr ( BAD_CAST mime , BAD_CAST " html " ) ) {
# endif
}
redir = xmlNanoHTTPRedir ( ret - > buf - > context ) ;
if ( redir ! = NULL ) {
if ( ret - > filename ! = NULL )
xmlFree ( ( xmlChar * ) ret - > filename ) ;
ret - > filename =
( char * ) xmlStrdup ( ( const xmlChar * ) redir ) ;
}
}
}
# endif
return ( ret ) ;
}
2001-02-23 20:55:21 +03:00
/**
2024-06-11 03:15:18 +03:00
* xmlInputCreateUrl :
2001-02-23 20:55:21 +03:00
* @ filename : the filename to use as entity
2024-06-11 03:15:18 +03:00
* @ flags : XML_INPUT flags
* @ out : pointer to new parser input
2001-02-23 20:55:21 +03:00
*
2024-06-11 03:15:18 +03:00
* Create a new input stream based on a file or a URL .
2001-02-23 20:55:21 +03:00
*
2024-06-11 03:15:18 +03:00
* The flag XML_INPUT_UNZIP allows decompression .
*
2024-06-11 19:11:51 +03:00
* The flag XML_INPUT_NETWORK allows network access .
*
2024-06-11 03:15:18 +03:00
* Available since 2.14 .0 .
*
* Returns an xmlParserErrors code .
2001-02-23 20:55:21 +03:00
*/
2024-06-11 03:15:18 +03:00
int
xmlInputCreateUrl ( const char * filename , int flags , xmlParserInputPtr * out ) {
2001-02-23 20:55:21 +03:00
xmlParserInputBufferPtr buf ;
2024-06-11 01:52:04 +03:00
xmlParserInputPtr input ;
2024-06-10 19:51:56 +03:00
int code = XML_ERR_OK ;
2001-02-23 20:55:21 +03:00
2024-06-11 03:15:18 +03:00
if ( out = = NULL )
return ( XML_ERR_ARGUMENT ) ;
* out = NULL ;
if ( filename = = NULL )
return ( XML_ERR_ARGUMENT ) ;
2023-12-19 17:41:37 +03:00
2024-06-10 19:51:56 +03:00
if ( xmlParserInputBufferCreateFilenameValue ! = NULL ) {
buf = xmlParserInputBufferCreateFilenameValue ( filename ,
XML_CHAR_ENCODING_NONE ) ;
if ( buf = = NULL )
code = XML_IO_ENOENT ;
} else {
2024-06-11 00:57:52 +03:00
code = xmlParserInputBufferCreateUrl ( filename , XML_CHAR_ENCODING_NONE ,
2024-06-11 01:00:32 +03:00
flags , & buf ) ;
2024-06-10 19:51:56 +03:00
}
2024-06-11 03:15:18 +03:00
if ( code ! = XML_ERR_OK )
return ( code ) ;
input = xmlNewInputInternal ( buf , filename ) ;
if ( input = = NULL )
return ( XML_ERR_NO_MEMORY ) ;
/*input = xmlCheckHTTPInput(ctxt, input);*/
* out = input ;
return ( XML_ERR_OK ) ;
}
/**
* xmlNewInputFromFile :
* @ ctxt : an XML parser context
* @ filename : the filename to use as entity
*
* Create a new input stream based on a file or an URL .
*
* Returns the new input stream or NULL in case of error
*/
xmlParserInputPtr
xmlNewInputFromFile ( xmlParserCtxtPtr ctxt , const char * filename ) {
xmlParserInputPtr input ;
int flags = 0 ;
int code ;
if ( ( ctxt = = NULL ) | | ( filename = = NULL ) )
return ( NULL ) ;
if ( ( ctxt - > options & XML_PARSE_NO_UNZIP ) = = 0 )
flags | = XML_INPUT_UNZIP ;
2024-06-11 19:11:51 +03:00
if ( ( ctxt - > options & XML_PARSE_NONET ) = = 0 )
flags | = XML_INPUT_NETWORK ;
2024-06-11 03:15:18 +03:00
code = xmlInputCreateUrl ( filename , flags , & input ) ;
2024-06-10 19:51:56 +03:00
if ( code ! = XML_ERR_OK ) {
2023-12-19 21:52:28 +03:00
xmlCtxtErrIO ( ctxt , code , filename ) ;
2024-06-11 03:15:18 +03:00
return ( NULL ) ;
2003-10-27 14:25:13 +03:00
}
2001-02-23 20:55:21 +03:00
2024-06-11 01:52:04 +03:00
input = xmlCheckHTTPInput ( ctxt , input ) ;
2023-12-23 02:58:36 +03:00
2024-06-11 01:52:04 +03:00
return ( input ) ;
2001-02-23 20:55:21 +03:00
}
2023-12-23 02:35:30 +03:00
/**
* xmlDefaultExternalEntityLoader :
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
* @ ctxt : the context in which the entity is called or NULL
*
* By default we don ' t load external entities , yet .
*
* Returns a new allocated xmlParserInputPtr , or NULL .
*/
static xmlParserInputPtr
2024-06-11 01:37:11 +03:00
xmlDefaultExternalEntityLoader ( const char * url , const char * ID ,
2023-12-23 02:35:30 +03:00
xmlParserCtxtPtr ctxt )
{
2024-06-11 01:37:11 +03:00
xmlParserInputPtr input = NULL ;
char * resource = NULL ;
2023-12-23 02:35:30 +03:00
2024-06-11 01:37:11 +03:00
( void ) ID ;
2023-12-23 02:35:30 +03:00
2024-06-11 01:37:11 +03:00
if ( url = = NULL )
return ( NULL ) ;
2023-12-23 02:35:30 +03:00
# ifdef LIBXML_CATALOG_ENABLED
2024-06-11 01:37:11 +03:00
resource = ( char * ) xmlResolveResourceFromCatalog ( url , ID , ctxt ) ;
if ( resource ! = NULL )
url = resource ;
2023-12-23 02:35:30 +03:00
# endif
2024-06-11 01:37:11 +03:00
if ( ( ctxt ! = NULL ) & &
( ctxt - > options & XML_PARSE_NONET ) & &
2024-06-12 19:19:55 +03:00
( xmlStrncasecmp ( BAD_CAST url , BAD_CAST " http:// " , 7 ) = = 0 ) ) {
2024-06-11 01:37:11 +03:00
xmlCtxtErrIO ( ctxt , XML_IO_NETWORK_ATTEMPT , url ) ;
} else {
input = xmlNewInputFromFile ( ctxt , url ) ;
}
2023-12-23 02:35:30 +03:00
2024-06-11 01:37:11 +03:00
if ( resource ! = NULL )
xmlFree ( resource ) ;
return ( input ) ;
2023-12-23 02:35:30 +03:00
}
/**
* xmlNoNetExternalEntityLoader :
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
* @ ctxt : the context in which the entity is called or NULL
*
2024-06-11 04:51:43 +03:00
* DEPRECATED : Use XML_PARSE_NONET .
*
2023-12-23 02:35:30 +03:00
* A specific entity loader disabling network accesses , though still
* allowing local catalog accesses for resolution .
*
* Returns a new allocated xmlParserInputPtr , or NULL .
*/
xmlParserInputPtr
xmlNoNetExternalEntityLoader ( const char * URL , const char * ID ,
xmlParserCtxtPtr ctxt ) {
2024-06-11 01:37:11 +03:00
int oldOptions = 0 ;
xmlParserInputPtr input ;
2023-12-23 02:35:30 +03:00
2024-06-11 01:37:11 +03:00
if ( ctxt ! = NULL ) {
oldOptions = ctxt - > options ;
ctxt - > options | = XML_PARSE_NONET ;
}
2023-12-23 02:35:30 +03:00
2024-06-11 01:37:11 +03:00
input = xmlDefaultExternalEntityLoader ( URL , ID , ctxt ) ;
if ( ctxt ! = NULL )
ctxt - > options = oldOptions ;
2023-12-23 02:35:30 +03:00
return ( input ) ;
}
/*
* This global has to die eventually
*/
static xmlExternalEntityLoader
xmlCurrentExternalEntityLoader = xmlDefaultExternalEntityLoader ;
/**
* xmlSetExternalEntityLoader :
* @ f : the new entity resolver function
*
2024-06-11 04:51:43 +03:00
* DEPRECATED : This is a global setting and not thread - safe . Use
* xmlCtxtSetResourceLoader or similar functions .
*
* Changes the default external entity resolver function for the
* application .
2023-12-23 02:35:30 +03:00
*/
void
xmlSetExternalEntityLoader ( xmlExternalEntityLoader f ) {
xmlCurrentExternalEntityLoader = f ;
}
/**
* xmlGetExternalEntityLoader :
*
2024-06-11 04:51:43 +03:00
* DEPRECATED : See xmlSetExternalEntityLoader .
*
2023-12-23 02:35:30 +03:00
* Get the default external entity resolver function for the application
*
* Returns the xmlExternalEntityLoader function pointer
*/
xmlExternalEntityLoader
xmlGetExternalEntityLoader ( void ) {
return ( xmlCurrentExternalEntityLoader ) ;
}
2024-06-11 04:51:43 +03:00
/**
* xmlCtxtSetResourceLoader :
* @ ctxt : parser context
* @ loader : callback
* @ vctxt : user data
*
* Installs a custom callback to load documents , DTDs or external
* entities .
*
* Available since 2.14 .0 .
*/
void
xmlCtxtSetResourceLoader ( xmlParserCtxtPtr ctxt , xmlResourceLoader loader ,
void * vctxt ) {
if ( ctxt = = NULL )
return ;
ctxt - > resourceLoader = loader ;
ctxt - > resourceCtxt = vctxt ;
}
2024-06-11 20:10:41 +03:00
/**
* xmlLoadResource :
* @ ctxt : parser context
* @ url : the URL for the entity to load
* @ publicId : the Public ID for the entity to load
* @ type : resource type
*
* Returns the xmlParserInputPtr or NULL in case of error .
*/
xmlParserInputPtr
xmlLoadResource ( xmlParserCtxtPtr ctxt , const char * url , const char * publicId ,
xmlResourceType type ) {
char * canonicFilename ;
xmlParserInputPtr ret ;
if ( url = = NULL )
return ( NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > resourceLoader ! = NULL ) ) {
int flags = 0 ;
int code ;
if ( ( ctxt - > options & XML_PARSE_NO_UNZIP ) = = 0 )
flags | = XML_INPUT_UNZIP ;
if ( ( ctxt - > options & XML_PARSE_NONET ) = = 0 )
flags | = XML_INPUT_NETWORK ;
code = ctxt - > resourceLoader ( ctxt - > resourceCtxt , url , publicId , flags ,
type , & ret ) ;
if ( code ! = XML_ERR_OK ) {
xmlCtxtErrIO ( ctxt , code , url ) ;
return ( NULL ) ;
}
return ( ret ) ;
}
canonicFilename = ( char * ) xmlCanonicPath ( ( const xmlChar * ) url ) ;
if ( canonicFilename = = NULL ) {
xmlCtxtErrMemory ( ctxt ) ;
return ( NULL ) ;
}
ret = xmlCurrentExternalEntityLoader ( canonicFilename , publicId , ctxt ) ;
xmlFree ( canonicFilename ) ;
return ( ret ) ;
}
2023-12-23 02:35:30 +03:00
/**
* xmlLoadExternalEntity :
* @ URL : the URL for the entity to load
* @ ID : the Public ID for the entity to load
* @ ctxt : the context in which the entity is called or NULL
*
2024-06-10 15:04:00 +03:00
* @ URL is a filename or URL . If if contains the substring " :// " ,
* it is assumed to be a Legacy Extended IRI . Otherwise , it is
* treated as a filesystem path .
*
* @ ID is an optional XML public ID , typically from a doctype
* declaration . It is used for catalog lookups .
*
* The following resource loaders will be called if they were
* registered ( in order of precedence ) :
*
2024-06-11 04:51:43 +03:00
* - the resource loader set with xmlCtxtSetResourceLoader
2024-06-10 15:04:00 +03:00
* - the global external entity loader set with
* xmlSetExternalEntityLoader
* - the per - thread xmlParserInputBufferCreateFilenameFunc set with
* xmlParserInputBufferCreateFilenameDefault
* - the default loader which will return
* - the result from a matching global input callback set with
* xmlRegisterInputCallbacks
* - a HTTP resource if support is compiled in .
* - a file opened from the filesystem , with automatic detection
* of compressed files if support is compiled in .
*
2023-12-23 02:35:30 +03:00
* Returns the xmlParserInputPtr or NULL
*/
xmlParserInputPtr
xmlLoadExternalEntity ( const char * URL , const char * ID ,
xmlParserCtxtPtr ctxt ) {
2024-06-11 20:10:41 +03:00
return ( xmlLoadResource ( ctxt , URL , ID , XML_RESOURCE_UNKNOWN ) ) ;
2023-12-23 02:35:30 +03:00
}
2001-02-23 20:55:21 +03:00
/************************************************************************
* *
* Commodity functions to handle parser contexts *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
2022-08-24 05:21:58 +03:00
* xmlInitSAXParserCtxt :
* @ ctxt : XML parser context
* @ sax : SAX handlert
* @ userData : user data
2001-02-23 20:55:21 +03:00
*
2022-08-24 05:21:58 +03:00
* Initialize a SAX parser context
2003-04-24 20:06:47 +04:00
*
* Returns 0 in case of success and - 1 in case of error
2001-02-23 20:55:21 +03:00
*/
2022-08-24 05:21:58 +03:00
static int
2022-09-01 01:13:19 +03:00
xmlInitSAXParserCtxt ( xmlParserCtxtPtr ctxt , const xmlSAXHandler * sax ,
2022-08-24 05:21:58 +03:00
void * userData )
2001-02-23 20:55:21 +03:00
{
2004-11-09 17:59:59 +03:00
xmlParserInputPtr input ;
2023-12-10 19:50:22 +03:00
if ( ctxt = = NULL )
2003-04-24 20:06:47 +04:00
return ( - 1 ) ;
2001-08-31 18:55:30 +04:00
2004-11-02 17:52:23 +03:00
if ( ctxt - > dict = = NULL )
ctxt - > dict = xmlDictCreate ( ) ;
2023-12-10 19:50:22 +03:00
if ( ctxt - > dict = = NULL )
2003-08-18 16:15:38 +04:00
return ( - 1 ) ;
2012-07-30 06:08:45 +04:00
xmlDictSetLimit ( ctxt - > dict , XML_MAX_DICTIONARY_LIMIT ) ;
2004-11-02 17:52:23 +03:00
if ( ctxt - > sax = = NULL )
ctxt - > sax = ( xmlSAXHandler * ) xmlMalloc ( sizeof ( xmlSAXHandler ) ) ;
2023-12-10 19:50:22 +03:00
if ( ctxt - > sax = = NULL )
2003-04-24 20:06:47 +04:00
return ( - 1 ) ;
2022-08-24 05:21:58 +03:00
if ( sax = = NULL ) {
memset ( ctxt - > sax , 0 , sizeof ( xmlSAXHandler ) ) ;
2003-09-25 18:29:29 +04:00
xmlSAXVersion ( ctxt - > sax , 2 ) ;
2022-08-24 05:21:58 +03:00
ctxt - > userData = ctxt ;
} else {
if ( sax - > initialized = = XML_SAX2_MAGIC ) {
memcpy ( ctxt - > sax , sax , sizeof ( xmlSAXHandler ) ) ;
} else {
memset ( ctxt - > sax , 0 , sizeof ( xmlSAXHandler ) ) ;
memcpy ( ctxt - > sax , sax , sizeof ( xmlSAXHandlerV1 ) ) ;
}
ctxt - > userData = userData ? userData : ctxt ;
}
2001-02-23 20:55:21 +03:00
2003-08-19 19:01:28 +04:00
ctxt - > maxatts = 0 ;
ctxt - > atts = NULL ;
2001-02-23 20:55:21 +03:00
/* Allocate the Input stack */
2004-11-02 17:52:23 +03:00
if ( ctxt - > inputTab = = NULL ) {
ctxt - > inputTab = ( xmlParserInputPtr * )
xmlMalloc ( 5 * sizeof ( xmlParserInputPtr ) ) ;
ctxt - > inputMax = 5 ;
}
2023-12-10 19:50:22 +03:00
if ( ctxt - > inputTab = = NULL )
2003-04-24 20:06:47 +04:00
return ( - 1 ) ;
2004-11-09 17:59:59 +03:00
while ( ( input = inputPop ( ctxt ) ) ! = NULL ) { /* Non consuming */
xmlFreeInputStream ( input ) ;
}
2001-02-23 20:55:21 +03:00
ctxt - > inputNr = 0 ;
ctxt - > input = NULL ;
ctxt - > version = NULL ;
ctxt - > encoding = NULL ;
ctxt - > standalone = - 1 ;
ctxt - > hasExternalSubset = 0 ;
ctxt - > hasPErefs = 0 ;
ctxt - > html = 0 ;
ctxt - > instate = XML_PARSER_START ;
/* Allocate the Node stack */
2004-11-02 17:52:23 +03:00
if ( ctxt - > nodeTab = = NULL ) {
ctxt - > nodeTab = ( xmlNodePtr * ) xmlMalloc ( 10 * sizeof ( xmlNodePtr ) ) ;
ctxt - > nodeMax = 10 ;
}
2023-12-10 19:50:22 +03:00
if ( ctxt - > nodeTab = = NULL )
2003-04-24 20:06:47 +04:00
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
ctxt - > nodeNr = 0 ;
ctxt - > node = NULL ;
/* Allocate the Name stack */
2004-11-02 17:52:23 +03:00
if ( ctxt - > nameTab = = NULL ) {
ctxt - > nameTab = ( const xmlChar * * ) xmlMalloc ( 10 * sizeof ( xmlChar * ) ) ;
ctxt - > nameMax = 10 ;
}
2023-12-10 19:50:22 +03:00
if ( ctxt - > nameTab = = NULL )
2003-04-24 20:06:47 +04:00
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
ctxt - > nameNr = 0 ;
ctxt - > name = NULL ;
/* Allocate the space stack */
2004-11-02 17:52:23 +03:00
if ( ctxt - > spaceTab = = NULL ) {
ctxt - > spaceTab = ( int * ) xmlMalloc ( 10 * sizeof ( int ) ) ;
ctxt - > spaceMax = 10 ;
}
2023-12-10 19:50:22 +03:00
if ( ctxt - > spaceTab = = NULL )
2003-04-24 20:06:47 +04:00
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
ctxt - > spaceNr = 1 ;
ctxt - > spaceMax = 10 ;
ctxt - > spaceTab [ 0 ] = - 1 ;
ctxt - > space = & ctxt - > spaceTab [ 0 ] ;
ctxt - > myDoc = NULL ;
ctxt - > wellFormed = 1 ;
2003-09-12 03:42:01 +04:00
ctxt - > nsWellFormed = 1 ;
2001-02-23 20:55:21 +03:00
ctxt - > valid = 1 ;
2024-01-05 03:14:28 +03:00
ctxt - > options = XML_PARSE_NODICT ;
/*
* Initialize some parser options from deprecated global variables .
* Note that the " modern " API taking options arguments or
* xmlCtxtSetOptions will ignore these defaults . They ' re only
* relevant if old API functions like xmlParseFile are used .
*/
2001-02-23 20:55:21 +03:00
ctxt - > loadsubset = xmlLoadExtDtdDefaultValue ;
2014-06-11 12:59:16 +04:00
if ( ctxt - > loadsubset ) {
ctxt - > options | = XML_PARSE_DTDLOAD ;
}
2001-02-23 20:55:21 +03:00
ctxt - > validate = xmlDoValidityCheckingDefaultValue ;
2024-01-05 03:14:28 +03:00
if ( ctxt - > validate ) {
ctxt - > options | = XML_PARSE_DTDVALID ;
}
2001-02-23 20:55:21 +03:00
ctxt - > pedantic = xmlPedanticParserDefaultValue ;
2014-06-11 12:59:16 +04:00
if ( ctxt - > pedantic ) {
ctxt - > options | = XML_PARSE_PEDANTIC ;
}
2001-07-25 21:18:57 +04:00
ctxt - > linenumbers = xmlLineNumbersDefaultValue ;
2001-02-23 20:55:21 +03:00
ctxt - > keepBlanks = xmlKeepBlanksDefaultValue ;
2014-06-11 12:59:16 +04:00
if ( ctxt - > keepBlanks = = 0 ) {
2003-09-26 18:51:39 +04:00
ctxt - > sax - > ignorableWhitespace = xmlSAX2IgnorableWhitespace ;
2014-06-11 12:59:16 +04:00
ctxt - > options | = XML_PARSE_NOBLANKS ;
}
2024-01-05 03:14:28 +03:00
ctxt - > replaceEntities = xmlSubstituteEntitiesDefaultValue ;
if ( ctxt - > replaceEntities ) {
ctxt - > options | = XML_PARSE_NOENT ;
}
if ( xmlGetWarningsDefaultValue = = 0 )
ctxt - > options | = XML_PARSE_NOWARNING ;
2001-09-14 14:29:27 +04:00
2022-01-13 19:06:14 +03:00
ctxt - > vctxt . flags = XML_VCTXT_USE_PCTXT ;
2001-02-23 20:55:21 +03:00
ctxt - > vctxt . userData = ctxt ;
2002-02-03 23:13:06 +03:00
ctxt - > vctxt . error = xmlParserValidityError ;
ctxt - > vctxt . warning = xmlParserValidityWarning ;
2024-01-05 03:14:28 +03:00
2001-02-23 20:55:21 +03:00
ctxt - > record_info = 0 ;
ctxt - > checkIndex = 0 ;
ctxt - > inSubset = 0 ;
ctxt - > errNo = XML_ERR_OK ;
ctxt - > depth = 0 ;
2001-08-22 18:29:45 +04:00
ctxt - > catalogs = NULL ;
2013-02-19 06:21:49 +04:00
ctxt - > sizeentities = 0 ;
ctxt - > sizeentcopy = 0 ;
2012-05-15 07:18:40 +04:00
ctxt - > input_id = 1 ;
2023-08-20 21:48:10 +03:00
ctxt - > maxAmpl = XML_MAX_AMPLIFICATION_DEFAULT ;
2001-02-23 20:55:21 +03:00
xmlInitNodeInfoSeq ( & ctxt - > node_seq ) ;
2023-10-02 13:16:05 +03:00
if ( ctxt - > nsdb = = NULL ) {
ctxt - > nsdb = xmlParserNsCreate ( ) ;
2024-06-11 17:19:58 +03:00
if ( ctxt - > nsdb = = NULL )
2023-10-02 13:16:05 +03:00
return ( - 1 ) ;
}
2003-04-24 20:06:47 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2022-08-24 05:21:58 +03:00
/**
* xmlInitParserCtxt :
* @ ctxt : an XML parser context
*
* DEPRECATED : Internal function which will be made private in a future
* version .
*
* Initialize a parser context
*
* Returns 0 in case of success and - 1 in case of error
*/
int
xmlInitParserCtxt ( xmlParserCtxtPtr ctxt )
{
return ( xmlInitSAXParserCtxt ( ctxt , NULL , NULL ) ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlFreeParserCtxt :
* @ ctxt : an XML parser context
*
* Free all the memory used by a parser context . However the parsed
* document in ctxt - > myDoc is not freed .
*/
void
xmlFreeParserCtxt ( xmlParserCtxtPtr ctxt )
{
xmlParserInputPtr input ;
if ( ctxt = = NULL ) return ;
while ( ( input = inputPop ( ctxt ) ) ! = NULL ) { /* Non consuming */
xmlFreeInputStream ( input ) ;
}
if ( ctxt - > spaceTab ! = NULL ) xmlFree ( ctxt - > spaceTab ) ;
2003-08-28 14:34:33 +04:00
if ( ctxt - > nameTab ! = NULL ) xmlFree ( ( xmlChar * * ) ctxt - > nameTab ) ;
2001-02-23 20:55:21 +03:00
if ( ctxt - > nodeTab ! = NULL ) xmlFree ( ctxt - > nodeTab ) ;
2010-03-15 17:16:02 +03:00
if ( ctxt - > nodeInfoTab ! = NULL ) xmlFree ( ctxt - > nodeInfoTab ) ;
2001-02-23 20:55:21 +03:00
if ( ctxt - > inputTab ! = NULL ) xmlFree ( ctxt - > inputTab ) ;
if ( ctxt - > version ! = NULL ) xmlFree ( ( char * ) ctxt - > version ) ;
if ( ctxt - > encoding ! = NULL ) xmlFree ( ( char * ) ctxt - > encoding ) ;
if ( ctxt - > extSubURI ! = NULL ) xmlFree ( ( char * ) ctxt - > extSubURI ) ;
if ( ctxt - > extSubSystem ! = NULL ) xmlFree ( ( char * ) ctxt - > extSubSystem ) ;
2003-09-30 04:43:48 +04:00
# ifdef LIBXML_SAX1_ENABLED
2003-09-25 18:29:29 +04:00
if ( ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax ! = ( xmlSAXHandlerPtr ) & xmlDefaultSAXHandler ) )
2003-09-30 04:43:48 +04:00
# else
if ( ctxt - > sax ! = NULL )
# endif /* LIBXML_SAX1_ENABLED */
2001-02-23 20:55:21 +03:00
xmlFree ( ctxt - > sax ) ;
2001-06-19 15:07:54 +04:00
if ( ctxt - > vctxt . nodeTab ! = NULL ) xmlFree ( ctxt - > vctxt . nodeTab ) ;
2003-08-28 14:34:33 +04:00
if ( ctxt - > atts ! = NULL ) xmlFree ( ( xmlChar * * ) ctxt - > atts ) ;
2003-08-18 16:15:38 +04:00
if ( ctxt - > dict ! = NULL ) xmlDictFree ( ctxt - > dict ) ;
2023-09-29 01:18:44 +03:00
if ( ctxt - > nsTab ! = NULL ) xmlFree ( ctxt - > nsTab ) ;
if ( ctxt - > nsdb ! = NULL ) xmlParserNsFree ( ctxt - > nsdb ) ;
if ( ctxt - > attrHash ! = NULL ) xmlFree ( ctxt - > attrHash ) ;
2003-09-10 14:50:59 +04:00
if ( ctxt - > pushTab ! = NULL ) xmlFree ( ctxt - > pushTab ) ;
if ( ctxt - > attallocs ! = NULL ) xmlFree ( ctxt - > attallocs ) ;
2012-09-11 09:26:36 +04:00
if ( ctxt - > attsDefault ! = NULL )
2017-11-09 18:42:47 +03:00
xmlHashFree ( ctxt - > attsDefault , xmlHashDefaultDeallocator ) ;
2003-09-10 14:50:59 +04:00
if ( ctxt - > attsSpecial ! = NULL )
xmlHashFree ( ctxt - > attsSpecial , NULL ) ;
2003-09-17 14:26:25 +04:00
if ( ctxt - > freeElems ! = NULL ) {
xmlNodePtr cur , next ;
cur = ctxt - > freeElems ;
while ( cur ! = NULL ) {
next = cur - > next ;
xmlFree ( cur ) ;
cur = next ;
}
}
if ( ctxt - > freeAttrs ! = NULL ) {
xmlAttrPtr cur , next ;
cur = ctxt - > freeAttrs ;
while ( cur ! = NULL ) {
next = cur - > next ;
xmlFree ( cur ) ;
cur = next ;
}
}
2003-10-03 02:28:19 +04:00
/*
* cleanup the error strings
*/
if ( ctxt - > lastError . message ! = NULL )
xmlFree ( ctxt - > lastError . message ) ;
if ( ctxt - > lastError . file ! = NULL )
xmlFree ( ctxt - > lastError . file ) ;
if ( ctxt - > lastError . str1 ! = NULL )
xmlFree ( ctxt - > lastError . str1 ) ;
if ( ctxt - > lastError . str2 ! = NULL )
xmlFree ( ctxt - > lastError . str2 ) ;
if ( ctxt - > lastError . str3 ! = NULL )
xmlFree ( ctxt - > lastError . str3 ) ;
2003-09-07 13:14:37 +04:00
2001-08-22 18:29:45 +04:00
# ifdef LIBXML_CATALOG_ENABLED
if ( ctxt - > catalogs ! = NULL )
xmlCatalogFreeLocal ( ctxt - > catalogs ) ;
# endif
2001-02-23 20:55:21 +03:00
xmlFree ( ctxt ) ;
}
/**
* xmlNewParserCtxt :
*
* Allocate and initialize a new parser context .
*
* Returns the xmlParserCtxtPtr or NULL
*/
xmlParserCtxtPtr
2005-07-30 02:02:24 +04:00
xmlNewParserCtxt ( void )
2022-08-24 05:21:58 +03:00
{
return ( xmlNewSAXParserCtxt ( NULL , NULL ) ) ;
}
/**
* xmlNewSAXParserCtxt :
* @ sax : SAX handler
* @ userData : user data
*
2022-09-01 01:13:19 +03:00
* Allocate and initialize a new SAX parser context . If userData is NULL ,
* the parser context will be passed as user data .
2022-08-24 05:21:58 +03:00
*
2023-12-27 20:33:30 +03:00
* Available since 2.11 .0 . If you want support older versions ,
* it ' s best to invoke xmlNewParserCtxt and set ctxt - > sax with
* struct assignment .
*
2022-09-01 01:13:19 +03:00
* Returns the xmlParserCtxtPtr or NULL if memory allocation failed .
2022-08-24 05:21:58 +03:00
*/
xmlParserCtxtPtr
2022-09-01 01:13:19 +03:00
xmlNewSAXParserCtxt ( const xmlSAXHandler * sax , void * userData )
2001-02-23 20:55:21 +03:00
{
xmlParserCtxtPtr ctxt ;
2023-12-27 20:33:30 +03:00
xmlInitParser ( ) ;
2001-02-23 20:55:21 +03:00
ctxt = ( xmlParserCtxtPtr ) xmlMalloc ( sizeof ( xmlParserCtxt ) ) ;
2023-12-10 19:50:22 +03:00
if ( ctxt = = NULL )
2001-02-23 20:55:21 +03:00
return ( NULL ) ;
memset ( ctxt , 0 , sizeof ( xmlParserCtxt ) ) ;
2022-08-24 05:21:58 +03:00
if ( xmlInitSAXParserCtxt ( ctxt , sax , userData ) < 0 ) {
2003-04-24 20:06:47 +04:00
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
2001-02-23 20:55:21 +03:00
return ( ctxt ) ;
}
/************************************************************************
* *
2020-03-08 19:19:42 +03:00
* Handling of node information *
2001-02-23 20:55:21 +03:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlClearParserCtxt :
* @ ctxt : an XML parser context
*
* Clear ( release owned resources ) and reinitialize a parser context
*/
void
xmlClearParserCtxt ( xmlParserCtxtPtr ctxt )
{
2001-08-31 18:55:30 +04:00
if ( ctxt = = NULL )
return ;
2001-02-23 20:55:21 +03:00
xmlClearNodeInfoSeq ( & ctxt - > node_seq ) ;
2004-11-02 17:52:23 +03:00
xmlCtxtReset ( ctxt ) ;
2001-02-23 20:55:21 +03:00
}
2004-11-05 20:22:25 +03:00
2001-02-23 20:55:21 +03:00
/**
* xmlParserFindNodeInfo :
2002-12-10 18:19:08 +03:00
* @ ctx : an XML parser context
2001-02-23 20:55:21 +03:00
* @ node : an XML node within the tree
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Don ' t use .
*
2001-02-23 20:55:21 +03:00
* Find the parser node info struct for a given node
2012-09-11 09:26:36 +04:00
*
2001-02-23 20:55:21 +03:00
* Returns an xmlParserNodeInfo block pointer or NULL
*/
2004-11-05 20:22:25 +03:00
const xmlParserNodeInfo *
2023-11-23 17:22:59 +03:00
xmlParserFindNodeInfo ( xmlParserCtxtPtr ctx , xmlNodePtr node )
2001-02-23 20:55:21 +03:00
{
2004-11-05 20:22:25 +03:00
unsigned long pos ;
if ( ( ctx = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
/* Find position where node should be at */
pos = xmlParserFindNodeInfoIndex ( & ctx - > node_seq , node ) ;
if ( pos < ctx - > node_seq . length
& & ctx - > node_seq . buffer [ pos ] . node = = node )
return & ctx - > node_seq . buffer [ pos ] ;
else
return NULL ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlInitNodeInfoSeq :
* @ seq : a node info sequence pointer
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Don ' t use .
*
2001-02-23 20:55:21 +03:00
* - - Initialize ( set to initial state ) node info sequence
*/
void
xmlInitNodeInfoSeq ( xmlParserNodeInfoSeqPtr seq )
{
2004-11-05 20:22:25 +03:00
if ( seq = = NULL )
return ;
seq - > length = 0 ;
seq - > maximum = 0 ;
seq - > buffer = NULL ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlClearNodeInfoSeq :
* @ seq : a node info sequence pointer
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Don ' t use .
*
2001-02-23 20:55:21 +03:00
* - - Clear ( release memory and reinitialize ) node
* info sequence
*/
void
xmlClearNodeInfoSeq ( xmlParserNodeInfoSeqPtr seq )
{
2004-11-05 20:22:25 +03:00
if ( seq = = NULL )
return ;
if ( seq - > buffer ! = NULL )
xmlFree ( seq - > buffer ) ;
xmlInitNodeInfoSeq ( seq ) ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlParserFindNodeInfoIndex :
* @ seq : a node info sequence pointer
* @ node : an XML node pointer
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Don ' t use .
2012-09-11 09:26:36 +04:00
*
2001-02-23 20:55:21 +03:00
* xmlParserFindNodeInfoIndex : Find the index that the info record for
* the given node is or should be at in a sorted sequence
*
* Returns a long indicating the position of the record
*/
2004-11-05 20:22:25 +03:00
unsigned long
2023-11-23 17:22:59 +03:00
xmlParserFindNodeInfoIndex ( xmlParserNodeInfoSeqPtr seq ,
xmlNodePtr node )
2001-02-23 20:55:21 +03:00
{
2004-11-05 20:22:25 +03:00
unsigned long upper , lower , middle ;
int found = 0 ;
if ( ( seq = = NULL ) | | ( node = = NULL ) )
2005-12-10 14:11:12 +03:00
return ( ( unsigned long ) - 1 ) ;
2004-11-05 20:22:25 +03:00
/* Do a binary search for the key */
lower = 1 ;
upper = seq - > length ;
middle = 0 ;
while ( lower < = upper & & ! found ) {
middle = lower + ( upper - lower ) / 2 ;
if ( node = = seq - > buffer [ middle - 1 ] . node )
found = 1 ;
else if ( node < seq - > buffer [ middle - 1 ] . node )
upper = middle - 1 ;
else
lower = middle + 1 ;
}
/* Return position */
if ( middle = = 0 | | seq - > buffer [ middle - 1 ] . node < node )
return middle ;
2001-02-23 20:55:21 +03:00
else
2004-11-05 20:22:25 +03:00
return middle - 1 ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlParserAddNodeInfo :
* @ ctxt : an XML parser context
* @ info : a node info sequence pointer
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Don ' t use .
*
2001-02-23 20:55:21 +03:00
* Insert node info record into the sorted sequence
*/
void
2002-01-23 20:53:44 +03:00
xmlParserAddNodeInfo ( xmlParserCtxtPtr ctxt ,
2023-11-23 17:22:59 +03:00
xmlParserNodeInfoPtr info )
2001-02-23 20:55:21 +03:00
{
2002-01-23 20:53:44 +03:00
unsigned long pos ;
2004-11-05 20:22:25 +03:00
if ( ( ctxt = = NULL ) | | ( info = = NULL ) ) return ;
2002-01-23 20:53:44 +03:00
/* Find pos and check to see if node is already in the sequence */
2003-07-31 18:47:38 +04:00
pos = xmlParserFindNodeInfoIndex ( & ctxt - > node_seq , ( xmlNodePtr )
2002-01-23 20:53:44 +03:00
info - > node ) ;
2006-03-09 17:13:55 +03:00
2012-09-11 09:26:36 +04:00
if ( ( pos < ctxt - > node_seq . length ) & &
2006-03-09 17:13:55 +03:00
( ctxt - > node_seq . buffer ! = NULL ) & &
( ctxt - > node_seq . buffer [ pos ] . node = = info - > node ) ) {
2002-01-23 20:53:44 +03:00
ctxt - > node_seq . buffer [ pos ] = * info ;
}
2001-02-23 20:55:21 +03:00
2002-01-23 20:53:44 +03:00
/* Otherwise, we need to add new node to buffer */
else {
2013-08-03 18:25:13 +04:00
if ( ( ctxt - > node_seq . length + 1 > ctxt - > node_seq . maximum ) | |
( ctxt - > node_seq . buffer = = NULL ) ) {
2002-01-23 20:53:44 +03:00
xmlParserNodeInfo * tmp_buffer ;
unsigned int byte_size ;
if ( ctxt - > node_seq . maximum = = 0 )
ctxt - > node_seq . maximum = 2 ;
byte_size = ( sizeof ( * ctxt - > node_seq . buffer ) *
( 2 * ctxt - > node_seq . maximum ) ) ;
if ( ctxt - > node_seq . buffer = = NULL )
2003-04-22 03:07:45 +04:00
tmp_buffer = ( xmlParserNodeInfo * ) xmlMalloc ( byte_size ) ;
2002-01-23 20:53:44 +03:00
else
tmp_buffer =
( xmlParserNodeInfo * ) xmlRealloc ( ctxt - > node_seq . buffer ,
byte_size ) ;
if ( tmp_buffer = = NULL ) {
2023-12-20 02:33:34 +03:00
xmlCtxtErrMemory ( ctxt ) ;
2002-01-23 20:53:44 +03:00
return ;
}
ctxt - > node_seq . buffer = tmp_buffer ;
ctxt - > node_seq . maximum * = 2 ;
}
2001-02-23 20:55:21 +03:00
2002-01-23 20:53:44 +03:00
/* If position is not at end, move elements out of the way */
if ( pos ! = ctxt - > node_seq . length ) {
unsigned long i ;
2001-02-23 20:55:21 +03:00
2002-01-23 20:53:44 +03:00
for ( i = ctxt - > node_seq . length ; i > pos ; i - - )
ctxt - > node_seq . buffer [ i ] = ctxt - > node_seq . buffer [ i - 1 ] ;
}
2001-02-23 20:55:21 +03:00
2002-01-23 20:53:44 +03:00
/* Copy element and increase length */
ctxt - > node_seq . buffer [ pos ] = * info ;
ctxt - > node_seq . length + + ;
2001-02-23 20:55:21 +03:00
}
}
2001-07-25 21:18:57 +04:00
/************************************************************************
* *
* Defaults settings *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlPedanticParserDefault :
2012-09-11 09:26:36 +04:00
* @ val : int 0 or 1
2001-07-25 21:18:57 +04:00
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Use the modern options API with XML_PARSE_PEDANTIC .
*
2001-07-25 21:18:57 +04:00
* Set and return the previous value for enabling pedantic warnings .
*
* Returns the last value for 0 for no substitution , 1 for substitution .
*/
int
xmlPedanticParserDefault ( int val ) {
int old = xmlPedanticParserDefaultValue ;
xmlPedanticParserDefaultValue = val ;
return ( old ) ;
}
/**
* xmlLineNumbersDefault :
2012-09-11 09:26:36 +04:00
* @ val : int 0 or 1
2001-07-25 21:18:57 +04:00
*
2022-08-24 16:55:46 +03:00
* DEPRECATED : The modern options API always enables line numbers .
*
2001-07-25 21:18:57 +04:00
* Set and return the previous value for enabling line numbers in elements
* contents . This may break on old application and is turned off by default .
*
* Returns the last value for 0 for no substitution , 1 for substitution .
*/
int
xmlLineNumbersDefault ( int val ) {
int old = xmlLineNumbersDefaultValue ;
xmlLineNumbersDefaultValue = val ;
return ( old ) ;
}
/**
* xmlSubstituteEntitiesDefault :
2012-09-11 09:26:36 +04:00
* @ val : int 0 or 1
2001-07-25 21:18:57 +04:00
*
2022-08-24 16:12:24 +03:00
* DEPRECATED : Use the modern options API with XML_PARSE_NOENT .
*
2001-07-25 21:18:57 +04:00
* Set and return the previous value for default entity support .
* Initially the parser always keep entity references instead of substituting
* entity values in the output . This function has to be used to change the
2001-12-31 19:16:02 +03:00
* default parser behavior
* SAX : : substituteEntities ( ) has to be used for changing that on a file by
2001-07-25 21:18:57 +04:00
* file basis .
*
* Returns the last value for 0 for no substitution , 1 for substitution .
*/
int
xmlSubstituteEntitiesDefault ( int val ) {
int old = xmlSubstituteEntitiesDefaultValue ;
xmlSubstituteEntitiesDefaultValue = val ;
return ( old ) ;
}
/**
* xmlKeepBlanksDefault :
2012-09-11 09:26:36 +04:00
* @ val : int 0 or 1
2001-07-25 21:18:57 +04:00
*
2022-08-24 16:55:46 +03:00
* DEPRECATED : Use the modern options API with XML_PARSE_NOBLANKS .
*
2001-07-25 21:18:57 +04:00
* Set and return the previous value for default blanks text nodes support .
* The 1. x version of the parser used an heuristic to try to detect
* ignorable white spaces . As a result the SAX callback was generating
2003-09-26 18:51:39 +04:00
* xmlSAX2IgnorableWhitespace ( ) callbacks instead of characters ( ) one , and when
2001-07-25 21:18:57 +04:00
* using the DOM output text nodes containing those blanks were not generated .
* The 2. x and later version will switch to the XML standard way and
* ignorableWhitespace ( ) are only generated when running the parser in
* validating mode and when the current element doesn ' t allow CDATA or
* mixed content .
2012-09-11 09:26:36 +04:00
* This function is provided as a way to force the standard behavior
2001-07-25 21:18:57 +04:00
* on 1. X libs and to switch back to the old mode for compatibility when
* running 1. X client code on 2. X . Upgrade of 1. X code should be done
* by using xmlIsBlankNode ( ) commodity function to detect the " empty "
* nodes generated .
* This value also affect autogeneration of indentation when saving code
* if blanks sections are kept , indentation is not generated .
*
* Returns the last value for 0 for no substitution , 1 for substitution .
*/
int
xmlKeepBlanksDefault ( int val ) {
int old = xmlKeepBlanksDefaultValue ;
xmlKeepBlanksDefaultValue = val ;
2023-09-20 18:54:48 +03:00
# ifdef LIBXML_OUTPUT_ENABLED
if ( ! val )
xmlIndentTreeOutput = 1 ;
# endif
2001-07-25 21:18:57 +04:00
return ( old ) ;
}