Fix for crash when assigning document.body
Maciej Stachowiak
mjs at apple.com
Fri Oct 3 14:37:52 CEST 2003
This patch fixes two problems that led to a crash on this HTML:
<html>
<body>
<script>document.body = new Object</script>
</body>
</html>
First of all, setting a document body to null at the C++ level should
be ignored, instead of removing the body, because that's what happens
when the JavaScript bindings can't convert the argument to a node.
Second, the HTML parser needs to keep the "current" node ref'd, since
script execution can remove arbitrary nodes from the document while
parsing.
-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/ChangeLog,v
retrieving revision 1.2050
diff -u -p -r1.2050 ChangeLog
--- ChangeLog 2003/10/02 23:28:33 1.2050
+++ ChangeLog 2003/10/03 07:34:01
@@ -1,3 +1,24 @@
+2003-10-03 Maciej Stachowiak <mjs at apple.com>
+
+ Reviewed by NOBODY (OOPS!).
+
+ - fixed 3398420 - crash when creating a new document.body object in <body>
+
+ * khtml/html/html_documentimpl.cpp:
+ (HTMLDocumentImpl::setBody): Don't remove the body when null is passed in,
+ as this means type error at the higher level and should be ignored.
+ * khtml/html/htmlparser.cpp:
+ (KHTMLParser::KHTMLParser): Initialize current to 0.
+ (KHTMLParser::setCurrent): Ref new current and deref old; we need to
+ keep it ref'd because script execution could drop the current node on the
+ floor.
+ (KHTMLParser::reset): Use setCurrent.
+ (KHTMLParser::insertNode): Likewise.
+ (KHTMLParser::reopenResidualStyleTags): Likewise.
+ (KHTMLParser::popOneBlock): Likewise.
+ (KHTMLParser::finished): Likewise.
+ * khtml/html/htmlparser.h: Prototype setCurrent.
+
2003-10-02 David Hyatt <hyatt at apple.com>
Remove the speed hit from using the UC break locators by not using them when
Index: khtml/html/html_documentimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_documentimpl.cpp,v
retrieving revision 1.46
diff -u -p -r1.46 khtml/html/html_documentimpl.cpp
--- khtml/html/html_documentimpl.cpp 2003/09/26 00:57:15 1.46
+++ khtml/html/html_documentimpl.cpp 2003/10/03 07:34:04
@@ -243,10 +243,10 @@ void HTMLDocumentImpl::setBody(HTMLEleme
{
int exceptioncode = 0;
HTMLElementImpl *b = body();
- if ( !_body && !b ) return;
- if ( !_body )
- documentElement()->removeChild( b, exceptioncode );
- else if ( !b )
+ if ( !_body )
+ return;
+
+ if ( !b )
documentElement()->appendChild( _body, exceptioncode );
else
documentElement()->replaceChild( _body, b, exceptioncode );
Index: khtml/html/htmlparser.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/htmlparser.cpp,v
retrieving revision 1.57
diff -u -p -r1.57 khtml/html/htmlparser.cpp
--- khtml/html/htmlparser.cpp 2003/09/25 00:37:35 1.57
+++ khtml/html/htmlparser.cpp 2003/10/03 07:34:05
@@ -111,7 +111,8 @@ public:
* element or ignore the tag.
*
*/
-KHTMLParser::KHTMLParser( KHTMLView *_parent, DocumentPtr *doc)
+KHTMLParser::KHTMLParser( KHTMLView *_parent, DocumentPtr *doc)
+ : current(0)
{
//kdDebug( 6035 ) << "parser constructor" << endl;
#if SPEED_DEBUG > 0
@@ -141,7 +142,7 @@ KHTMLParser::KHTMLParser( DOM::DocumentF
blockStack = 0;
reset();
- current = i;
+ setCurrent(i);
inBody = true;
}
@@ -161,7 +162,7 @@ KHTMLParser::~KHTMLParser()
void KHTMLParser::reset()
{
- current = document->document();
+ setCurrent(document->document());
freeBlock();
@@ -183,6 +184,15 @@ void KHTMLParser::reset()
discard_until = 0;
}
+void KHTMLParser::setCurrent(DOM::NodeImpl *newCurrent)
+{
+ if (newCurrent)
+ newCurrent->ref();
+ if (current)
+ current->deref();
+ current = newCurrent;
+}
+
void KHTMLParser::parseToken(Token *t)
{
if (t->id > 2*ID_CLOSE_TAG)
@@ -310,7 +320,7 @@ bool KHTMLParser::insertNode(NodeImpl *n
if (newNode == current)
popBlock(id);
else
- current = newNode;
+ setCurrent(newNode);
#if SPEED_DEBUG < 2
if(!n->attached() && HTMLWidget)
n->attach();
@@ -405,7 +415,7 @@ bool KHTMLParser::insertNode(NodeImpl *n
DOM::NodeImpl *newNode = head->addChild(n);
if ( newNode ) {
pushBlock(id, tagPriority[id]);
- current = newNode;
+ setCurrent(newNode);
#if SPEED_DEBUG < 2
if(!n->attached() && HTMLWidget)
n->attach();
@@ -619,7 +629,7 @@ bool KHTMLParser::insertNode(NodeImpl *n
!flat && endTag[id] != DOM::FORBIDDEN)
{
pushBlock(id, tagPriority[id]);
- current = n;
+ setCurrent(n);
inStrayTableContent = true;
blockStack->strayTableContent = true;
}
@@ -1396,7 +1406,7 @@ void KHTMLParser::reopenResidualStyleTag
malformedTableParent = 0;
// Update |current| manually to point to the new node.
- current = newNode;
+ setCurrent(newNode);
// Advance to the next tag that needs to be reopened.
HTMLStackElem* next = elem->next;
@@ -1529,7 +1539,7 @@ void KHTMLParser::popOneBlock(bool delBl
removeForbidden(Elem->id, forbiddenTag);
blockStack = Elem->next;
- current = Elem->node;
+ setCurrent(Elem->node);
if (Elem->strayTableContent)
inStrayTableContent = false;
@@ -1614,5 +1624,5 @@ void KHTMLParser::finished()
{
// This ensures that "current" is not left pointing to a node when the document is destroyed.
freeBlock();
- current = 0;
+ setCurrent(0);
}
Index: khtml/html/htmlparser.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/htmlparser.h,v
retrieving revision 1.17
diff -u -p -r1.17 khtml/html/htmlparser.h
--- khtml/html/htmlparser.h 2003/07/17 19:49:39 1.17
+++ khtml/html/htmlparser.h 2003/10/03 07:34:05
@@ -97,6 +97,7 @@ public:
DOM::DocumentPtr *docPtr() const { return document; }
protected:
+ void setCurrent(DOM::NodeImpl *newCurrent);
KHTMLView *HTMLWidget;
DOM::DocumentPtr *document;
More information about the Khtml-devel
mailing list