patch to fix XML parsing problem with new exception

Darin Adler darin at apple.com
Thu Dec 4 20:47:26 CET 2003


I added some exception handling to help with W3C DOM tests. But I did 
it wrong. This patch fixes it so it doesn't screw up XML parsing. 
Probably very different in your tree; not sure if it's applicable.

-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/ChangeLog,v
retrieving revision 1.2337
diff -p -u -u -p -r1.2337 ChangeLog
--- ChangeLog	2003/12/04 18:57:42	1.2337
+++ ChangeLog	2003/12/04 19:45:17
@@ -1,3 +1,47 @@
+2003-12-04  Darin Adler  <darin at apple.com>
+
+        Reviewed by John.
+
+        - fixed 3498712: REGRESSION (100-115): Safari aborts at http://www11.dht.dk/~blangstrup_org/
+
+        This was an uncaught exception thrown by DocumentImpl. But the design of KHTML DOM is that
+        "impl" classes return exception codes; they don't throw exceptions.
+
+        * khtml/dom/dom_doc.cpp:
+        (DOM::Document::createElement): Throw exception if necessary. The impl function now returns
+        an exception code.
+        (DOM::Document::createElementNS): Ditto.
+
+        * khtml/html/html_documentimpl.h: Add exception code parameter to createElement.
+        * khtml/html/html_documentimpl.cpp: (HTMLDocumentImpl::createElement): Pass along the
+        exception code from the lower level.
+
+        * khtml/xml/dom_docimpl.h: Add exception code parameters to createElement, createElementNS,
+        and createHTMLElement.
+        * khtml/xml/dom_docimpl.cpp:
+        (DOMImplementationImpl::createDocument): Handle exception code from createElementNS.
+        (DocumentImpl::createElement): Add exception code parameter, not set since there is
+        no exception.
+        (DocumentImpl::importNode): Handle exception code from createElementNS.
+        (DocumentImpl::createElementNS): Add exception code parameter. Propagate the exception
+        codes that we get from createHTMLElement and setPrefix.
+        (DocumentImpl::createHTMLElement): Add exception code parameter. Use an exception code
+        rather than a C++ exception for INVALID_CHARACTER_ERR.
+
+        * khtml/xml/dom_elementimpl.cpp: (ElementImpl::cloneNode): Pass exception code parameter to
+        createElement.
+
+        * khtml/xml/xml_tokenizer.cpp:
+        (XMLHandler::startElement): Pass exception code parameter to createElementNS, and return false
+        if it is not zero. This is where the bug happened. Before we would get an exception from
+        createElementNS, but "impl" functions are not supposed to throw in KHTML's DOM.
+        (XMLTokenizer::finish): Add various exception code parameters to compile, but we know we won't
+        get any exceptions.
+
+        * kwq/WebCoreDOMDocument.mm:
+        (-[WebCoreDOMDocument createElement:]): Pass an (ignored) exception code parameter.
+        (-[WebCoreDOMDocument createElementNS::]): Pass an (ignored) exception code parameter.
+
 === Safari-116 ===
 
 2003-12-03  Richard Williamson   <rjw at apple.com>
Index: khtml/dom/dom_doc.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/dom_doc.cpp,v
retrieving revision 1.12
diff -p -u -u -p -r1.12 khtml/dom/dom_doc.cpp
--- khtml/dom/dom_doc.cpp	2003/12/02 23:13:49	1.12
+++ khtml/dom/dom_doc.cpp	2003/12/04 19:45:18
@@ -234,14 +234,24 @@ Element Document::documentElement() cons
 
 Element Document::createElement( const DOMString &tagName )
 {
-    if (impl) return ((DocumentImpl *)impl)->createElement(tagName);
-    return 0;
+    if (!impl) return 0;
+    int exceptioncode = 0;
+    ElementImpl *e = ((DocumentImpl *)impl)->createElement(tagName, exceptioncode);
+    if (exceptioncode) {
+        throw DOMException(exceptioncode);
+    }
+    return e;
 }
 
 Element Document::createElementNS( const DOMString &namespaceURI, const DOMString &qualifiedName )
 {
-    if (impl) return ((DocumentImpl *)impl)->createElementNS(namespaceURI,qualifiedName);
-    return 0;
+    if (!impl) return 0;
+    int exceptioncode = 0;
+    ElementImpl *e = ((DocumentImpl *)impl)->createElementNS(namespaceURI, qualifiedName, exceptioncode);
+    if (exceptioncode) {
+        throw DOMException(exceptioncode);
+    }
+    return e;
 }
 
 DocumentFragment Document::createDocumentFragment(  )
