Changeset 31860 in webkit
- Timestamp:
- Apr 14, 2008 4:50:21 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r31859 r31860 1 2008-04-14 Julien Chaffraix <jchaffraix@webkit.org> 2 3 Reviewed by Ap. 4 5 Layout test for http://bugs.webkit.org/show_bug.cgi?id=17403: 6 WebKit Creates Invalid Xhtml Links with Ajax 7 8 * fast/parser/ampersand-escaped-parseXMLFragment-expected.txt: Added. 9 * fast/parser/ampersand-escaped-parseXMLFragment.xhtml: Added. 10 1 11 2008-04-14 Rob Buis <buis@kde.org> 2 12 -
trunk/WebCore/ChangeLog
r31859 r31860 1 2008-04-14 Julien Chaffraix <jchaffraix@webkit.org> 2 3 Reviewed by Ap. 4 5 Bug 17403: WebKit Creates Invalid Xhtml Links with Ajax 6 http://bugs.webkit.org/show_bug.cgi?id=17403 7 8 The previous code had callbacks for the normal parsing (full document) and fragment parsing. 9 The difference was induced by the method we were using which did not accept a xmlParserCtxt. 10 The code has been refactored to allow us to share the callbacks between the different cases. 11 A drawback is that we have to use xmlParseContent which is an internal libxml method and thus 12 some internal intialization is done in WebCore. 13 14 Test: fast/parser/ampersand-escaped-parseXMLFragment.xhtml 15 16 * dom/XMLTokenizer.cpp: 17 (WebCore::createStringParser): Moved didInit in the global scope as it is shared by the 18 2 create methods. 19 20 (WebCore::createMemoryParser): Create a memory parser similar to the previous code. 21 Initialize the xmlParserContext to call xmlParseContent in parseXMLDocumentFragment. 22 23 (WebCore::XMLTokenizer::initializeParserContext): Check m_parsingFragment to know 24 which create method to call. 25 26 * dom/XMLTokenizer.h: Added parseXMLDocumentFragment as a friend of XMLTokenizer. 27 1 28 2008-04-14 Rob Buis <buis@kde.org> 2 29 -
trunk/WebCore/dom/XMLTokenizer.cpp
r31848 r31860 438 438 } 439 439 440 static bool didInit = false; 441 440 442 static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* userData) 441 443 { 442 static bool didInit = false;443 444 if (!didInit) { 444 445 xmlInitParser(); … … 455 456 const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM); 456 457 xmlSwitchEncoding(parser, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE); 458 459 return parser; 460 } 461 462 463 // Chunk should be encoded in UTF-8 464 static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk) 465 { 466 if (!didInit) { 467 xmlInitParser(); 468 xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc); 469 xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc); 470 libxmlLoaderThread = currentThread(); 471 didInit = true; 472 } 473 474 xmlParserCtxtPtr parser = xmlCreateMemoryParserCtxt(chunk, xmlStrlen((const xmlChar*)chunk)); 475 476 if (!parser) 477 return 0; 478 479 // Copy the sax handler 480 memcpy(parser->sax, handlers, sizeof(xmlSAXHandler)); 481 482 // Set parser options. 483 // XML_PARSE_NODICT: default dictionary option. 484 // XML_PARSE_NOENT: force entities substitutions. 485 xmlCtxtUseOptions(parser, XML_PARSE_NODICT | XML_PARSE_NOENT); 486 487 // Internal initialization 488 parser->sax2 = 1; 489 parser->instate = XML_PARSER_CONTENT; // We are parsing a CONTENT 490 parser->depth = 0; 491 parser->str_xml = xmlDictLookup(parser->dict, BAD_CAST "xml", 3); 492 parser->str_xmlns = xmlDictLookup(parser->dict, BAD_CAST "xmlns", 5); 493 parser->str_xml_ns = xmlDictLookup(parser->dict, XML_XML_NAMESPACE, 36); 494 parser->_private = userData; 495 457 496 return parser; 458 497 } … … 595 634 #if defined(USE_QXMLSTREAM) && QT_VERSION >= 0x040400 596 635 delete m_stream.entityResolver(); 636 #endif 637 #ifndef USE_QXMLSTREAM 638 if (m_context) 639 xmlFreeParserCtxt(m_context); 597 640 #endif 598 641 } … … 1258 1301 } 1259 1302 1260 void XMLTokenizer::initializeParserContext( )1303 void XMLTokenizer::initializeParserContext(const char* chunk) 1261 1304 { 1262 1305 #ifndef USE_QXMLSTREAM 1263 1306 xmlSAXHandler sax; 1264 1307 memset(&sax, 0, sizeof(sax)); 1308 1265 1309 sax.error = normalErrorHandler; 1266 1310 sax.fatalError = fatalErrorHandler; … … 1285 1329 m_sawXSLTransform = false; 1286 1330 m_sawFirstElement = false; 1287 1331 1288 1332 #ifndef USE_QXMLSTREAM 1289 m_context = createStringParser(&sax, this); 1333 if (m_parsingFragment) 1334 m_context = createMemoryParser(&sax, this, chunk); 1335 else 1336 m_context = createStringParser(&sax, this); 1290 1337 #endif 1291 1338 } … … 1545 1592 } 1546 1593 1594 bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent) 1595 { 1596 if (!chunk.length()) 1597 return true; 1598 1599 XMLTokenizer tokenizer(fragment, parent); 1600 1547 1601 #ifndef USE_QXMLSTREAM 1548 static void balancedStartElementNsHandler(void* closure, const xmlChar* localname, const xmlChar* prefix, 1549 const xmlChar* uri, int nb_namespaces, const xmlChar** namespaces, 1550 int nb_attributes, int nb_defaulted, const xmlChar** libxmlAttributes) 1551 { 1552 static_cast<XMLTokenizer*>(closure)->startElementNs(localname, prefix, uri, nb_namespaces, namespaces, nb_attributes, nb_defaulted, libxmlAttributes); 1553 } 1554 1555 static void balancedEndElementNsHandler(void* closure, const xmlChar* localname, const xmlChar* prefix, const xmlChar* uri) 1556 { 1557 static_cast<XMLTokenizer*>(closure)->endElementNs(); 1558 } 1559 1560 static void balancedCharactersHandler(void* closure, const xmlChar* s, int len) 1561 { 1562 static_cast<XMLTokenizer*>(closure)->characters(s, len); 1563 } 1564 1565 static void balancedProcessingInstructionHandler(void* closure, const xmlChar* target, const xmlChar* data) 1566 { 1567 static_cast<XMLTokenizer*>(closure)->processingInstruction(target, data); 1568 } 1569 1570 static void balancedCdataBlockHandler(void* closure, const xmlChar* s, int len) 1571 { 1572 static_cast<XMLTokenizer*>(closure)->cdataBlock(s, len); 1573 } 1574 1575 static void balancedCommentHandler(void* closure, const xmlChar* comment) 1576 { 1577 static_cast<XMLTokenizer*>(closure)->comment(comment); 1578 } 1579 1580 WTF_ATTRIBUTE_PRINTF(2, 3) 1581 static void balancedWarningHandler(void* closure, const char* message, ...) 1582 { 1583 va_list args; 1584 va_start(args, message); 1585 static_cast<XMLTokenizer*>(closure)->error(XMLTokenizer::warning, message, args); 1586 va_end(args); 1587 } 1588 #endif 1589 bool parseXMLDocumentFragment(const String& string, DocumentFragment* fragment, Element* parent) 1590 { 1591 if (!string.length()) 1592 return true; 1593 1594 XMLTokenizer tokenizer(fragment, parent); 1595 1596 #ifndef USE_QXMLSTREAM 1597 xmlSAXHandler sax; 1598 memset(&sax, 0, sizeof(sax)); 1599 1600 sax.characters = balancedCharactersHandler; 1601 sax.processingInstruction = balancedProcessingInstructionHandler; 1602 sax.startElementNs = balancedStartElementNsHandler; 1603 sax.endElementNs = balancedEndElementNsHandler; 1604 sax.cdataBlock = balancedCdataBlockHandler; 1605 sax.ignorableWhitespace = balancedCharactersHandler; 1606 sax.comment = balancedCommentHandler; 1607 sax.warning = balancedWarningHandler; 1608 sax.initialized = XML_SAX2_MAGIC; 1609 1610 int result = xmlParseBalancedChunkMemory(0, &sax, &tokenizer, 0, (const xmlChar*)string.utf8().data(), 0); 1602 tokenizer.initializeParserContext(chunk.utf8().data()); 1603 1604 xmlParseContent(tokenizer.m_context); 1605 1611 1606 tokenizer.endDocument(); 1612 return result == 0; 1607 1608 // Check if all the chunk has been processed. 1609 long bytesProcessed = xmlByteConsumed(tokenizer.m_context); 1610 if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) == sizeof(UChar) * chunk.length()) 1611 return false; 1612 1613 // No error if the chunk is well formed or it is not but we have no error. 1614 return tokenizer.m_context->wellFormed || xmlCtxtGetLastError(tokenizer.m_context) == 0; 1613 1615 #else 1614 1616 tokenizer.write(String("<qxmlstreamdummyelement>"), false); 1615 tokenizer.write( string, false);1617 tokenizer.write(chunk, false); 1616 1618 tokenizer.write(String("</qxmlstreamdummyelement>"), false); 1617 1619 tokenizer.finish(); -
trunk/WebCore/dom/XMLTokenizer.h
r30243 r31860 82 82 83 83 #ifndef USE_QXMLSTREAM 84 85 friend bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent); 86 84 87 // callbacks from parser SAX 85 88 void error(ErrorType, const char* message, va_list args) WTF_ATTRIBUTE_PRINTF(3, 0); … … 116 119 117 120 private: 118 void initializeParserContext( );121 void initializeParserContext(const char* chunk = 0); 119 122 void setCurrentNode(Node*); 120 123
Note: See TracChangeset
for help on using the changeset viewer.