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