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