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