Index: khtml/html/html_documentimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_documentimpl.cpp,v
retrieving revision 1.49
diff -p -u -u -p -r1.49 khtml/html/html_documentimpl.cpp
--- khtml/html/html_documentimpl.cpp	2003/11/19 20:36:13	1.49
+++ khtml/html/html_documentimpl.cpp	2003/12/04 19:45:18
@@ -273,9 +273,9 @@ bool HTMLDocumentImpl::childAllowed( Nod
     return (newChild->id() == ID_HTML || newChild->id() == ID_COMMENT);
 }
 
-ElementImpl *HTMLDocumentImpl::createElement( const DOMString &name )
+ElementImpl *HTMLDocumentImpl::createElement( const DOMString &name, int &exceptioncode )
 {
-    return createHTMLElement(name);
+    return createHTMLElement(name, exceptioncode);
 }
 
 void HTMLDocumentImpl::slotHistoryChanged()
Index: khtml/html/html_documentimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_documentimpl.h,v
retrieving revision 1.18
diff -p -u -u -p -r1.18 khtml/html/html_documentimpl.h
--- khtml/html/html_documentimpl.h	2003/11/19 20:36:13	1.18
+++ khtml/html/html_documentimpl.h	2003/12/04 19:45:18
@@ -73,7 +73,7 @@ public:
 
     virtual bool childAllowed( NodeImpl *newChild );
 
-    virtual ElementImpl *createElement ( const DOMString &tagName );
+    virtual ElementImpl *createElement ( const DOMString &tagName, int &exceptioncode );
 
     HTMLMapElementImpl* getMap(const DOMString& url_);
 
Index: khtml/xml/dom_docimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_docimpl.cpp,v
retrieving revision 1.97
diff -p -u -u -p -r1.97 khtml/xml/dom_docimpl.cpp
--- khtml/xml/dom_docimpl.cpp	2003/12/03 01:09:01	1.97
+++ khtml/xml/dom_docimpl.cpp	2003/12/04 19:45:20
@@ -185,8 +185,9 @@ DocumentImpl *DOMImplementationImpl::cre
     if (doc->doctype() && dtype)
         doc->doctype()->copyFrom(*dtype);
 
-    ElementImpl *element = doc->createElementNS(namespaceURI,qualifiedName);
-    doc->appendChild(element,exceptioncode);
+    ElementImpl *element = doc->createElementNS(namespaceURI,qualifiedName,exceptioncode);
+    if (element)
+        doc->appendChild(element,exceptioncode);
     if (exceptioncode) {
         delete element;
         delete doc;
@@ -396,7 +397,7 @@ ElementImpl *DocumentImpl::documentEleme
     return static_cast<ElementImpl*>(n);
 }
 
-ElementImpl *DocumentImpl::createElement( const DOMString &name )
+ElementImpl *DocumentImpl::createElement( const DOMString &name, int &exceptioncode )
 {
     return new XMLElementImpl( document, name.implementation() );
 }
