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