SAX2.c revision 06c93b75095ddca6ba80e45dd381bb69cd04b9f6
198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor/* 298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * SAX2.c : Default SAX2 handler to build a tree. 398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * 498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * See Copyright for the status of this software. 598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * 698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * Daniel Veillard <daniel@veillard.com> 798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor */ 898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor 998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor 1098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#define IN_LIBXML 1198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include "libxml.h" 1298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include <stdlib.h> 1398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include <string.h> 14a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#include <limits.h> 156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include <libxml/xmlmemory.h> 16677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor#include <libxml/tree.h> 17188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor#include <libxml/parser.h> 18ae0cdff0b83e59c7fe769baf171d1ba194ad8b88Benjamin Kramer#include <libxml/parserInternals.h> 1998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include <libxml/valid.h> 208229d22e6449851b89361bf2f41804557328be63Rafael Espindola#include <libxml/entities.h> 2198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include <libxml/xmlerror.h> 22c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include <libxml/debugXML.h> 2398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include <libxml/xmlIO.h> 242492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#include <libxml/SAX.h> 252492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#include <libxml/uri.h> 262492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#include <libxml/valid.h> 272492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#include <libxml/HTMLtree.h> 2898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include <libxml/globals.h> 2998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor 3098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor/* Define SIZE_T_MAX unless defined through <limits.h>. */ 311a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor#ifndef SIZE_T_MAX 32ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor# define SIZE_T_MAX ((size_t)-1) 33ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor#endif /* !SIZE_T_MAX */ 34c544ba09695e300f31355af342258bd57619e737Douglas Gregor 35c544ba09695e300f31355af342258bd57619e737Douglas Gregor/* #define DEBUG_SAX2 */ 36c544ba09695e300f31355af342258bd57619e737Douglas Gregor/* #define DEBUG_SAX2_TREE */ 376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 38c544ba09695e300f31355af342258bd57619e737Douglas Gregor/** 39c544ba09695e300f31355af342258bd57619e737Douglas Gregor * TODO: 40c544ba09695e300f31355af342258bd57619e737Douglas Gregor * 41c544ba09695e300f31355af342258bd57619e737Douglas Gregor * macro to flag unimplemented blocks 42c544ba09695e300f31355af342258bd57619e737Douglas Gregor * XML_CATALOG_PREFER user env to select between system/public prefered 43c544ba09695e300f31355af342258bd57619e737Douglas Gregor * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk> 446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with 45c544ba09695e300f31355af342258bd57619e737Douglas Gregor *> values "system" and "public". I have made the default be "system" to 46c544ba09695e300f31355af342258bd57619e737Douglas Gregor *> match yours. 4798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor */ 4898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#define TODO \ 49176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines xmlGenericError(xmlGenericErrorContext, \ 50176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "Unimplemented block at %s:%d\n", \ 51ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor __FILE__, __LINE__); 52ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor 53176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/* 5498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * xmlSAX2ErrMemory: 5598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * @ctxt: an XML validation parser context 56677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor * @msg: a string to accompany the error message 5787e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor */ 5887e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregorstatic void 59677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas GregorxmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) { 60677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor if (ctxt != NULL) { 61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg); 63677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->errNo = XML_ERR_NO_MEMORY; 64677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->instate = XML_PARSER_EOF; 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ctxt->disableSAX = 1; 66677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor } 67677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor} 68677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor 69677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor/** 700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines * xmlValidError: 710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines * @ctxt: an XML validation parser context 720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines * @error: the error number 730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines * @msg: the error message 740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines * @str1: extra data 750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines * @str2: extra data 760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines * 77edadb9a879e14b3732461316a83ffc4c3482ad19Eli Friedman * Handle a validation error 78edadb9a879e14b3732461316a83ffc4c3482ad19Eli Friedman */ 79677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregorstatic void 80edadb9a879e14b3732461316a83ffc4c3482ad19Eli FriedmanxmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error, 81677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor const char *msg, const char *str1, const char *str2) 8298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor{ 83edadb9a879e14b3732461316a83ffc4c3482ad19Eli Friedman xmlStructuredErrorFunc schannel = NULL; 84677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor 8598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 86677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor (ctxt->instate == XML_PARSER_EOF)) 87677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor return; 881a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor if (ctxt != NULL) { 8998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor ctxt->errNo = error; 9098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) 9198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor schannel = ctxt->sax->serror; 92057df20b3107cef764052d271c89b8591b98b3ceDouglas Gregor __xmlRaiseError(schannel, 93cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor ctxt->vctxt.error, ctxt->vctxt.userData, 9498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor ctxt, NULL, XML_FROM_DTD, error, 95d64c26f6676eef69d1713f353ca8a3c2fe963f17Argyrios Kyrtzidis XML_ERR_ERROR, NULL, 0, (const char *) str1, 9687e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor (const char *) str2, NULL, 0, 0, 9798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor msg, (const char *) str1, (const char *) str2); 98a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ctxt->valid = 0; 99a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else { 100b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar __xmlRaiseError(schannel, 101b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar NULL, NULL, 10298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor ctxt, NULL, XML_FROM_DTD, error, 10398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor XML_ERR_ERROR, NULL, 0, (const char *) str1, 10487e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor (const char *) str2, NULL, 0, 0, 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines msg, (const char *) str1, (const char *) str2); 106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/** 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * xmlFatalErrMsg: 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * @ctxt: an XML parser context 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * @error: the error number 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * @msg: the error message 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * @str1: an error string 11598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * @str2: an error string 116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * 11798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * Handle a fatal parser error, i.e. violating Well-Formedness constraints 118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines */ 11998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorstatic void 12098339b96a8089a6da715487e432c5abfca0ca0dfDouglas GregorxmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const char *msg, const xmlChar *str1, const xmlChar *str2) 122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines{ 12398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (ctxt->instate == XML_PARSER_EOF)) 125c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return; 126c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (ctxt != NULL) 127c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ctxt->errNo = error; 128c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, 129c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines XML_ERR_FATAL, NULL, 0, 130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (const char *) str1, (const char *) str2, 131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NULL, 0, 0, msg, str1, str2); 132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ctxt != NULL) { 133c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ctxt->wellFormed = 0; 134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ctxt->valid = 0; 135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ctxt->recovery == 0) 136176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ctxt->disableSAX = 1; 137677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor } 138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 140176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/** 14198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * xmlWarnMsg: 142a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * @ctxt: an XML parser context 143a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * @error: the error number 144a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * @msg: the error message 145677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor * @str1: an error string 146176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * @str2: an error string 147176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * 148176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * Handle a parser warning 149176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines */ 150176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic void 151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesxmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 152176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const char *msg, const xmlChar *str1) 153176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines{ 154176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 155176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (ctxt->instate == XML_PARSER_EOF)) 156176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 157176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ctxt != NULL) 158176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ctxt->errNo = error; 159176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, 160176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines XML_ERR_WARNING, NULL, 0, 161176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (const char *) str1, NULL, 162b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar NULL, 0, 0, msg, str1); 163176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 164a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 165a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar/** 166b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar * xmlNsErrMsg: 167b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar * @ctxt: an XML parser context 168b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar * @error: the error number 169b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar * @msg: the error message 170176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * @str1: an error string 171176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * @str2: an error string 172176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * 173176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * Handle a namespace error 174176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines */ 17598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorstatic void 17698339b96a8089a6da715487e432c5abfca0ca0dfDouglas GregorxmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 17798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor const char *msg, const xmlChar *str1, const xmlChar *str2) 17898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor{ 17998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 18087e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor (ctxt->instate == XML_PARSER_EOF)) 18187e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor return; 18287e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor if (ctxt != NULL) 18398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor ctxt->errNo = error; 18498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, 185677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor XML_ERR_ERROR, NULL, 0, 186677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor (const char *) str1, (const char *) str2, 187677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor NULL, 0, 0, msg, str1, str2); 18898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor} 18998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor 190c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/** 191c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * xmlNsWarnMsg: 192c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * @ctxt: an XML parser context 193c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * @error: the error number 1947cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor * @msg: the error message 1957cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor * @str1: an error string 1967cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor * 197a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * Handle a namespace warning 198a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar */ 199a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarstatic void 2007cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas GregorxmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 2017cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor const char *msg, const xmlChar *str1, const xmlChar *str2) 2027cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor{ 203b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 204b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar (ctxt->instate == XML_PARSER_EOF)) 205b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar return; 2067cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor if (ctxt != NULL) 2077cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor ctxt->errNo = error; 208b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, 2097cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor XML_ERR_WARNING, NULL, 0, 210b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar (const char *) str1, (const char *) str2, 211b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar NULL, 0, 0, msg, str1, str2); 2127cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor} 213a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 214a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar/** 215a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * xmlSAX2GetPublicId: 216a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * @ctx: the user data (XML parser context) 217a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * 218a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN" 219a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * 220a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * Returns a xmlChar * 221a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar */ 2227cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregorconst xmlChar * 2237cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas GregorxmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED) 2247cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor{ 225677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 226677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor return(NULL); 2276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 228677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor 2296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/** 230677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor * xmlSAX2GetSystemId: 231677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor * @ctx: the user data (XML parser context) 232c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * 233c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * Provides the system ID, basically URL or filename e.g. 234c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * http://www.sgmlsource.com/dtds/memo.dtd 235c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * 236c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines * Returns a xmlChar * 237c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines */ 238c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesconst xmlChar * 2397cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas GregorxmlSAX2GetSystemId(void *ctx) 2407cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor{ 2417cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2427cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL); 2437cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor return((const xmlChar *) ctxt->input->filename); 2447cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor} 2457cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor 246176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/** 247176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * xmlSAX2GetLineNumber: 248176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * @ctx: the user data (XML parser context) 249176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * 250176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * Provide the line number of the current parsing point. 251176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * 252176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines * Returns an int 25398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor */ 25498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorint 255d3cf5fba332fc77f7e72ef58077822606718671dDouglas GregorxmlSAX2GetLineNumber(void *ctx) 256d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor{ 257d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 258d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor if ((ctx == NULL) || (ctxt->input == NULL)) return(0); 259d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor return(ctxt->input->line); 2606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 261d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor 262d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor/** 263d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor * xmlSAX2GetColumnNumber: 264d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor * @ctx: the user data (XML parser context) 265d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor * 266d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor * Provide the column number of the current parsing point. 267d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor * 268d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor * Returns an int 2696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines */ 270d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregorint 271d3cf5fba332fc77f7e72ef58077822606718671dDouglas GregorxmlSAX2GetColumnNumber(void *ctx) 272d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor{ 273d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 274188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor if ((ctx == NULL) || (ctxt->input == NULL)) return(0); 275188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor return(ctxt->input->col); 276fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor} 277fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor 278fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor/** 279677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor * xmlSAX2IsStandalone: 280fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor * @ctx: the user data (XML parser context) 281fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor * 282fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor * Is this document tagged standalone ? 283fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor * 284fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor * Returns 1 if true 285fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor */ 286fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregorint 287fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas GregorxmlSAX2IsStandalone(void *ctx) 288fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor{ 289fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 290fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0); 291fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor return(ctxt->myDoc->standalone == 1); 292fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor} 293fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor 294fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor/** 295188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor * xmlSAX2HasInternalSubset: 296188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor * @ctx: the user data (XML parser context) 297a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * 298a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * Does this document has an internal subset 299a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * 300a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * Returns 1 if true 30198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor */ 30298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorint 30398339b96a8089a6da715487e432c5abfca0ca0dfDouglas GregorxmlSAX2HasInternalSubset(void *ctx) 30498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor{ 305d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 30698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0); 30798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor return(ctxt->myDoc->intSubset != NULL); 308a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 309a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 310188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor/** 311d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * xmlSAX2HasExternalSubset: 312d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * @ctx: the user data (XML parser context) 313d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * 314d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * Does this document has an external subset 315d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * 316d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * Returns 1 if true 317d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor */ 318d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregorint 319d07865b42dcb32154c75134fded51b38cc55a0c4Douglas GregorxmlSAX2HasExternalSubset(void *ctx) 320d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor{ 321d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 322a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0); 323a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return(ctxt->myDoc->extSubset != NULL); 324a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 325a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 326a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar/** 327d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * xmlSAX2InternalSubset: 328cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor * @ctx: the user data (XML parser context) 329d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * @name: the root element name 330d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * @ExternalID: the external ID 331d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * @SystemID: the SYSTEM ID (e.g. filename or URL) 332a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * 333a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar * Callback on internal subset declaration. 334d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor */ 335d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregorvoid 336d07865b42dcb32154c75134fded51b38cc55a0c4Douglas GregorxmlSAX2InternalSubset(void *ctx, const xmlChar *name, 337d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor const xmlChar *ExternalID, const xmlChar *SystemID) 338a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar{ 339a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 340d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlDtdPtr dtd; 341d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor if (ctx == NULL) return; 342d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor#ifdef DEBUG_SAX 343d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlGenericError(xmlGenericErrorContext, 344d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n", 345d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor name, ExternalID, SystemID); 346d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor#endif 347d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor 348d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor if (ctxt->myDoc == NULL) 349d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor return; 350d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor dtd = xmlGetIntSubset(ctxt->myDoc); 351d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor if (dtd != NULL) { 352188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor if (ctxt->html) 353d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor return; 3546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines xmlUnlinkNode((xmlNodePtr) dtd); 35598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor xmlFreeDtd(dtd); 356cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor ctxt->myDoc->intSubset = NULL; 357d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor } 358d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor ctxt->myDoc->intSubset = 359d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID); 360188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor if (ctxt->myDoc->intSubset == NULL) 361188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset"); 362188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor} 363188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor 364188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor/** 365188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor * xmlSAX2ExternalSubset: 366188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor * @ctx: the user data (XML parser context) 367677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor * @name: the root element name 368d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor * @ExternalID: the external ID 369188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor * @SystemID: the SYSTEM ID (e.g. filename or URL) 370188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor * 371188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor * Callback on external subset declaration. 372d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor */ 373d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregorvoid 374d07865b42dcb32154c75134fded51b38cc55a0c4Douglas GregorxmlSAX2ExternalSubset(void *ctx, const xmlChar *name, 375d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor const xmlChar *ExternalID, const xmlChar *SystemID) 37698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor{ 377d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 378d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor if (ctx == NULL) return; 379d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor#ifdef DEBUG_SAX 380d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor xmlGenericError(xmlGenericErrorContext, 381a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n", 382d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor name, ExternalID, SystemID); 383d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor#endif 384d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor if (((ExternalID != NULL) || (SystemID != NULL)) && 385d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor (((ctxt->validate) || (ctxt->loadsubset != 0)) && 386d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor (ctxt->wellFormed && ctxt->myDoc))) { 387d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor /* 388d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor * Try to fetch and parse the external subset. 389d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor */ 390d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlParserInputPtr oldinput; 391d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor int oldinputNr; 392d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor int oldinputMax; 393d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlParserInputPtr *oldinputTab; 394d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor xmlParserInputPtr input = NULL; 395d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor xmlCharEncoding enc; 396d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor int oldcharset; 397d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor 39898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor /* 39998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * Ask the Entity resolver to load the damn thing 400d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor */ 401d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL)) 402d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, 403d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor SystemID); 404d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor if (input == NULL) { 405344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm return; 406d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor } 40798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor 408d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID); 409d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor 41098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor /* 41198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor * make sure we won't destroy the main document context 412677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor */ 413677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor oldinput = ctxt->input; 414677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor oldinputNr = ctxt->inputNr; 415677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor oldinputMax = ctxt->inputMax; 4166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines oldinputTab = ctxt->inputTab; 4176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines oldcharset = ctxt->charset; 4186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 419677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->inputTab = (xmlParserInputPtr *) 420677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor xmlMalloc(5 * sizeof(xmlParserInputPtr)); 421677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor if (ctxt->inputTab == NULL) { 422677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset"); 423677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->input = oldinput; 424677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->inputNr = oldinputNr; 4256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ctxt->inputMax = oldinputMax; 4266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ctxt->inputTab = oldinputTab; 4276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ctxt->charset = oldcharset; 428677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor return; 429677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor } 430677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->inputNr = 0; 431677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->inputMax = 5; 432677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor ctxt->input = NULL; 4332492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor xmlPushInput(ctxt, input); 4342492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor 4352492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor /* 4362492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor * On the fly encoding conversion if needed 4371a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor */ 4381a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor if (ctxt->input->length >= 4) { 4392492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor enc = xmlDetectCharEncoding(ctxt->input->cur, 4); 4402492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor xmlSwitchEncoding(ctxt, enc); 4412492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor } 4422492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor 4432492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor if (input->filename == NULL) 4442492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor input->filename = (char *) xmlCanonicPath(SystemID); 4452492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor input->line = 1; 4462492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor input->col = 1; 4472492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor input->base = ctxt->input->cur; 4482492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor input->cur = ctxt->input->cur; 4492492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor input->free = NULL; 4502492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor 4512492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor /* 4522492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor * let's parse that entity knowing it's an external subset. 4532492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor */ 4542492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor xmlParseExternalSubset(ctxt, ExternalID, SystemID); 4552492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor 4562492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor /* 4572492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor * Free up the external entities 4582492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor */ 4592492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor 4602492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor while (ctxt->inputNr > 1) 4612492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor xmlPopInput(ctxt); 4622492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor xmlFreeInputStream(ctxt->input); 4632492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor xmlFree(ctxt->inputTab); 4642492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor 4652492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor /* 4662492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor * Restore the parsing context of the main entity 4671a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor */ 4686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ctxt->input = oldinput; 4692492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor ctxt->inputNr = oldinputNr; 4702492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor ctxt->inputMax = oldinputMax; 4712492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor ctxt->inputTab = oldinputTab; 4722492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor ctxt->charset = oldcharset; 4732492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor /* ctxt->wellFormed = oldwellFormed; */ 4742492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor } 4752492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor} 4762492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor 477/** 478 * xmlSAX2ResolveEntity: 479 * @ctx: the user data (XML parser context) 480 * @publicId: The public ID of the entity 481 * @systemId: The system ID of the entity 482 * 483 * The entity loader, to control the loading of external entities, 484 * the application can either: 485 * - override this xmlSAX2ResolveEntity() callback in the SAX block 486 * - or better use the xmlSetExternalEntityLoader() function to 487 * set up it's own entity resolution routine 488 * 489 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. 490 */ 491xmlParserInputPtr 492xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 493{ 494 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 495 xmlParserInputPtr ret; 496 xmlChar *URI; 497 const char *base = NULL; 498 499 if (ctx == NULL) return(NULL); 500 if (ctxt->input != NULL) 501 base = ctxt->input->filename; 502 if (base == NULL) 503 base = ctxt->directory; 504 505 URI = xmlBuildURI(systemId, (const xmlChar *) base); 506 507#ifdef DEBUG_SAX 508 xmlGenericError(xmlGenericErrorContext, 509 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId); 510#endif 511 512 ret = xmlLoadExternalEntity((const char *) URI, 513 (const char *) publicId, ctxt); 514 if (URI != NULL) 515 xmlFree(URI); 516 return(ret); 517} 518 519/** 520 * xmlSAX2GetEntity: 521 * @ctx: the user data (XML parser context) 522 * @name: The entity name 523 * 524 * Get an entity by name 525 * 526 * Returns the xmlEntityPtr if found. 527 */ 528xmlEntityPtr 529xmlSAX2GetEntity(void *ctx, const xmlChar *name) 530{ 531 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 532 xmlEntityPtr ret = NULL; 533 534 if (ctx == NULL) return(NULL); 535#ifdef DEBUG_SAX 536 xmlGenericError(xmlGenericErrorContext, 537 "SAX.xmlSAX2GetEntity(%s)\n", name); 538#endif 539 540 if (ctxt->inSubset == 0) { 541 ret = xmlGetPredefinedEntity(name); 542 if (ret != NULL) 543 return(ret); 544 } 545 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) { 546 if (ctxt->inSubset == 2) { 547 ctxt->myDoc->standalone = 0; 548 ret = xmlGetDocEntity(ctxt->myDoc, name); 549 ctxt->myDoc->standalone = 1; 550 } else { 551 ret = xmlGetDocEntity(ctxt->myDoc, name); 552 if (ret == NULL) { 553 ctxt->myDoc->standalone = 0; 554 ret = xmlGetDocEntity(ctxt->myDoc, name); 555 if (ret != NULL) { 556 xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE, 557 "Entity(%s) document marked standalone but requires external subset\n", 558 name, NULL); 559 } 560 ctxt->myDoc->standalone = 1; 561 } 562 } 563 } else { 564 ret = xmlGetDocEntity(ctxt->myDoc, name); 565 } 566 if ((ret != NULL) && 567 ((ctxt->validate) || (ctxt->replaceEntities)) && 568 (ret->children == NULL) && 569 (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) { 570 int val; 571 572 /* 573 * for validation purposes we really need to fetch and 574 * parse the external entity 575 */ 576 xmlNodePtr children; 577 578 val = xmlParseCtxtExternalEntity(ctxt, ret->URI, 579 ret->ExternalID, &children); 580 if (val == 0) { 581 xmlAddChildList((xmlNodePtr) ret, children); 582 } else { 583 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING, 584 "Failure to process entity %s\n", name, NULL); 585 ctxt->validate = 0; 586 return(NULL); 587 } 588 ret->owner = 1; 589 if (ret->checked == 0) 590 ret->checked = 1; 591 } 592 return(ret); 593} 594 595/** 596 * xmlSAX2GetParameterEntity: 597 * @ctx: the user data (XML parser context) 598 * @name: The entity name 599 * 600 * Get a parameter entity by name 601 * 602 * Returns the xmlEntityPtr if found. 603 */ 604xmlEntityPtr 605xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name) 606{ 607 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 608 xmlEntityPtr ret; 609 610 if (ctx == NULL) return(NULL); 611#ifdef DEBUG_SAX 612 xmlGenericError(xmlGenericErrorContext, 613 "SAX.xmlSAX2GetParameterEntity(%s)\n", name); 614#endif 615 616 ret = xmlGetParameterEntity(ctxt->myDoc, name); 617 return(ret); 618} 619 620 621/** 622 * xmlSAX2EntityDecl: 623 * @ctx: the user data (XML parser context) 624 * @name: the entity name 625 * @type: the entity type 626 * @publicId: The public ID of the entity 627 * @systemId: The system ID of the entity 628 * @content: the entity value (without processing). 629 * 630 * An entity definition has been parsed 631 */ 632void 633xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type, 634 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 635{ 636 xmlEntityPtr ent; 637 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 638 639 if (ctx == NULL) return; 640#ifdef DEBUG_SAX 641 xmlGenericError(xmlGenericErrorContext, 642 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n", 643 name, type, publicId, systemId, content); 644#endif 645 if (ctxt->inSubset == 1) { 646 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId, 647 systemId, content); 648 if ((ent == NULL) && (ctxt->pedantic)) 649 xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED, 650 "Entity(%s) already defined in the internal subset\n", 651 name); 652 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 653 xmlChar *URI; 654 const char *base = NULL; 655 656 if (ctxt->input != NULL) 657 base = ctxt->input->filename; 658 if (base == NULL) 659 base = ctxt->directory; 660 661 URI = xmlBuildURI(systemId, (const xmlChar *) base); 662 ent->URI = URI; 663 } 664 } else if (ctxt->inSubset == 2) { 665 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId, 666 systemId, content); 667 if ((ent == NULL) && (ctxt->pedantic) && 668 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 669 ctxt->sax->warning(ctxt->userData, 670 "Entity(%s) already defined in the external subset\n", name); 671 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 672 xmlChar *URI; 673 const char *base = NULL; 674 675 if (ctxt->input != NULL) 676 base = ctxt->input->filename; 677 if (base == NULL) 678 base = ctxt->directory; 679 680 URI = xmlBuildURI(systemId, (const xmlChar *) base); 681 ent->URI = URI; 682 } 683 } else { 684 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING, 685 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n", 686 name, NULL); 687 } 688} 689 690/** 691 * xmlSAX2AttributeDecl: 692 * @ctx: the user data (XML parser context) 693 * @elem: the name of the element 694 * @fullname: the attribute name 695 * @type: the attribute type 696 * @def: the type of default value 697 * @defaultValue: the attribute default value 698 * @tree: the tree of enumerated value set 699 * 700 * An attribute definition has been parsed 701 */ 702void 703xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, 704 int type, int def, const xmlChar *defaultValue, 705 xmlEnumerationPtr tree) 706{ 707 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 708 xmlAttributePtr attr; 709 xmlChar *name = NULL, *prefix = NULL; 710 711 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) 712 return; 713 714#ifdef DEBUG_SAX 715 xmlGenericError(xmlGenericErrorContext, 716 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n", 717 elem, fullname, type, def, defaultValue); 718#endif 719 if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) && 720 (type != XML_ATTRIBUTE_ID)) { 721 /* 722 * Raise the error but keep the validity flag 723 */ 724 int tmp = ctxt->valid; 725 xmlErrValid(ctxt, XML_DTD_XMLID_TYPE, 726 "xml:id : attribute type should be ID\n", NULL, NULL); 727 ctxt->valid = tmp; 728 } 729 /* TODO: optimize name/prefix allocation */ 730 name = xmlSplitQName(ctxt, fullname, &prefix); 731 ctxt->vctxt.valid = 1; 732 if (ctxt->inSubset == 1) 733 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem, 734 name, prefix, (xmlAttributeType) type, 735 (xmlAttributeDefault) def, defaultValue, tree); 736 else if (ctxt->inSubset == 2) 737 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem, 738 name, prefix, (xmlAttributeType) type, 739 (xmlAttributeDefault) def, defaultValue, tree); 740 else { 741 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, 742 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n", 743 name, NULL); 744 xmlFreeEnumeration(tree); 745 return; 746 } 747#ifdef LIBXML_VALID_ENABLED 748 if (ctxt->vctxt.valid == 0) 749 ctxt->valid = 0; 750 if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) && 751 (ctxt->myDoc->intSubset != NULL)) 752 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc, 753 attr); 754#endif /* LIBXML_VALID_ENABLED */ 755 if (prefix != NULL) 756 xmlFree(prefix); 757 if (name != NULL) 758 xmlFree(name); 759} 760 761/** 762 * xmlSAX2ElementDecl: 763 * @ctx: the user data (XML parser context) 764 * @name: the element name 765 * @type: the element type 766 * @content: the element value tree 767 * 768 * An element definition has been parsed 769 */ 770void 771xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type, 772 xmlElementContentPtr content) 773{ 774 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 775 xmlElementPtr elem = NULL; 776 777 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) 778 return; 779 780#ifdef DEBUG_SAX 781 xmlGenericError(xmlGenericErrorContext, 782 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type); 783#endif 784 785 if (ctxt->inSubset == 1) 786 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, 787 name, (xmlElementTypeVal) type, content); 788 else if (ctxt->inSubset == 2) 789 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, 790 name, (xmlElementTypeVal) type, content); 791 else { 792 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, 793 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n", 794 name, NULL); 795 return; 796 } 797#ifdef LIBXML_VALID_ENABLED 798 if (elem == NULL) 799 ctxt->valid = 0; 800 if (ctxt->validate && ctxt->wellFormed && 801 ctxt->myDoc && ctxt->myDoc->intSubset) 802 ctxt->valid &= 803 xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem); 804#endif /* LIBXML_VALID_ENABLED */ 805} 806 807/** 808 * xmlSAX2NotationDecl: 809 * @ctx: the user data (XML parser context) 810 * @name: The name of the notation 811 * @publicId: The public ID of the entity 812 * @systemId: The system ID of the entity 813 * 814 * What to do when a notation declaration has been parsed. 815 */ 816void 817xmlSAX2NotationDecl(void *ctx, const xmlChar *name, 818 const xmlChar *publicId, const xmlChar *systemId) 819{ 820 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 821 xmlNotationPtr nota = NULL; 822 823 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) 824 return; 825 826#ifdef DEBUG_SAX 827 xmlGenericError(xmlGenericErrorContext, 828 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId); 829#endif 830 831 if ((publicId == NULL) && (systemId == NULL)) { 832 xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING, 833 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n", 834 name, NULL); 835 return; 836 } else if (ctxt->inSubset == 1) 837 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name, 838 publicId, systemId); 839 else if (ctxt->inSubset == 2) 840 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name, 841 publicId, systemId); 842 else { 843 xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING, 844 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n", 845 name, NULL); 846 return; 847 } 848#ifdef LIBXML_VALID_ENABLED 849 if (nota == NULL) ctxt->valid = 0; 850 if ((ctxt->validate) && (ctxt->wellFormed) && 851 (ctxt->myDoc->intSubset != NULL)) 852 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc, 853 nota); 854#endif /* LIBXML_VALID_ENABLED */ 855} 856 857/** 858 * xmlSAX2UnparsedEntityDecl: 859 * @ctx: the user data (XML parser context) 860 * @name: The name of the entity 861 * @publicId: The public ID of the entity 862 * @systemId: The system ID of the entity 863 * @notationName: the name of the notation 864 * 865 * What to do when an unparsed entity declaration is parsed 866 */ 867void 868xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name, 869 const xmlChar *publicId, const xmlChar *systemId, 870 const xmlChar *notationName) 871{ 872 xmlEntityPtr ent; 873 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 874 if (ctx == NULL) return; 875#ifdef DEBUG_SAX 876 xmlGenericError(xmlGenericErrorContext, 877 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n", 878 name, publicId, systemId, notationName); 879#endif 880 if (ctxt->inSubset == 1) { 881 ent = xmlAddDocEntity(ctxt->myDoc, name, 882 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 883 publicId, systemId, notationName); 884 if ((ent == NULL) && (ctxt->pedantic) && 885 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 886 ctxt->sax->warning(ctxt->userData, 887 "Entity(%s) already defined in the internal subset\n", name); 888 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 889 xmlChar *URI; 890 const char *base = NULL; 891 892 if (ctxt->input != NULL) 893 base = ctxt->input->filename; 894 if (base == NULL) 895 base = ctxt->directory; 896 897 URI = xmlBuildURI(systemId, (const xmlChar *) base); 898 ent->URI = URI; 899 } 900 } else if (ctxt->inSubset == 2) { 901 ent = xmlAddDtdEntity(ctxt->myDoc, name, 902 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 903 publicId, systemId, notationName); 904 if ((ent == NULL) && (ctxt->pedantic) && 905 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 906 ctxt->sax->warning(ctxt->userData, 907 "Entity(%s) already defined in the external subset\n", name); 908 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 909 xmlChar *URI; 910 const char *base = NULL; 911 912 if (ctxt->input != NULL) 913 base = ctxt->input->filename; 914 if (base == NULL) 915 base = ctxt->directory; 916 917 URI = xmlBuildURI(systemId, (const xmlChar *) base); 918 ent->URI = URI; 919 } 920 } else { 921 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, 922 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n", 923 name, NULL); 924 } 925} 926 927/** 928 * xmlSAX2SetDocumentLocator: 929 * @ctx: the user data (XML parser context) 930 * @loc: A SAX Locator 931 * 932 * Receive the document locator at startup, actually xmlDefaultSAXLocator 933 * Everything is available on the context, so this is useless in our case. 934 */ 935void 936xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED) 937{ 938 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 939#ifdef DEBUG_SAX 940 xmlGenericError(xmlGenericErrorContext, 941 "SAX.xmlSAX2SetDocumentLocator()\n"); 942#endif 943} 944 945/** 946 * xmlSAX2StartDocument: 947 * @ctx: the user data (XML parser context) 948 * 949 * called when the document start being processed. 950 */ 951void 952xmlSAX2StartDocument(void *ctx) 953{ 954 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 955 xmlDocPtr doc; 956 957 if (ctx == NULL) return; 958 959#ifdef DEBUG_SAX 960 xmlGenericError(xmlGenericErrorContext, 961 "SAX.xmlSAX2StartDocument()\n"); 962#endif 963 if (ctxt->html) { 964#ifdef LIBXML_HTML_ENABLED 965 if (ctxt->myDoc == NULL) 966 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 967 ctxt->myDoc->properties = XML_DOC_HTML; 968 ctxt->myDoc->parseFlags = ctxt->options; 969 if (ctxt->myDoc == NULL) { 970 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); 971 return; 972 } 973#else 974 xmlGenericError(xmlGenericErrorContext, 975 "libxml2 built without HTML support\n"); 976 ctxt->errNo = XML_ERR_INTERNAL_ERROR; 977 ctxt->instate = XML_PARSER_EOF; 978 ctxt->disableSAX = 1; 979 return; 980#endif 981 } else { 982 doc = ctxt->myDoc = xmlNewDoc(ctxt->version); 983 if (doc != NULL) { 984 doc->properties = 0; 985 if (ctxt->options & XML_PARSE_OLD10) 986 doc->properties |= XML_DOC_OLD10; 987 doc->parseFlags = ctxt->options; 988 if (ctxt->encoding != NULL) 989 doc->encoding = xmlStrdup(ctxt->encoding); 990 else 991 doc->encoding = NULL; 992 doc->standalone = ctxt->standalone; 993 } else { 994 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); 995 return; 996 } 997 if ((ctxt->dictNames) && (doc != NULL)) { 998 doc->dict = ctxt->dict; 999 xmlDictReference(doc->dict); 1000 } 1001 } 1002 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && 1003 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { 1004 ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename); 1005 if (ctxt->myDoc->URL == NULL) 1006 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); 1007 } 1008} 1009 1010/** 1011 * xmlSAX2EndDocument: 1012 * @ctx: the user data (XML parser context) 1013 * 1014 * called when the document end has been detected. 1015 */ 1016void 1017xmlSAX2EndDocument(void *ctx) 1018{ 1019 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1020#ifdef DEBUG_SAX 1021 xmlGenericError(xmlGenericErrorContext, 1022 "SAX.xmlSAX2EndDocument()\n"); 1023#endif 1024 if (ctx == NULL) return; 1025#ifdef LIBXML_VALID_ENABLED 1026 if (ctxt->validate && ctxt->wellFormed && 1027 ctxt->myDoc && ctxt->myDoc->intSubset) 1028 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc); 1029#endif /* LIBXML_VALID_ENABLED */ 1030 1031 /* 1032 * Grab the encoding if it was added on-the-fly 1033 */ 1034 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) && 1035 (ctxt->myDoc->encoding == NULL)) { 1036 ctxt->myDoc->encoding = ctxt->encoding; 1037 ctxt->encoding = NULL; 1038 } 1039 if ((ctxt->inputTab != NULL) && 1040 (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) && 1041 (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) && 1042 (ctxt->myDoc->encoding == NULL)) { 1043 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding); 1044 } 1045 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) && 1046 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) { 1047 ctxt->myDoc->charset = ctxt->charset; 1048 } 1049} 1050 1051#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) 1052/** 1053 * xmlSAX2AttributeInternal: 1054 * @ctx: the user data (XML parser context) 1055 * @fullname: The attribute name, including namespace prefix 1056 * @value: The attribute value 1057 * @prefix: the prefix on the element node 1058 * 1059 * Handle an attribute that has been read by the parser. 1060 * The default handling is to convert the attribute into an 1061 * DOM subtree and past it in a new xmlAttr element added to 1062 * the element. 1063 */ 1064static void 1065xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, 1066 const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED) 1067{ 1068 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1069 xmlAttrPtr ret; 1070 xmlChar *name; 1071 xmlChar *ns; 1072 xmlChar *nval; 1073 xmlNsPtr namespace; 1074 1075 if (ctxt->html) { 1076 name = xmlStrdup(fullname); 1077 ns = NULL; 1078 namespace = NULL; 1079 } else { 1080 /* 1081 * Split the full name into a namespace prefix and the tag name 1082 */ 1083 name = xmlSplitQName(ctxt, fullname, &ns); 1084 if ((name != NULL) && (name[0] == 0)) { 1085 if (xmlStrEqual(ns, BAD_CAST "xmlns")) { 1086 xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR, 1087 "invalid namespace declaration '%s'\n", 1088 fullname, NULL); 1089 } else { 1090 xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN, 1091 "Avoid attribute ending with ':' like '%s'\n", 1092 fullname, NULL); 1093 } 1094 if (ns != NULL) 1095 xmlFree(ns); 1096 ns = NULL; 1097 xmlFree(name); 1098 name = xmlStrdup(fullname); 1099 } 1100 } 1101 if (name == NULL) { 1102 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 1103 if (ns != NULL) 1104 xmlFree(ns); 1105 return; 1106 } 1107 1108#ifdef LIBXML_HTML_ENABLED 1109 if ((ctxt->html) && 1110 (value == NULL) && (htmlIsBooleanAttr(fullname))) { 1111 nval = xmlStrdup(fullname); 1112 value = (const xmlChar *) nval; 1113 } else 1114#endif 1115 { 1116#ifdef LIBXML_VALID_ENABLED 1117 /* 1118 * Do the last stage of the attribute normalization 1119 * Needed for HTML too: 1120 * http://www.w3.org/TR/html4/types.html#h-6.2 1121 */ 1122 ctxt->vctxt.valid = 1; 1123 nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt, 1124 ctxt->myDoc, ctxt->node, 1125 fullname, value); 1126 if (ctxt->vctxt.valid != 1) { 1127 ctxt->valid = 0; 1128 } 1129 if (nval != NULL) 1130 value = nval; 1131#else 1132 nval = NULL; 1133#endif /* LIBXML_VALID_ENABLED */ 1134 } 1135 1136 /* 1137 * Check whether it's a namespace definition 1138 */ 1139 if ((!ctxt->html) && (ns == NULL) && 1140 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') && 1141 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) { 1142 xmlNsPtr nsret; 1143 xmlChar *val; 1144 1145 if (!ctxt->replaceEntities) { 1146 ctxt->depth++; 1147 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 1148 0,0,0); 1149 ctxt->depth--; 1150 } else { 1151 val = (xmlChar *) value; 1152 } 1153 1154 if (val[0] != 0) { 1155 xmlURIPtr uri; 1156 1157 uri = xmlParseURI((const char *)val); 1158 if (uri == NULL) { 1159 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 1160 ctxt->sax->warning(ctxt->userData, 1161 "xmlns: %s not a valid URI\n", val); 1162 } else { 1163 if (uri->scheme == NULL) { 1164 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 1165 ctxt->sax->warning(ctxt->userData, 1166 "xmlns: URI %s is not absolute\n", val); 1167 } 1168 xmlFreeURI(uri); 1169 } 1170 } 1171 1172 /* a default namespace definition */ 1173 nsret = xmlNewNs(ctxt->node, val, NULL); 1174 1175#ifdef LIBXML_VALID_ENABLED 1176 /* 1177 * Validate also for namespace decls, they are attributes from 1178 * an XML-1.0 perspective 1179 */ 1180 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 1181 ctxt->myDoc && ctxt->myDoc->intSubset) 1182 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 1183 ctxt->node, prefix, nsret, val); 1184#endif /* LIBXML_VALID_ENABLED */ 1185 if (name != NULL) 1186 xmlFree(name); 1187 if (nval != NULL) 1188 xmlFree(nval); 1189 if (val != value) 1190 xmlFree(val); 1191 return; 1192 } 1193 if ((!ctxt->html) && 1194 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') && 1195 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) { 1196 xmlNsPtr nsret; 1197 xmlChar *val; 1198 1199 if (!ctxt->replaceEntities) { 1200 ctxt->depth++; 1201 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 1202 0,0,0); 1203 ctxt->depth--; 1204 if (val == NULL) { 1205 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 1206 xmlFree(ns); 1207 if (name != NULL) 1208 xmlFree(name); 1209 return; 1210 } 1211 } else { 1212 val = (xmlChar *) value; 1213 } 1214 1215 if (val[0] == 0) { 1216 xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY, 1217 "Empty namespace name for prefix %s\n", name, NULL); 1218 } 1219 if ((ctxt->pedantic != 0) && (val[0] != 0)) { 1220 xmlURIPtr uri; 1221 1222 uri = xmlParseURI((const char *)val); 1223 if (uri == NULL) { 1224 xmlNsWarnMsg(ctxt, XML_WAR_NS_URI, 1225 "xmlns:%s: %s not a valid URI\n", name, value); 1226 } else { 1227 if (uri->scheme == NULL) { 1228 xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE, 1229 "xmlns:%s: URI %s is not absolute\n", name, value); 1230 } 1231 xmlFreeURI(uri); 1232 } 1233 } 1234 1235 /* a standard namespace definition */ 1236 nsret = xmlNewNs(ctxt->node, val, name); 1237 xmlFree(ns); 1238#ifdef LIBXML_VALID_ENABLED 1239 /* 1240 * Validate also for namespace decls, they are attributes from 1241 * an XML-1.0 perspective 1242 */ 1243 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 1244 ctxt->myDoc && ctxt->myDoc->intSubset) 1245 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 1246 ctxt->node, prefix, nsret, value); 1247#endif /* LIBXML_VALID_ENABLED */ 1248 if (name != NULL) 1249 xmlFree(name); 1250 if (nval != NULL) 1251 xmlFree(nval); 1252 if (val != value) 1253 xmlFree(val); 1254 return; 1255 } 1256 1257 if (ns != NULL) { 1258 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns); 1259 1260 if (namespace == NULL) { 1261 xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 1262 "Namespace prefix %s of attribute %s is not defined\n", 1263 ns, name); 1264 } else { 1265 xmlAttrPtr prop; 1266 1267 prop = ctxt->node->properties; 1268 while (prop != NULL) { 1269 if (prop->ns != NULL) { 1270 if ((xmlStrEqual(name, prop->name)) && 1271 ((namespace == prop->ns) || 1272 (xmlStrEqual(namespace->href, prop->ns->href)))) { 1273 xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED, 1274 "Attribute %s in %s redefined\n", 1275 name, namespace->href); 1276 ctxt->wellFormed = 0; 1277 if (ctxt->recovery == 0) ctxt->disableSAX = 1; 1278 goto error; 1279 } 1280 } 1281 prop = prop->next; 1282 } 1283 } 1284 } else { 1285 namespace = NULL; 1286 } 1287 1288 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */ 1289 ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL); 1290 1291 if (ret != NULL) { 1292 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { 1293 xmlNodePtr tmp; 1294 1295 ret->children = xmlStringGetNodeList(ctxt->myDoc, value); 1296 tmp = ret->children; 1297 while (tmp != NULL) { 1298 tmp->parent = (xmlNodePtr) ret; 1299 if (tmp->next == NULL) 1300 ret->last = tmp; 1301 tmp = tmp->next; 1302 } 1303 } else if (value != NULL) { 1304 ret->children = xmlNewDocText(ctxt->myDoc, value); 1305 ret->last = ret->children; 1306 if (ret->children != NULL) 1307 ret->children->parent = (xmlNodePtr) ret; 1308 } 1309 } 1310 1311#ifdef LIBXML_VALID_ENABLED 1312 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 1313 ctxt->myDoc && ctxt->myDoc->intSubset) { 1314 1315 /* 1316 * If we don't substitute entities, the validation should be 1317 * done on a value with replaced entities anyway. 1318 */ 1319 if (!ctxt->replaceEntities) { 1320 xmlChar *val; 1321 1322 ctxt->depth++; 1323 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 1324 0,0,0); 1325 ctxt->depth--; 1326 1327 if (val == NULL) 1328 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1329 ctxt->myDoc, ctxt->node, ret, value); 1330 else { 1331 xmlChar *nvalnorm; 1332 1333 /* 1334 * Do the last stage of the attribute normalization 1335 * It need to be done twice ... it's an extra burden related 1336 * to the ability to keep xmlSAX2References in attributes 1337 */ 1338 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc, 1339 ctxt->node, fullname, val); 1340 if (nvalnorm != NULL) { 1341 xmlFree(val); 1342 val = nvalnorm; 1343 } 1344 1345 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1346 ctxt->myDoc, ctxt->node, ret, val); 1347 xmlFree(val); 1348 } 1349 } else { 1350 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, 1351 ctxt->node, ret, value); 1352 } 1353 } else 1354#endif /* LIBXML_VALID_ENABLED */ 1355 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && 1356 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || 1357 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { 1358 /* 1359 * when validating, the ID registration is done at the attribute 1360 * validation level. Otherwise we have to do specific handling here. 1361 */ 1362 if (xmlStrEqual(fullname, BAD_CAST "xml:id")) { 1363 /* 1364 * Add the xml:id value 1365 * 1366 * Open issue: normalization of the value. 1367 */ 1368 if (xmlValidateNCName(value, 1) != 0) { 1369 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, 1370 "xml:id : attribute value %s is not an NCName\n", 1371 (const char *) value, NULL); 1372 } 1373 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); 1374 } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) 1375 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); 1376 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) 1377 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret); 1378 } 1379 1380error: 1381 if (nval != NULL) 1382 xmlFree(nval); 1383 if (ns != NULL) 1384 xmlFree(ns); 1385} 1386 1387/* 1388 * xmlCheckDefaultedAttributes: 1389 * 1390 * Check defaulted attributes from the DTD 1391 */ 1392static void 1393xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name, 1394 const xmlChar *prefix, const xmlChar **atts) { 1395 xmlElementPtr elemDecl; 1396 const xmlChar *att; 1397 int internal = 1; 1398 int i; 1399 1400 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix); 1401 if (elemDecl == NULL) { 1402 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix); 1403 internal = 0; 1404 } 1405 1406process_external_subset: 1407 1408 if (elemDecl != NULL) { 1409 xmlAttributePtr attr = elemDecl->attributes; 1410 /* 1411 * Check against defaulted attributes from the external subset 1412 * if the document is stamped as standalone 1413 */ 1414 if ((ctxt->myDoc->standalone == 1) && 1415 (ctxt->myDoc->extSubset != NULL) && 1416 (ctxt->validate)) { 1417 while (attr != NULL) { 1418 if ((attr->defaultValue != NULL) && 1419 (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset, 1420 attr->elem, attr->name, 1421 attr->prefix) == attr) && 1422 (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 1423 attr->elem, attr->name, 1424 attr->prefix) == NULL)) { 1425 xmlChar *fulln; 1426 1427 if (attr->prefix != NULL) { 1428 fulln = xmlStrdup(attr->prefix); 1429 fulln = xmlStrcat(fulln, BAD_CAST ":"); 1430 fulln = xmlStrcat(fulln, attr->name); 1431 } else { 1432 fulln = xmlStrdup(attr->name); 1433 } 1434 if (fulln == NULL) { 1435 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 1436 break; 1437 } 1438 1439 /* 1440 * Check that the attribute is not declared in the 1441 * serialization 1442 */ 1443 att = NULL; 1444 if (atts != NULL) { 1445 i = 0; 1446 att = atts[i]; 1447 while (att != NULL) { 1448 if (xmlStrEqual(att, fulln)) 1449 break; 1450 i += 2; 1451 att = atts[i]; 1452 } 1453 } 1454 if (att == NULL) { 1455 xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED, 1456 "standalone: attribute %s on %s defaulted from external subset\n", 1457 (const char *)fulln, 1458 (const char *)attr->elem); 1459 } 1460 xmlFree(fulln); 1461 } 1462 attr = attr->nexth; 1463 } 1464 } 1465 1466 /* 1467 * Actually insert defaulted values when needed 1468 */ 1469 attr = elemDecl->attributes; 1470 while (attr != NULL) { 1471 /* 1472 * Make sure that attributes redefinition occuring in the 1473 * internal subset are not overriden by definitions in the 1474 * external subset. 1475 */ 1476 if (attr->defaultValue != NULL) { 1477 /* 1478 * the element should be instantiated in the tree if: 1479 * - this is a namespace prefix 1480 * - the user required for completion in the tree 1481 * like XSLT 1482 * - there isn't already an attribute definition 1483 * in the internal subset overriding it. 1484 */ 1485 if (((attr->prefix != NULL) && 1486 (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) || 1487 ((attr->prefix == NULL) && 1488 (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) || 1489 (ctxt->loadsubset & XML_COMPLETE_ATTRS)) { 1490 xmlAttributePtr tst; 1491 1492 tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 1493 attr->elem, attr->name, 1494 attr->prefix); 1495 if ((tst == attr) || (tst == NULL)) { 1496 xmlChar fn[50]; 1497 xmlChar *fulln; 1498 1499 fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50); 1500 if (fulln == NULL) { 1501 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 1502 return; 1503 } 1504 1505 /* 1506 * Check that the attribute is not declared in the 1507 * serialization 1508 */ 1509 att = NULL; 1510 if (atts != NULL) { 1511 i = 0; 1512 att = atts[i]; 1513 while (att != NULL) { 1514 if (xmlStrEqual(att, fulln)) 1515 break; 1516 i += 2; 1517 att = atts[i]; 1518 } 1519 } 1520 if (att == NULL) { 1521 xmlSAX2AttributeInternal(ctxt, fulln, 1522 attr->defaultValue, prefix); 1523 } 1524 if ((fulln != fn) && (fulln != attr->name)) 1525 xmlFree(fulln); 1526 } 1527 } 1528 } 1529 attr = attr->nexth; 1530 } 1531 if (internal == 1) { 1532 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, 1533 name, prefix); 1534 internal = 0; 1535 goto process_external_subset; 1536 } 1537 } 1538} 1539 1540/** 1541 * xmlSAX2StartElement: 1542 * @ctx: the user data (XML parser context) 1543 * @fullname: The element name, including namespace prefix 1544 * @atts: An array of name/value attributes pairs, NULL terminated 1545 * 1546 * called when an opening tag has been processed. 1547 */ 1548void 1549xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) 1550{ 1551 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1552 xmlNodePtr ret; 1553 xmlNodePtr parent; 1554 xmlNsPtr ns; 1555 xmlChar *name; 1556 xmlChar *prefix; 1557 const xmlChar *att; 1558 const xmlChar *value; 1559 int i; 1560 1561 if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return; 1562 parent = ctxt->node; 1563#ifdef DEBUG_SAX 1564 xmlGenericError(xmlGenericErrorContext, 1565 "SAX.xmlSAX2StartElement(%s)\n", fullname); 1566#endif 1567 1568 /* 1569 * First check on validity: 1570 */ 1571 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 1572 ((ctxt->myDoc->intSubset == NULL) || 1573 ((ctxt->myDoc->intSubset->notations == NULL) && 1574 (ctxt->myDoc->intSubset->elements == NULL) && 1575 (ctxt->myDoc->intSubset->attributes == NULL) && 1576 (ctxt->myDoc->intSubset->entities == NULL)))) { 1577 xmlErrValid(ctxt, XML_ERR_NO_DTD, 1578 "Validation failed: no DTD found !", NULL, NULL); 1579 ctxt->validate = 0; 1580 } 1581 1582 1583 /* 1584 * Split the full name into a namespace prefix and the tag name 1585 */ 1586 name = xmlSplitQName(ctxt, fullname, &prefix); 1587 1588 1589 /* 1590 * Note : the namespace resolution is deferred until the end of the 1591 * attributes parsing, since local namespace can be defined as 1592 * an attribute at this level. 1593 */ 1594 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL); 1595 if (ret == NULL) { 1596 if (prefix != NULL) 1597 xmlFree(prefix); 1598 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 1599 return; 1600 } 1601 if (ctxt->myDoc->children == NULL) { 1602#ifdef DEBUG_SAX_TREE 1603 xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name); 1604#endif 1605 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 1606 } else if (parent == NULL) { 1607 parent = ctxt->myDoc->children; 1608 } 1609 ctxt->nodemem = -1; 1610 if (ctxt->linenumbers) { 1611 if (ctxt->input != NULL) { 1612 if (ctxt->input->line < 65535) 1613 ret->line = (short) ctxt->input->line; 1614 else 1615 ret->line = 65535; 1616 } 1617 } 1618 1619 /* 1620 * We are parsing a new node. 1621 */ 1622#ifdef DEBUG_SAX_TREE 1623 xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name); 1624#endif 1625 nodePush(ctxt, ret); 1626 1627 /* 1628 * Link the child element 1629 */ 1630 if (parent != NULL) { 1631 if (parent->type == XML_ELEMENT_NODE) { 1632#ifdef DEBUG_SAX_TREE 1633 xmlGenericError(xmlGenericErrorContext, 1634 "adding child %s to %s\n", name, parent->name); 1635#endif 1636 xmlAddChild(parent, ret); 1637 } else { 1638#ifdef DEBUG_SAX_TREE 1639 xmlGenericError(xmlGenericErrorContext, 1640 "adding sibling %s to ", name); 1641 xmlDebugDumpOneNode(stderr, parent, 0); 1642#endif 1643 xmlAddSibling(parent, ret); 1644 } 1645 } 1646 1647 /* 1648 * Insert all the defaulted attributes from the DTD especially namespaces 1649 */ 1650 if ((!ctxt->html) && 1651 ((ctxt->myDoc->intSubset != NULL) || 1652 (ctxt->myDoc->extSubset != NULL))) { 1653 xmlCheckDefaultedAttributes(ctxt, name, prefix, atts); 1654 } 1655 1656 /* 1657 * process all the attributes whose name start with "xmlns" 1658 */ 1659 if (atts != NULL) { 1660 i = 0; 1661 att = atts[i++]; 1662 value = atts[i++]; 1663 if (!ctxt->html) { 1664 while ((att != NULL) && (value != NULL)) { 1665 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') && 1666 (att[3] == 'n') && (att[4] == 's')) 1667 xmlSAX2AttributeInternal(ctxt, att, value, prefix); 1668 1669 att = atts[i++]; 1670 value = atts[i++]; 1671 } 1672 } 1673 } 1674 1675 /* 1676 * Search the namespace, note that since the attributes have been 1677 * processed, the local namespaces are available. 1678 */ 1679 ns = xmlSearchNs(ctxt->myDoc, ret, prefix); 1680 if ((ns == NULL) && (parent != NULL)) 1681 ns = xmlSearchNs(ctxt->myDoc, parent, prefix); 1682 if ((prefix != NULL) && (ns == NULL)) { 1683 ns = xmlNewNs(ret, NULL, prefix); 1684 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 1685 "Namespace prefix %s is not defined\n", 1686 prefix, NULL); 1687 } 1688 1689 /* 1690 * set the namespace node, making sure that if the default namspace 1691 * is unbound on a parent we simply kee it NULL 1692 */ 1693 if ((ns != NULL) && (ns->href != NULL) && 1694 ((ns->href[0] != 0) || (ns->prefix != NULL))) 1695 xmlSetNs(ret, ns); 1696 1697 /* 1698 * process all the other attributes 1699 */ 1700 if (atts != NULL) { 1701 i = 0; 1702 att = atts[i++]; 1703 value = atts[i++]; 1704 if (ctxt->html) { 1705 while (att != NULL) { 1706 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 1707 att = atts[i++]; 1708 value = atts[i++]; 1709 } 1710 } else { 1711 while ((att != NULL) && (value != NULL)) { 1712 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') || 1713 (att[3] != 'n') || (att[4] != 's')) 1714 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 1715 1716 /* 1717 * Next ones 1718 */ 1719 att = atts[i++]; 1720 value = atts[i++]; 1721 } 1722 } 1723 } 1724 1725#ifdef LIBXML_VALID_ENABLED 1726 /* 1727 * If it's the Document root, finish the DTD validation and 1728 * check the document root element for validity 1729 */ 1730 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) { 1731 int chk; 1732 1733 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); 1734 if (chk <= 0) 1735 ctxt->valid = 0; 1736 if (chk < 0) 1737 ctxt->wellFormed = 0; 1738 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 1739 ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1; 1740 } 1741#endif /* LIBXML_VALID_ENABLED */ 1742 1743 if (prefix != NULL) 1744 xmlFree(prefix); 1745 1746} 1747 1748/** 1749 * xmlSAX2EndElement: 1750 * @ctx: the user data (XML parser context) 1751 * @name: The element name 1752 * 1753 * called when the end of an element has been detected. 1754 */ 1755void 1756xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED) 1757{ 1758 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1759 xmlParserNodeInfo node_info; 1760 xmlNodePtr cur; 1761 1762 if (ctx == NULL) return; 1763 cur = ctxt->node; 1764#ifdef DEBUG_SAX 1765 if (name == NULL) 1766 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n"); 1767 else 1768 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name); 1769#endif 1770 1771 /* Capture end position and add node */ 1772 if (cur != NULL && ctxt->record_info) { 1773 node_info.end_pos = ctxt->input->cur - ctxt->input->base; 1774 node_info.end_line = ctxt->input->line; 1775 node_info.node = cur; 1776 xmlParserAddNodeInfo(ctxt, &node_info); 1777 } 1778 ctxt->nodemem = -1; 1779 1780#ifdef LIBXML_VALID_ENABLED 1781 if (ctxt->validate && ctxt->wellFormed && 1782 ctxt->myDoc && ctxt->myDoc->intSubset) 1783 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, 1784 cur); 1785#endif /* LIBXML_VALID_ENABLED */ 1786 1787 1788 /* 1789 * end of parsing of this node. 1790 */ 1791#ifdef DEBUG_SAX_TREE 1792 xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name); 1793#endif 1794 nodePop(ctxt); 1795} 1796#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */ 1797 1798/* 1799 * xmlSAX2TextNode: 1800 * @ctxt: the parser context 1801 * @str: the input string 1802 * @len: the string length 1803 * 1804 * Remove the entities from an attribute value 1805 * 1806 * Returns the newly allocated string or NULL if not needed or error 1807 */ 1808static xmlNodePtr 1809xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) { 1810 xmlNodePtr ret; 1811 const xmlChar *intern = NULL; 1812 1813 /* 1814 * Allocate 1815 */ 1816 if (ctxt->freeElems != NULL) { 1817 ret = ctxt->freeElems; 1818 ctxt->freeElems = ret->next; 1819 ctxt->freeElemsNr--; 1820 } else { 1821 ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); 1822 } 1823 if (ret == NULL) { 1824 xmlErrMemory(ctxt, "xmlSAX2Characters"); 1825 return(NULL); 1826 } 1827 memset(ret, 0, sizeof(xmlNode)); 1828 /* 1829 * intern the formatting blanks found between tags, or the 1830 * very short strings 1831 */ 1832 if (ctxt->dictNames) { 1833 xmlChar cur = str[len]; 1834 1835 if ((len < (int) (2 * sizeof(void *))) && 1836 (ctxt->options & XML_PARSE_COMPACT)) { 1837 /* store the string in the node overrithing properties and nsDef */ 1838 xmlChar *tmp = (xmlChar *) &(ret->properties); 1839 memcpy(tmp, str, len); 1840 tmp[len] = 0; 1841 intern = tmp; 1842 } else if ((len <= 3) && ((cur == '"') || (cur == '\'') || 1843 ((cur == '<') && (str[len + 1] != '!')))) { 1844 intern = xmlDictLookup(ctxt->dict, str, len); 1845 } else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') && 1846 (str[len + 1] != '!')) { 1847 int i; 1848 1849 for (i = 1;i < len;i++) { 1850 if (!IS_BLANK_CH(str[i])) goto skip; 1851 } 1852 intern = xmlDictLookup(ctxt->dict, str, len); 1853 } 1854 } 1855skip: 1856 ret->type = XML_TEXT_NODE; 1857 1858 ret->name = xmlStringText; 1859 if (intern == NULL) { 1860 ret->content = xmlStrndup(str, len); 1861 if (ret->content == NULL) { 1862 xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode"); 1863 xmlFree(ret); 1864 return(NULL); 1865 } 1866 } else 1867 ret->content = (xmlChar *) intern; 1868 1869 if (ctxt->input != NULL) 1870 ret->line = ctxt->input->line; 1871 1872 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 1873 xmlRegisterNodeDefaultValue(ret); 1874 return(ret); 1875} 1876 1877#ifdef LIBXML_VALID_ENABLED 1878/* 1879 * xmlSAX2DecodeAttrEntities: 1880 * @ctxt: the parser context 1881 * @str: the input string 1882 * @len: the string length 1883 * 1884 * Remove the entities from an attribute value 1885 * 1886 * Returns the newly allocated string or NULL if not needed or error 1887 */ 1888static xmlChar * 1889xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, 1890 const xmlChar *end) { 1891 const xmlChar *in; 1892 xmlChar *ret; 1893 1894 in = str; 1895 while (in < end) 1896 if (*in++ == '&') 1897 goto decode; 1898 return(NULL); 1899decode: 1900 ctxt->depth++; 1901 ret = xmlStringLenDecodeEntities(ctxt, str, end - str, 1902 XML_SUBSTITUTE_REF, 0,0,0); 1903 ctxt->depth--; 1904 return(ret); 1905} 1906#endif /* LIBXML_VALID_ENABLED */ 1907 1908/** 1909 * xmlSAX2AttributeNs: 1910 * @ctx: the user data (XML parser context) 1911 * @localname: the local name of the attribute 1912 * @prefix: the attribute namespace prefix if available 1913 * @URI: the attribute namespace name if available 1914 * @value: Start of the attribute value 1915 * @valueend: end of the attribute value 1916 * 1917 * Handle an attribute that has been read by the parser. 1918 * The default handling is to convert the attribute into an 1919 * DOM subtree and past it in a new xmlAttr element added to 1920 * the element. 1921 */ 1922static void 1923xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt, 1924 const xmlChar * localname, 1925 const xmlChar * prefix, 1926 const xmlChar * value, 1927 const xmlChar * valueend) 1928{ 1929 xmlAttrPtr ret; 1930 xmlNsPtr namespace = NULL; 1931 xmlChar *dup = NULL; 1932 1933 /* 1934 * Note: if prefix == NULL, the attribute is not in the default namespace 1935 */ 1936 if (prefix != NULL) 1937 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix); 1938 1939 /* 1940 * allocate the node 1941 */ 1942 if (ctxt->freeAttrs != NULL) { 1943 ret = ctxt->freeAttrs; 1944 ctxt->freeAttrs = ret->next; 1945 ctxt->freeAttrsNr--; 1946 memset(ret, 0, sizeof(xmlAttr)); 1947 ret->type = XML_ATTRIBUTE_NODE; 1948 1949 ret->parent = ctxt->node; 1950 ret->doc = ctxt->myDoc; 1951 ret->ns = namespace; 1952 1953 if (ctxt->dictNames) 1954 ret->name = localname; 1955 else 1956 ret->name = xmlStrdup(localname); 1957 1958 /* link at the end to preserv order, TODO speed up with a last */ 1959 if (ctxt->node->properties == NULL) { 1960 ctxt->node->properties = ret; 1961 } else { 1962 xmlAttrPtr prev = ctxt->node->properties; 1963 1964 while (prev->next != NULL) prev = prev->next; 1965 prev->next = ret; 1966 ret->prev = prev; 1967 } 1968 1969 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 1970 xmlRegisterNodeDefaultValue((xmlNodePtr)ret); 1971 } else { 1972 if (ctxt->dictNames) 1973 ret = xmlNewNsPropEatName(ctxt->node, namespace, 1974 (xmlChar *) localname, NULL); 1975 else 1976 ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL); 1977 if (ret == NULL) { 1978 xmlErrMemory(ctxt, "xmlSAX2AttributeNs"); 1979 return; 1980 } 1981 } 1982 1983 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { 1984 xmlNodePtr tmp; 1985 1986 /* 1987 * We know that if there is an entity reference, then 1988 * the string has been dup'ed and terminates with 0 1989 * otherwise with ' or " 1990 */ 1991 if (*valueend != 0) { 1992 tmp = xmlSAX2TextNode(ctxt, value, valueend - value); 1993 ret->children = tmp; 1994 ret->last = tmp; 1995 if (tmp != NULL) { 1996 tmp->doc = ret->doc; 1997 tmp->parent = (xmlNodePtr) ret; 1998 } 1999 } else { 2000 ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value, 2001 valueend - value); 2002 tmp = ret->children; 2003 while (tmp != NULL) { 2004 tmp->doc = ret->doc; 2005 tmp->parent = (xmlNodePtr) ret; 2006 if (tmp->next == NULL) 2007 ret->last = tmp; 2008 tmp = tmp->next; 2009 } 2010 } 2011 } else if (value != NULL) { 2012 xmlNodePtr tmp; 2013 2014 tmp = xmlSAX2TextNode(ctxt, value, valueend - value); 2015 ret->children = tmp; 2016 ret->last = tmp; 2017 if (tmp != NULL) { 2018 tmp->doc = ret->doc; 2019 tmp->parent = (xmlNodePtr) ret; 2020 } 2021 } 2022 2023#ifdef LIBXML_VALID_ENABLED 2024 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 2025 ctxt->myDoc && ctxt->myDoc->intSubset) { 2026 /* 2027 * If we don't substitute entities, the validation should be 2028 * done on a value with replaced entities anyway. 2029 */ 2030 if (!ctxt->replaceEntities) { 2031 dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend); 2032 if (dup == NULL) { 2033 if (*valueend == 0) { 2034 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 2035 ctxt->myDoc, ctxt->node, ret, value); 2036 } else { 2037 /* 2038 * That should already be normalized. 2039 * cheaper to finally allocate here than duplicate 2040 * entry points in the full validation code 2041 */ 2042 dup = xmlStrndup(value, valueend - value); 2043 2044 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 2045 ctxt->myDoc, ctxt->node, ret, dup); 2046 } 2047 } else { 2048 /* 2049 * dup now contains a string of the flattened attribute 2050 * content with entities substitued. Check if we need to 2051 * apply an extra layer of normalization. 2052 * It need to be done twice ... it's an extra burden related 2053 * to the ability to keep references in attributes 2054 */ 2055 if (ctxt->attsSpecial != NULL) { 2056 xmlChar *nvalnorm; 2057 xmlChar fn[50]; 2058 xmlChar *fullname; 2059 2060 fullname = xmlBuildQName(localname, prefix, fn, 50); 2061 if (fullname != NULL) { 2062 ctxt->vctxt.valid = 1; 2063 nvalnorm = xmlValidCtxtNormalizeAttributeValue( 2064 &ctxt->vctxt, ctxt->myDoc, 2065 ctxt->node, fullname, dup); 2066 if (ctxt->vctxt.valid != 1) 2067 ctxt->valid = 0; 2068 2069 if ((fullname != fn) && (fullname != localname)) 2070 xmlFree(fullname); 2071 if (nvalnorm != NULL) { 2072 xmlFree(dup); 2073 dup = nvalnorm; 2074 } 2075 } 2076 } 2077 2078 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 2079 ctxt->myDoc, ctxt->node, ret, dup); 2080 } 2081 } else { 2082 /* 2083 * if entities already have been substitued, then 2084 * the attribute as passed is already normalized 2085 */ 2086 dup = xmlStrndup(value, valueend - value); 2087 2088 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 2089 ctxt->myDoc, ctxt->node, ret, dup); 2090 } 2091 } else 2092#endif /* LIBXML_VALID_ENABLED */ 2093 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && 2094 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || 2095 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { 2096 /* 2097 * when validating, the ID registration is done at the attribute 2098 * validation level. Otherwise we have to do specific handling here. 2099 */ 2100 if ((prefix == ctxt->str_xml) && 2101 (localname[0] == 'i') && (localname[1] == 'd') && 2102 (localname[2] == 0)) { 2103 /* 2104 * Add the xml:id value 2105 * 2106 * Open issue: normalization of the value. 2107 */ 2108 if (dup == NULL) 2109 dup = xmlStrndup(value, valueend - value); 2110#ifdef LIBXML_VALID_ENABLED 2111 if (xmlValidateNCName(dup, 1) != 0) { 2112 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, 2113 "xml:id : attribute value %s is not an NCName\n", 2114 (const char *) dup, NULL); 2115 } 2116#endif 2117 xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); 2118 } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) { 2119 /* might be worth duplicate entry points and not copy */ 2120 if (dup == NULL) 2121 dup = xmlStrndup(value, valueend - value); 2122 xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); 2123 } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) { 2124 if (dup == NULL) 2125 dup = xmlStrndup(value, valueend - value); 2126 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret); 2127 } 2128 } 2129 if (dup != NULL) 2130 xmlFree(dup); 2131} 2132 2133/** 2134 * xmlSAX2StartElementNs: 2135 * @ctx: the user data (XML parser context) 2136 * @localname: the local name of the element 2137 * @prefix: the element namespace prefix if available 2138 * @URI: the element namespace name if available 2139 * @nb_namespaces: number of namespace definitions on that node 2140 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions 2141 * @nb_attributes: the number of attributes on that node 2142 * @nb_defaulted: the number of defaulted attributes. 2143 * @attributes: pointer to the array of (localname/prefix/URI/value/end) 2144 * attribute values. 2145 * 2146 * SAX2 callback when an element start has been detected by the parser. 2147 * It provides the namespace informations for the element, as well as 2148 * the new namespace declarations on the element. 2149 */ 2150void 2151xmlSAX2StartElementNs(void *ctx, 2152 const xmlChar *localname, 2153 const xmlChar *prefix, 2154 const xmlChar *URI, 2155 int nb_namespaces, 2156 const xmlChar **namespaces, 2157 int nb_attributes, 2158 int nb_defaulted, 2159 const xmlChar **attributes) 2160{ 2161 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2162 xmlNodePtr ret; 2163 xmlNodePtr parent; 2164 xmlNsPtr last = NULL, ns; 2165 const xmlChar *uri, *pref; 2166 int i, j; 2167 2168 if (ctx == NULL) return; 2169 parent = ctxt->node; 2170 /* 2171 * First check on validity: 2172 */ 2173 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 2174 ((ctxt->myDoc->intSubset == NULL) || 2175 ((ctxt->myDoc->intSubset->notations == NULL) && 2176 (ctxt->myDoc->intSubset->elements == NULL) && 2177 (ctxt->myDoc->intSubset->attributes == NULL) && 2178 (ctxt->myDoc->intSubset->entities == NULL)))) { 2179 xmlErrValid(ctxt, XML_ERR_NO_DTD, 2180 "Validation failed: no DTD found !", NULL, NULL); 2181 ctxt->validate = 0; 2182 } 2183 2184 /* 2185 * allocate the node 2186 */ 2187 if (ctxt->freeElems != NULL) { 2188 ret = ctxt->freeElems; 2189 ctxt->freeElems = ret->next; 2190 ctxt->freeElemsNr--; 2191 memset(ret, 0, sizeof(xmlNode)); 2192 ret->type = XML_ELEMENT_NODE; 2193 2194 if (ctxt->dictNames) 2195 ret->name = localname; 2196 else { 2197 ret->name = xmlStrdup(localname); 2198 if (ret->name == NULL) { 2199 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs"); 2200 return; 2201 } 2202 } 2203 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 2204 xmlRegisterNodeDefaultValue(ret); 2205 } else { 2206 if (ctxt->dictNames) 2207 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 2208 (xmlChar *) localname, NULL); 2209 else 2210 ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL); 2211 if (ret == NULL) { 2212 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs"); 2213 return; 2214 } 2215 } 2216 if (ctxt->linenumbers) { 2217 if (ctxt->input != NULL) { 2218 if (ctxt->input->line < 65535) 2219 ret->line = (short) ctxt->input->line; 2220 else 2221 ret->line = 65535; 2222 } 2223 } 2224 2225 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 2226 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 2227 } 2228 /* 2229 * Build the namespace list 2230 */ 2231 for (i = 0,j = 0;j < nb_namespaces;j++) { 2232 pref = namespaces[i++]; 2233 uri = namespaces[i++]; 2234 ns = xmlNewNs(NULL, uri, pref); 2235 if (ns != NULL) { 2236 if (last == NULL) { 2237 ret->nsDef = last = ns; 2238 } else { 2239 last->next = ns; 2240 last = ns; 2241 } 2242 if ((URI != NULL) && (prefix == pref)) 2243 ret->ns = ns; 2244 } else { 2245 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs"); 2246 return; 2247 } 2248#ifdef LIBXML_VALID_ENABLED 2249 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 2250 ctxt->myDoc && ctxt->myDoc->intSubset) { 2251 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 2252 ret, prefix, ns, uri); 2253 } 2254#endif /* LIBXML_VALID_ENABLED */ 2255 } 2256 ctxt->nodemem = -1; 2257 2258 /* 2259 * We are parsing a new node. 2260 */ 2261 nodePush(ctxt, ret); 2262 2263 /* 2264 * Link the child element 2265 */ 2266 if (parent != NULL) { 2267 if (parent->type == XML_ELEMENT_NODE) { 2268 xmlAddChild(parent, ret); 2269 } else { 2270 xmlAddSibling(parent, ret); 2271 } 2272 } 2273 2274 /* 2275 * Insert the defaulted attributes from the DTD only if requested: 2276 */ 2277 if ((nb_defaulted != 0) && 2278 ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0)) 2279 nb_attributes -= nb_defaulted; 2280 2281 /* 2282 * Search the namespace if it wasn't already found 2283 * Note that, if prefix is NULL, this searches for the default Ns 2284 */ 2285 if ((URI != NULL) && (ret->ns == NULL)) { 2286 ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix); 2287 if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) { 2288 ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix); 2289 } 2290 if (ret->ns == NULL) { 2291 ns = xmlNewNs(ret, NULL, prefix); 2292 if (ns == NULL) { 2293 2294 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs"); 2295 return; 2296 } 2297 if (prefix != NULL) 2298 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 2299 "Namespace prefix %s was not found\n", 2300 prefix, NULL); 2301 else 2302 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 2303 "Namespace default prefix was not found\n", 2304 NULL, NULL); 2305 } 2306 } 2307 2308 /* 2309 * process all the other attributes 2310 */ 2311 if (nb_attributes > 0) { 2312 for (j = 0,i = 0;i < nb_attributes;i++,j+=5) { 2313 xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1], 2314 attributes[j+3], attributes[j+4]); 2315 } 2316 } 2317 2318#ifdef LIBXML_VALID_ENABLED 2319 /* 2320 * If it's the Document root, finish the DTD validation and 2321 * check the document root element for validity 2322 */ 2323 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) { 2324 int chk; 2325 2326 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); 2327 if (chk <= 0) 2328 ctxt->valid = 0; 2329 if (chk < 0) 2330 ctxt->wellFormed = 0; 2331 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 2332 ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1; 2333 } 2334#endif /* LIBXML_VALID_ENABLED */ 2335} 2336 2337/** 2338 * xmlSAX2EndElementNs: 2339 * @ctx: the user data (XML parser context) 2340 * @localname: the local name of the element 2341 * @prefix: the element namespace prefix if available 2342 * @URI: the element namespace name if available 2343 * 2344 * SAX2 callback when an element end has been detected by the parser. 2345 * It provides the namespace informations for the element. 2346 */ 2347void 2348xmlSAX2EndElementNs(void *ctx, 2349 const xmlChar * localname ATTRIBUTE_UNUSED, 2350 const xmlChar * prefix ATTRIBUTE_UNUSED, 2351 const xmlChar * URI ATTRIBUTE_UNUSED) 2352{ 2353 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2354 xmlParserNodeInfo node_info; 2355 xmlNodePtr cur; 2356 2357 if (ctx == NULL) return; 2358 cur = ctxt->node; 2359 /* Capture end position and add node */ 2360 if ((ctxt->record_info) && (cur != NULL)) { 2361 node_info.end_pos = ctxt->input->cur - ctxt->input->base; 2362 node_info.end_line = ctxt->input->line; 2363 node_info.node = cur; 2364 xmlParserAddNodeInfo(ctxt, &node_info); 2365 } 2366 ctxt->nodemem = -1; 2367 2368#ifdef LIBXML_VALID_ENABLED 2369 if (ctxt->validate && ctxt->wellFormed && 2370 ctxt->myDoc && ctxt->myDoc->intSubset) 2371 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur); 2372#endif /* LIBXML_VALID_ENABLED */ 2373 2374 /* 2375 * end of parsing of this node. 2376 */ 2377 nodePop(ctxt); 2378} 2379 2380/** 2381 * xmlSAX2Reference: 2382 * @ctx: the user data (XML parser context) 2383 * @name: The entity name 2384 * 2385 * called when an entity xmlSAX2Reference is detected. 2386 */ 2387void 2388xmlSAX2Reference(void *ctx, const xmlChar *name) 2389{ 2390 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2391 xmlNodePtr ret; 2392 2393 if (ctx == NULL) return; 2394#ifdef DEBUG_SAX 2395 xmlGenericError(xmlGenericErrorContext, 2396 "SAX.xmlSAX2Reference(%s)\n", name); 2397#endif 2398 if (name[0] == '#') 2399 ret = xmlNewCharRef(ctxt->myDoc, name); 2400 else 2401 ret = xmlNewReference(ctxt->myDoc, name); 2402#ifdef DEBUG_SAX_TREE 2403 xmlGenericError(xmlGenericErrorContext, 2404 "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name); 2405#endif 2406 if (xmlAddChild(ctxt->node, ret) == NULL) { 2407 xmlFreeNode(ret); 2408 } 2409} 2410 2411/** 2412 * xmlSAX2Characters: 2413 * @ctx: the user data (XML parser context) 2414 * @ch: a xmlChar string 2415 * @len: the number of xmlChar 2416 * 2417 * receiving some chars from the parser. 2418 */ 2419void 2420xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) 2421{ 2422 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2423 xmlNodePtr lastChild; 2424 2425 if (ctx == NULL) return; 2426#ifdef DEBUG_SAX 2427 xmlGenericError(xmlGenericErrorContext, 2428 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len); 2429#endif 2430 /* 2431 * Handle the data if any. If there is no child 2432 * add it as content, otherwise if the last child is text, 2433 * concatenate it, else create a new node of type text. 2434 */ 2435 2436 if (ctxt->node == NULL) { 2437#ifdef DEBUG_SAX_TREE 2438 xmlGenericError(xmlGenericErrorContext, 2439 "add chars: ctxt->node == NULL !\n"); 2440#endif 2441 return; 2442 } 2443 lastChild = ctxt->node->last; 2444#ifdef DEBUG_SAX_TREE 2445 xmlGenericError(xmlGenericErrorContext, 2446 "add chars to %s \n", ctxt->node->name); 2447#endif 2448 2449 /* 2450 * Here we needed an accelerator mechanism in case of very large 2451 * elements. Use an attribute in the structure !!! 2452 */ 2453 if (lastChild == NULL) { 2454 lastChild = xmlSAX2TextNode(ctxt, ch, len); 2455 if (lastChild != NULL) { 2456 ctxt->node->children = lastChild; 2457 ctxt->node->last = lastChild; 2458 lastChild->parent = ctxt->node; 2459 lastChild->doc = ctxt->node->doc; 2460 ctxt->nodelen = len; 2461 ctxt->nodemem = len + 1; 2462 } else { 2463 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters"); 2464 return; 2465 } 2466 } else { 2467 int coalesceText = (lastChild != NULL) && 2468 (lastChild->type == XML_TEXT_NODE) && 2469 (lastChild->name == xmlStringText); 2470 if ((coalesceText) && (ctxt->nodemem != 0)) { 2471 /* 2472 * The whole point of maintaining nodelen and nodemem, 2473 * xmlTextConcat is too costly, i.e. compute length, 2474 * reallocate a new buffer, move data, append ch. Here 2475 * We try to minimaze realloc() uses and avoid copying 2476 * and recomputing length over and over. 2477 */ 2478 if (lastChild->content == (xmlChar *)&(lastChild->properties)) { 2479 lastChild->content = xmlStrdup(lastChild->content); 2480 lastChild->properties = NULL; 2481 } else if ((ctxt->nodemem == ctxt->nodelen + 1) && 2482 (xmlDictOwns(ctxt->dict, lastChild->content))) { 2483 lastChild->content = xmlStrdup(lastChild->content); 2484 } 2485 if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) && 2486 ((ctxt->options & XML_PARSE_HUGE) == 0)) { 2487 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node"); 2488 return; 2489 } 2490 if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len || 2491 (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) { 2492 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented"); 2493 return; 2494 } 2495 if (ctxt->nodelen + len >= ctxt->nodemem) { 2496 xmlChar *newbuf; 2497 size_t size; 2498 2499 size = ctxt->nodemem + len; 2500 size *= 2; 2501 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size); 2502 if (newbuf == NULL) { 2503 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters"); 2504 return; 2505 } 2506 ctxt->nodemem = size; 2507 lastChild->content = newbuf; 2508 } 2509 memcpy(&lastChild->content[ctxt->nodelen], ch, len); 2510 ctxt->nodelen += len; 2511 lastChild->content[ctxt->nodelen] = 0; 2512 } else if (coalesceText) { 2513 if (xmlTextConcat(lastChild, ch, len)) { 2514 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters"); 2515 } 2516 if (ctxt->node->children != NULL) { 2517 ctxt->nodelen = xmlStrlen(lastChild->content); 2518 ctxt->nodemem = ctxt->nodelen + 1; 2519 } 2520 } else { 2521 /* Mixed content, first time */ 2522 lastChild = xmlSAX2TextNode(ctxt, ch, len); 2523 if (lastChild != NULL) { 2524 xmlAddChild(ctxt->node, lastChild); 2525 if (ctxt->node->children != NULL) { 2526 ctxt->nodelen = len; 2527 ctxt->nodemem = len + 1; 2528 } 2529 } 2530 } 2531 } 2532} 2533 2534/** 2535 * xmlSAX2IgnorableWhitespace: 2536 * @ctx: the user data (XML parser context) 2537 * @ch: a xmlChar string 2538 * @len: the number of xmlChar 2539 * 2540 * receiving some ignorable whitespaces from the parser. 2541 * UNUSED: by default the DOM building will use xmlSAX2Characters 2542 */ 2543void 2544xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) 2545{ 2546 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 2547#ifdef DEBUG_SAX 2548 xmlGenericError(xmlGenericErrorContext, 2549 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len); 2550#endif 2551} 2552 2553/** 2554 * xmlSAX2ProcessingInstruction: 2555 * @ctx: the user data (XML parser context) 2556 * @target: the target name 2557 * @data: the PI data's 2558 * 2559 * A processing instruction has been parsed. 2560 */ 2561void 2562xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target, 2563 const xmlChar *data) 2564{ 2565 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2566 xmlNodePtr ret; 2567 xmlNodePtr parent; 2568 2569 if (ctx == NULL) return; 2570 parent = ctxt->node; 2571#ifdef DEBUG_SAX 2572 xmlGenericError(xmlGenericErrorContext, 2573 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data); 2574#endif 2575 2576 ret = xmlNewDocPI(ctxt->myDoc, target, data); 2577 if (ret == NULL) return; 2578 2579 if (ctxt->linenumbers) { 2580 if (ctxt->input != NULL) { 2581 if (ctxt->input->line < 65535) 2582 ret->line = (short) ctxt->input->line; 2583 else 2584 ret->line = 65535; 2585 } 2586 } 2587 if (ctxt->inSubset == 1) { 2588 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 2589 return; 2590 } else if (ctxt->inSubset == 2) { 2591 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 2592 return; 2593 } 2594 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 2595#ifdef DEBUG_SAX_TREE 2596 xmlGenericError(xmlGenericErrorContext, 2597 "Setting PI %s as root\n", target); 2598#endif 2599 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 2600 return; 2601 } 2602 if (parent->type == XML_ELEMENT_NODE) { 2603#ifdef DEBUG_SAX_TREE 2604 xmlGenericError(xmlGenericErrorContext, 2605 "adding PI %s child to %s\n", target, parent->name); 2606#endif 2607 xmlAddChild(parent, ret); 2608 } else { 2609#ifdef DEBUG_SAX_TREE 2610 xmlGenericError(xmlGenericErrorContext, 2611 "adding PI %s sibling to ", target); 2612 xmlDebugDumpOneNode(stderr, parent, 0); 2613#endif 2614 xmlAddSibling(parent, ret); 2615 } 2616} 2617 2618/** 2619 * xmlSAX2Comment: 2620 * @ctx: the user data (XML parser context) 2621 * @value: the xmlSAX2Comment content 2622 * 2623 * A xmlSAX2Comment has been parsed. 2624 */ 2625void 2626xmlSAX2Comment(void *ctx, const xmlChar *value) 2627{ 2628 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2629 xmlNodePtr ret; 2630 xmlNodePtr parent; 2631 2632 if (ctx == NULL) return; 2633 parent = ctxt->node; 2634#ifdef DEBUG_SAX 2635 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value); 2636#endif 2637 ret = xmlNewDocComment(ctxt->myDoc, value); 2638 if (ret == NULL) return; 2639 if (ctxt->linenumbers) { 2640 if (ctxt->input != NULL) { 2641 if (ctxt->input->line < 65535) 2642 ret->line = (short) ctxt->input->line; 2643 else 2644 ret->line = 65535; 2645 } 2646 } 2647 2648 if (ctxt->inSubset == 1) { 2649 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 2650 return; 2651 } else if (ctxt->inSubset == 2) { 2652 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 2653 return; 2654 } 2655 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 2656#ifdef DEBUG_SAX_TREE 2657 xmlGenericError(xmlGenericErrorContext, 2658 "Setting xmlSAX2Comment as root\n"); 2659#endif 2660 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 2661 return; 2662 } 2663 if (parent->type == XML_ELEMENT_NODE) { 2664#ifdef DEBUG_SAX_TREE 2665 xmlGenericError(xmlGenericErrorContext, 2666 "adding xmlSAX2Comment child to %s\n", parent->name); 2667#endif 2668 xmlAddChild(parent, ret); 2669 } else { 2670#ifdef DEBUG_SAX_TREE 2671 xmlGenericError(xmlGenericErrorContext, 2672 "adding xmlSAX2Comment sibling to "); 2673 xmlDebugDumpOneNode(stderr, parent, 0); 2674#endif 2675 xmlAddSibling(parent, ret); 2676 } 2677} 2678 2679/** 2680 * xmlSAX2CDataBlock: 2681 * @ctx: the user data (XML parser context) 2682 * @value: The pcdata content 2683 * @len: the block length 2684 * 2685 * called when a pcdata block has been parsed 2686 */ 2687void 2688xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len) 2689{ 2690 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2691 xmlNodePtr ret, lastChild; 2692 2693 if (ctx == NULL) return; 2694#ifdef DEBUG_SAX 2695 xmlGenericError(xmlGenericErrorContext, 2696 "SAX.pcdata(%.10s, %d)\n", value, len); 2697#endif 2698 lastChild = xmlGetLastChild(ctxt->node); 2699#ifdef DEBUG_SAX_TREE 2700 xmlGenericError(xmlGenericErrorContext, 2701 "add chars to %s \n", ctxt->node->name); 2702#endif 2703 if ((lastChild != NULL) && 2704 (lastChild->type == XML_CDATA_SECTION_NODE)) { 2705 xmlTextConcat(lastChild, value, len); 2706 } else { 2707 ret = xmlNewCDataBlock(ctxt->myDoc, value, len); 2708 xmlAddChild(ctxt->node, ret); 2709 } 2710} 2711 2712static int xmlSAX2DefaultVersionValue = 2; 2713 2714#ifdef LIBXML_SAX1_ENABLED 2715/** 2716 * xmlSAXDefaultVersion: 2717 * @version: the version, 1 or 2 2718 * 2719 * Set the default version of SAX used globally by the library. 2720 * By default, during initialization the default is set to 2. 2721 * Note that it is generally a better coding style to use 2722 * xmlSAXVersion() to set up the version explicitly for a given 2723 * parsing context. 2724 * 2725 * Returns the previous value in case of success and -1 in case of error. 2726 */ 2727int 2728xmlSAXDefaultVersion(int version) 2729{ 2730 int ret = xmlSAX2DefaultVersionValue; 2731 2732 if ((version != 1) && (version != 2)) 2733 return(-1); 2734 xmlSAX2DefaultVersionValue = version; 2735 return(ret); 2736} 2737#endif /* LIBXML_SAX1_ENABLED */ 2738 2739/** 2740 * xmlSAXVersion: 2741 * @hdlr: the SAX handler 2742 * @version: the version, 1 or 2 2743 * 2744 * Initialize the default XML SAX handler according to the version 2745 * 2746 * Returns 0 in case of success and -1 in case of error. 2747 */ 2748int 2749xmlSAXVersion(xmlSAXHandler *hdlr, int version) 2750{ 2751 if (hdlr == NULL) return(-1); 2752 if (version == 2) { 2753 hdlr->startElement = NULL; 2754 hdlr->endElement = NULL; 2755 hdlr->startElementNs = xmlSAX2StartElementNs; 2756 hdlr->endElementNs = xmlSAX2EndElementNs; 2757 hdlr->serror = NULL; 2758 hdlr->initialized = XML_SAX2_MAGIC; 2759#ifdef LIBXML_SAX1_ENABLED 2760 } else if (version == 1) { 2761 hdlr->startElement = xmlSAX2StartElement; 2762 hdlr->endElement = xmlSAX2EndElement; 2763 hdlr->initialized = 1; 2764#endif /* LIBXML_SAX1_ENABLED */ 2765 } else 2766 return(-1); 2767 hdlr->internalSubset = xmlSAX2InternalSubset; 2768 hdlr->externalSubset = xmlSAX2ExternalSubset; 2769 hdlr->isStandalone = xmlSAX2IsStandalone; 2770 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 2771 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 2772 hdlr->resolveEntity = xmlSAX2ResolveEntity; 2773 hdlr->getEntity = xmlSAX2GetEntity; 2774 hdlr->getParameterEntity = xmlSAX2GetParameterEntity; 2775 hdlr->entityDecl = xmlSAX2EntityDecl; 2776 hdlr->attributeDecl = xmlSAX2AttributeDecl; 2777 hdlr->elementDecl = xmlSAX2ElementDecl; 2778 hdlr->notationDecl = xmlSAX2NotationDecl; 2779 hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl; 2780 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 2781 hdlr->startDocument = xmlSAX2StartDocument; 2782 hdlr->endDocument = xmlSAX2EndDocument; 2783 hdlr->reference = xmlSAX2Reference; 2784 hdlr->characters = xmlSAX2Characters; 2785 hdlr->cdataBlock = xmlSAX2CDataBlock; 2786 hdlr->ignorableWhitespace = xmlSAX2Characters; 2787 hdlr->processingInstruction = xmlSAX2ProcessingInstruction; 2788 hdlr->comment = xmlSAX2Comment; 2789 hdlr->warning = xmlParserWarning; 2790 hdlr->error = xmlParserError; 2791 hdlr->fatalError = xmlParserError; 2792 2793 return(0); 2794} 2795 2796/** 2797 * xmlSAX2InitDefaultSAXHandler: 2798 * @hdlr: the SAX handler 2799 * @warning: flag if non-zero sets the handler warning procedure 2800 * 2801 * Initialize the default XML SAX2 handler 2802 */ 2803void 2804xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning) 2805{ 2806 if ((hdlr == NULL) || (hdlr->initialized != 0)) 2807 return; 2808 2809 xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue); 2810 if (warning == 0) 2811 hdlr->warning = NULL; 2812 else 2813 hdlr->warning = xmlParserWarning; 2814} 2815 2816/** 2817 * xmlDefaultSAXHandlerInit: 2818 * 2819 * Initialize the default SAX2 handler 2820 */ 2821void 2822xmlDefaultSAXHandlerInit(void) 2823{ 2824#ifdef LIBXML_SAX1_ENABLED 2825 xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1); 2826#endif /* LIBXML_SAX1_ENABLED */ 2827} 2828 2829#ifdef LIBXML_HTML_ENABLED 2830 2831/** 2832 * xmlSAX2InitHtmlDefaultSAXHandler: 2833 * @hdlr: the SAX handler 2834 * 2835 * Initialize the default HTML SAX2 handler 2836 */ 2837void 2838xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr) 2839{ 2840 if ((hdlr == NULL) || (hdlr->initialized != 0)) 2841 return; 2842 2843 hdlr->internalSubset = xmlSAX2InternalSubset; 2844 hdlr->externalSubset = NULL; 2845 hdlr->isStandalone = NULL; 2846 hdlr->hasInternalSubset = NULL; 2847 hdlr->hasExternalSubset = NULL; 2848 hdlr->resolveEntity = NULL; 2849 hdlr->getEntity = xmlSAX2GetEntity; 2850 hdlr->getParameterEntity = NULL; 2851 hdlr->entityDecl = NULL; 2852 hdlr->attributeDecl = NULL; 2853 hdlr->elementDecl = NULL; 2854 hdlr->notationDecl = NULL; 2855 hdlr->unparsedEntityDecl = NULL; 2856 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 2857 hdlr->startDocument = xmlSAX2StartDocument; 2858 hdlr->endDocument = xmlSAX2EndDocument; 2859 hdlr->startElement = xmlSAX2StartElement; 2860 hdlr->endElement = xmlSAX2EndElement; 2861 hdlr->reference = NULL; 2862 hdlr->characters = xmlSAX2Characters; 2863 hdlr->cdataBlock = xmlSAX2CDataBlock; 2864 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 2865 hdlr->processingInstruction = xmlSAX2ProcessingInstruction; 2866 hdlr->comment = xmlSAX2Comment; 2867 hdlr->warning = xmlParserWarning; 2868 hdlr->error = xmlParserError; 2869 hdlr->fatalError = xmlParserError; 2870 2871 hdlr->initialized = 1; 2872} 2873 2874/** 2875 * htmlDefaultSAXHandlerInit: 2876 * 2877 * Initialize the default SAX handler 2878 */ 2879void 2880htmlDefaultSAXHandlerInit(void) 2881{ 2882 xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler); 2883} 2884 2885#endif /* LIBXML_HTML_ENABLED */ 2886 2887#ifdef LIBXML_DOCB_ENABLED 2888 2889/** 2890 * xmlSAX2InitDocbDefaultSAXHandler: 2891 * @hdlr: the SAX handler 2892 * 2893 * Initialize the default DocBook SAX2 handler 2894 */ 2895void 2896xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr) 2897{ 2898 if ((hdlr == NULL) || (hdlr->initialized != 0)) 2899 return; 2900 2901 hdlr->internalSubset = xmlSAX2InternalSubset; 2902 hdlr->externalSubset = NULL; 2903 hdlr->isStandalone = xmlSAX2IsStandalone; 2904 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 2905 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 2906 hdlr->resolveEntity = xmlSAX2ResolveEntity; 2907 hdlr->getEntity = xmlSAX2GetEntity; 2908 hdlr->getParameterEntity = NULL; 2909 hdlr->entityDecl = xmlSAX2EntityDecl; 2910 hdlr->attributeDecl = NULL; 2911 hdlr->elementDecl = NULL; 2912 hdlr->notationDecl = NULL; 2913 hdlr->unparsedEntityDecl = NULL; 2914 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 2915 hdlr->startDocument = xmlSAX2StartDocument; 2916 hdlr->endDocument = xmlSAX2EndDocument; 2917 hdlr->startElement = xmlSAX2StartElement; 2918 hdlr->endElement = xmlSAX2EndElement; 2919 hdlr->reference = xmlSAX2Reference; 2920 hdlr->characters = xmlSAX2Characters; 2921 hdlr->cdataBlock = NULL; 2922 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 2923 hdlr->processingInstruction = NULL; 2924 hdlr->comment = xmlSAX2Comment; 2925 hdlr->warning = xmlParserWarning; 2926 hdlr->error = xmlParserError; 2927 hdlr->fatalError = xmlParserError; 2928 2929 hdlr->initialized = 1; 2930} 2931 2932/** 2933 * docbDefaultSAXHandlerInit: 2934 * 2935 * Initialize the default SAX handler 2936 */ 2937void 2938docbDefaultSAXHandlerInit(void) 2939{ 2940 xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler); 2941} 2942 2943#endif /* LIBXML_DOCB_ENABLED */ 2944#define bottom_SAX2 2945#include "elfgcchack.h" 2946