@@ -442,7 +443,9 @@ NodeImpl *DocumentImpl::importNode(NodeI
 
 	if(importedNode->nodeType() == Node::ELEMENT_NODE)
 	{
-		ElementImpl *tempElementImpl = createElementNS(getDocument()->namespaceURI(id()), importedNode->nodeName());
+		ElementImpl *tempElementImpl = createElementNS(getDocument()->namespaceURI(id()), importedNode->nodeName(), exceptioncode);
+                if (exceptioncode)
+                    return 0;
 		result = tempElementImpl;
 
 		if(static_cast<ElementImpl *>(importedNode)->attributes(true) && static_cast<ElementImpl *>(importedNode)->attributes(true)->length())
@@ -504,7 +507,7 @@ NodeImpl *DocumentImpl::importNode(NodeI
 	return result;
 }
 
-ElementImpl *DocumentImpl::createElementNS( const DOMString &_namespaceURI, const DOMString &_qualifiedName )
+ElementImpl *DocumentImpl::createElementNS( const DOMString &_namespaceURI, const DOMString &_qualifiedName, int &exceptioncode)
 {
     ElementImpl *e = 0;
     QString qName = _qualifiedName.string();
@@ -514,10 +517,16 @@ ElementImpl *DocumentImpl::createElement
         _namespaceURI == XHTML_NAMESPACE) {
         // User requested an element in the XHTML namespace - this means we create a HTML element
         // (elements not in this namespace are treated as normal XML elements)
-        e = createHTMLElement(qName.mid(colonPos+1));
-        int exceptioncode = 0;
-        if (e && colonPos >= 0)
-            e->setPrefix(qName.left(colonPos),  exceptioncode);
+        e = createHTMLElement(qName.mid(colonPos+1), exceptioncode);
+        if (exceptioncode)
+            return 0;
+        if (e && colonPos >= 0) {
+            e->setPrefix(qName.left(colonPos), exceptioncode);
+            if (exceptioncode) {
+                delete e;
+                return 0;
+            }
+        }
     }
     if (!e)
         e = new XMLElementImpl( document, _qualifiedName.implementation(), _namespaceURI.implementation() );
@@ -621,9 +630,12 @@ unsigned short DocumentImpl::nodeType() 
     return Node::DOCUMENT_NODE;
 }
 
-ElementImpl *DocumentImpl::createHTMLElement( const DOMString &name )
+ElementImpl *DocumentImpl::createHTMLElement( const DOMString &name, int &exceptioncode )
 {
-    if (!isValidName(name)) throw DOMException(DOMException::INVALID_CHARACTER_ERR);
+    if (!isValidName(name)) {
+        exceptioncode = DOMException::INVALID_CHARACTER_ERR;
+        return 0;
+    }
 
     uint id = khtml::getTagID( name.string().lower().latin1(), name.string().length() );
 
Index: khtml/xml/dom_docimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_docimpl.h,v
retrieving revision 1.46
diff -p -u -u -p -r1.46 khtml/xml/dom_docimpl.h
--- khtml/xml/dom_docimpl.h	2003/12/02 23:13:50	1.46
+++ khtml/xml/dom_docimpl.h	2003/12/04 19:45:20
@@ -147,7 +147,7 @@ public:
 
     DOMImplementationImpl *implementation() const;
     ElementImpl *documentElement() const;
-    virtual ElementImpl *createElement ( const DOMString &tagName );
+    virtual ElementImpl *createElement ( const DOMString &tagName, int &exceptioncode );
     DocumentFragmentImpl *createDocumentFragment ();
     TextImpl *createTextNode ( const DOMString &data );
     CommentImpl *createComment ( const DOMString &data );
@@ -156,7 +156,7 @@ public:
     Attr createAttribute(NodeImpl::Id id);
     EntityReferenceImpl *createEntityReference ( const DOMString &name );
     NodeImpl *importNode( NodeImpl *importedNode, bool deep, int &exceptioncode );
-    virtual ElementImpl *createElementNS ( const DOMString &_namespaceURI, const DOMString &_qualifiedName );
+    virtual ElementImpl *createElementNS ( const DOMString &_namespaceURI, const DOMString &_qualifiedName, int &exceptioncode );
     ElementImpl *getElementById ( const DOMString &elementId ) const;
 
     // Actually part of HTMLDocument, but used for giving XML documents a window title as well
@@ -172,7 +172,7 @@ public:
     virtual bool isDocumentNode() const { return true; }
     virtual bool isHTMLDocument() const { return false; }
 
-    virtual ElementImpl *createHTMLElement ( const DOMString &tagName );
+    virtual ElementImpl *createHTMLElement ( const DOMString &tagName, int &exceptioncode );
 
     khtml::CSSStyleSelector *styleSelector() { return m_styleSelector; }
 
Index: khtml/xml/dom_elementimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_elementimpl.cpp,v
retrieving revision 1.26
diff -p -u -u -p -r1.26 khtml/xml/dom_elementimpl.cpp
--- khtml/xml/dom_elementimpl.cpp	2003/12/02 23:13:50	1.26
+++ khtml/xml/dom_elementimpl.cpp	2003/12/04 19:45:20
@@ -294,7 +294,8 @@ void ElementImpl::setAttributeMap( Named
 NodeImpl *ElementImpl::cloneNode(bool deep)
 {
     // ### we loose the namespace here ... FIXME
-    ElementImpl *clone = getDocument()->createElement(tagName());
+    int exceptioncode;
+    ElementImpl *clone = getDocument()->createElement(tagName(), exceptioncode);
     if (!clone) return 0;
 
     // clone attributes
Index: khtml/xml/xml_tokenizer.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/xml_tokenizer.cpp,v
retrieving revision 1.15
diff -p -u -u -p -r1.15 khtml/xml/xml_tokenizer.cpp
--- khtml/xml/xml_tokenizer.cpp	2003/11/17 23:27:42	1.15
+++ khtml/xml/xml_tokenizer.cpp	2003/12/04 19:45:21
@@ -77,12 +77,13 @@ bool XMLHandler::startElement( const QSt
     if (m_currentNode->nodeType() == Node::TEXT_NODE)
         exitText();
 
-    ElementImpl *newElement;
-    newElement = m_doc->document()->createElementNS(namespaceURI,qName);
+    int exceptioncode = 0;
+    ElementImpl *newElement = m_doc->document()->createElementNS(namespaceURI,qName,exceptioncode);
+    if (!newElement)
+        return false;
 
     int i;
     for (i = 0; i < atts.length(); i++) {
-        int exceptioncode = 0;
         DOMString uri(atts.uri(i));
         DOMString ln(atts.localName(i));
         DOMString val(atts.value(i));
@@ -376,9 +377,9 @@ void XMLTokenizer::finish()
 
         // Create elements for display
         DocumentImpl *doc = m_doc->document();
-        NodeImpl *html = doc->createElementNS(XHTML_NAMESPACE,"html");
-        NodeImpl   *body = doc->createElementNS(XHTML_NAMESPACE,"body");
-        NodeImpl     *h1 = doc->createElementNS(XHTML_NAMESPACE,"h1");
+        NodeImpl *html = doc->createElementNS(XHTML_NAMESPACE,"html",exceptioncode);
+        NodeImpl   *body = doc->createElementNS(XHTML_NAMESPACE,"body",exceptioncode);
+        NodeImpl     *h1 = doc->createElementNS(XHTML_NAMESPACE,"h1",exceptioncode);
 #if APPLE_CHANGES
         // FIXME: Is there some alternative to having this text hardcoded here?
         NodeImpl       *headingText = doc->createTextNode("XML parsing error");
@@ -391,8 +392,8 @@ void XMLTokenizer::finish()
         NodeImpl       *lineText = 0;
         NodeImpl       *errorLocText = 0;
         if (!line.isNull()) {
-                      hr = doc->createElementNS(XHTML_NAMESPACE,"hr");
-                      pre = doc->createElementNS(XHTML_NAMESPACE,"pre");
+                      hr = doc->createElementNS(XHTML_NAMESPACE,"hr",exceptioncode);
+                      pre = doc->createElementNS(XHTML_NAMESPACE,"pre",exceptioncode);
                         lineText = doc->createTextNode(line+"\n");
                         errorLocText = doc->createTextNode(errorLocPtr);
         }
Index: kwq/WebCoreDOMDocument.mm
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/kwq/WebCoreDOMDocument.mm,v
retrieving revision 1.9
diff -p -u -u -p -r1.9 kwq/WebCoreDOMDocument.mm
--- kwq/WebCoreDOMDocument.mm	2003/07/01 23:27:21	1.9
+++ kwq/WebCoreDOMDocument.mm	2003/12/04 19:45:21
@@ -188,12 +188,14 @@ DOM::DOMString NSStringToDOMString(NSStr
 
 - (id<WebDOMElement>)createElement:(NSString *)tagName
 {
-    return [WebCoreDOMElement elementWithImpl: [self documentImpl]->createElement(NSStringToDOMString(tagName))];
+    int exceptionCode;
+    return [WebCoreDOMElement elementWithImpl: [self documentImpl]->createElement(NSStringToDOMString(tagName), exceptionCode)];
 }
 
 - (id<WebDOMElement>)createElementNS:(NSString *)namespaceURI :(NSString *)qualifiedName
 {
-    return [WebCoreDOMElement elementWithImpl: [self documentImpl]->createElementNS(NSStringToDOMString(namespaceURI),NSStringToDOMString(qualifiedName))];
+    int exceptionCode;
+    return [WebCoreDOMElement elementWithImpl: [self documentImpl]->createElementNS(NSStringToDOMString(namespaceURI), NSStringToDOMString(qualifiedName), exceptionCode)];
 }
 
 - (id<WebDOMDocumentFragment>)createDocumentFragment
-------------- next part --------------


     -- Darin


More information about the Khtml-devel mailing list