Closed Bug 10762 Opened 25 years ago Closed 25 years ago

Crasho manipulating <select>/<option> with JavaScript

Categories

(Core :: DOM: Core & HTML, defect, P1)

x86
Windows NT
defect

Tracking

()

VERIFIED FIXED

People

(Reporter: law, Assigned: vidur)

References

()

Details

(Keywords: crash)

I was playing with an old .xml file and produced a crash.  The URL above will
take you to the page (careful, it crashes 5.0!).  Here's the stack when it
crashes:

nsOptionList::IndexOf(nsIContent * 0x0a22453c) line 988 + 3 bytes
nsHTMLSelectElement::RemoveOption(nsHTMLSelectElement * const 0x0a224a3c,
nsIContent * 0x0a22453c) line 658 + 15 bytes
nsHTMLOptionElement::SetParent(nsHTMLOptionElement * const 0x0a22453c,
nsIContent * 0x00000000) line 197
nsGenericHTMLContainerElement::RemoveChildAt(int 0x00000001, int 0x00000001)
line 2780
nsGenericHTMLContainerElement::RemoveChild(nsIDOMNode * 0x0a224530, nsIDOMNode *
* 0x0012e96c) line 2588 + 14 bytes
nsHTMLSelectElement::RemoveChild(nsHTMLSelectElement * const 0x0a224a20,
nsIDOMNode * 0x0a224530, nsIDOMNode * * 0x0012e96c) line 120 + 22 bytes
NodeRemoveChild(JSContext * 0x09e07310, JSObject * 0x00e1a0c8, unsigned int
0x00000001, long * 0x00d90f50, long * 0x0012ea28) line 543 + 25 bytes
js_Invoke(JSContext * 0x09e07310, unsigned int 0x00000001, unsigned int
0x00000000) line 654 + 26 bytes
js_Interpret(JSContext * 0x09e07310, long * 0x0012f254) line 2228 + 15 bytes
js_Invoke(JSContext * 0x09e07310, unsigned int 0x00000000, unsigned int
0x00000000) line 670 + 13 bytes
js_Interpret(JSContext * 0x09e07310, long * 0x0012fa2c) line 2228 + 15 bytes
js_Execute(JSContext * 0x09e07310, JSObject * 0x00d82e58, JSScript * 0x0a220f40,
JSFunction * 0x00000000, JSStackFrame * 0x00000000, int 0x00000000, long *
0x0012fa2c) line 827 + 13 bytes
JS_EvaluateUCScriptForPrincipals(JSContext * 0x09e07310, JSObject * 0x00d82e58,
JSPrincipals * 0x0a219260, const unsigned short * 0x0012fadc, unsigned int
0x0000000d, const char * 0x0a220fd0, unsigned int 0x0000007d, long * 0x0012fa2c)
line 2596 + 27 bytes
nsJSContext::EvaluateString(nsJSContext * const 0x09e07480, const nsString &
{...}, const char * 0x0a220fd0, unsigned int 0x0000007d, nsString & {...}, int *
0x0012fa50) line 155 + 66 bytes
nsXMLContentSink::EvaluateScript(nsXMLContentSink * const 0x0a230b10, nsString &
{...}, unsigned int 0x0000007d) line 1680 + 32 bytes
nsXMLContentSink::ProcessEndSCRIPTTag(const nsIParserNode & {...}) line 1703 +
23 bytes
nsXMLContentSink::CloseContainer(nsXMLContentSink * const 0x0a230b10, const
nsIParserNode & {...}) line 774 + 12 bytes
CWellFormedDTD::HandleToken(CWellFormedDTD * const 0x0a1fb830, CToken *
0x09af48e0, nsIParser * 0x0a237da0) line 539 + 22 bytes
CWellFormedDTD::BuildModel(CWellFormedDTD * const 0x0a1fb830, nsIParser *
0x0a237da0, nsITokenizer * 0x0a1fa920, nsITokenObserver * 0x00000000,
nsIContentSink * 0x0a230b10) line 253 + 20 bytes
nsParser::BuildModel() line 941 + 34 bytes
nsParser::ResumeParse(nsIDTD * 0x00000000, int 0x00000000) line 886 + 11 bytes
nsParser::OnDataAvailable(nsParser * const 0x0a237da4, nsIChannel * 0x0a22e790,
nsISupports * 0x00000000, nsIInputStream * 0x0a22cfe0, unsigned int 0x00000000,
unsigned int 0x00001159) line 1159 + 19 bytes
nsDocumentBindInfo::OnDataAvailable(nsDocumentBindInfo * const 0x0a21e950,
nsIChannel * 0x0a22e790, nsISupports * 0x00000000, nsIInputStream * 0x0a22cfe0,
unsigned int 0x00000000, unsigned int 0x00001159) line 2024 + 32 bytes
nsOnDataAvailableEvent::HandleEvent(nsOnDataAvailableEvent * const 0x0a233890)
line 350
nsStreamListenerEvent::HandlePLEvent(PLEvent * 0x0a233894) line 149 + 12 bytes
PL_HandleEvent(PLEvent * 0x0a233894) line 509 + 10 bytes
PL_ProcessPendingEvents(PLEventQueue * 0x00ae2b40) line 470 + 9 bytes
_md_EventReceiverProc(HWND__ * 0x052d0532, unsigned int 0x0000c0aa, unsigned int
0x00000000, long 0x00ae2b40) line 932 + 9 bytes
USER32! 77e713ed()
00ae2b40()
Updating URL (renamed the .xml file).  Sorry about that file being on on
internal web server (to anybody on the outside).  If you're really curious,
email me and I'll send it to you.
Dupe of 11488? (Hard to tell without being able to access the testcase)
The call stack is different, but both bugs seemed to be triggered by removing an
option element.

Here's the xml file for this bug:

<app xmlns:foo="http://foo.bar.com/xml#"
xmlns:html="http://www.w3.org/TR/REC-html40">
<data>
    <var id="AppShell">
        <windowlist>
            <window type="browser" id="1"/>
            <window type="browser" id="2"/>
            <window type="mail-news" id="3"/>
        </windowlist>
    </var>
    <var id="ProfileMgr">
        <profilelist>
            <profile id="law" dir="file:///c/program
files/communicator/users/law"/>
            <profile id="home" dir="file:///c/program
files/communicator/users/home"/>
        </profilelist>
    </var>
</data>
	<html:script>
		function hex( value ) {
			var result = "";
			for( var i = 0; i &lt; value.length; i++ ) {
				var c = value[i] - 0;
				result += c.toString(16);
			}
			return result;
		}
		function nodeChildren( node ) {
			var kids = "";
			var children = node.childNodes;
			for( var i = 0; i &lt; children.length; i++ ) {
				kids += "\n\tchild[";
				kids += i;
				if ( children.item(i) != null ) {
					kids += "] = name[";
					kids += children.item( i ).nodeName;
					kids += "] = type[";
					kids += children.item( i ).nodeType;
					kids += "] value[";
					kids += children.item( i ).nodeValue;
					kids += "]";
				} else {
					kids += "] = null";
				}
			}
			return kids;
		}
		function nodeAttrs( node ) {
			var attrs = "";
			var attrList = node.attributes;
			for( var i = 0; attrList &amp;&amp; i &lt;
attrList.length; i++ ) {
				attrs += "\n\tattr[";
				attrs += attrList[i].nodeName;
				attrs += "] = [";
				attrs += attrList[i].nodeValue;
				attrs += "]";
			}
			return attrs;
		}
	    function nodeInfo( node, label ) {
		    var msg =  label + ":";
			msg += " name=[" + node.nodeName + "]";
			msg += " type=[" + node.nodeType + "]";
			msg += " value=[" + node.nodeValue + "]";
			msg += " len=[" + node.nodeValue.length + "]";
			msg += " hex=[" + hex(node.nodeValue) + "]";
			msg += nodeChildren(node);
			msg += nodeAttrs(node);
			return msg;
		}
		function showProfiles() {
			var data = document.getElementsByTagName( "profile" );
			var txt = "";
			for( var i = 0; i &lt; data.length; i++ ) {
				txt += "\n" + nodeInfo( data[i], "profile " + i
);
				for( var j = 0; j &lt;
data[i].attributes.length; j++ ) {
					var attr = data[i].attributes[j];
					txt += "\n\t" + nodeInfo( attr, "attr "
+ j );
				}
			}
			alert(txt);
		}
		function showOptions() {
			var opts = document.getElementsByTagName( "select" )[0];
			var txt = nodeInfo(opts, "\nOptions");
			alert(txt);
		}
	    function addOptions() {
		    var list = document.getElementsByTagName( "select" )[0];
			var data = document.getElementsByTagName( "profile" );
			for( var i = 0; i &lt; data.length; i++ ) {
				// Clone first option (second child).
				var opt  = list.childNodes[1].cloneNode( false
);
				if ( !opt ) {
					alert( "couldn't create new option
element!" );
					return;
				}
				var before = list.childNodes.length;
				// Insert after dummy node.
				list.insertBefore( opt, list.childNodes[2+i] );
				if ( before == list.childNodes.length ) {
					alert( "couldn't append child to list!"
);
					return;
				}
				opt.setAttribute( "index", i );
				var val =
data[i].attributes.getNamedItem("id").nodeValue;
				text = document.createTextNode( val );
				opt.appendChild( text );
			}
			// Remove dummy.
			list.removeChild( list.childNodes[1] );
		}
	</html:script>

	<html:div>
		<html:center>
		<html:table html:cols="1" html:width="90%"><html:tr><html:td>
		<html:b><html:font html:size="+1">Welcome to
Mozilla</html:font></html:b><html:br/>
		<html:p/>To access your personal profile, passwords, and
certificates, please
		   choose your profile from the list below.
		<html:p>If you have a Roaming Access profile which does not
exist on this
		   computer, choose Guest.  Mozilla will then prompt you to log
into your
		   Roaming Access server.<html:br/>
		<html:p/>Profile Name
		<html:select html:id="x" html:size="1" html:width="200">
			<html:option>dummy</html:option>
			<html:option>Guest</html:option>
			<html:script>addOptions();</html:script>
		</html:select>
		<html:hr/>
		<html:button>Manage Profiles</html:button>
		<html:button>Start Communicator</html:button>
		<html:button>Exit</html:button>
		</html:td></html:tr></html:table>
		</html:center>
	</html:div>

</app>
Crashes are all M11/P1/critical.
Status: NEW → RESOLVED
Closed: 25 years ago
Resolution: --- → FIXED
Had to fix the XML to make it well-formed - the <html:p> element before the text
"If you have Roaming..." needed a trailing slash (<html:p/>). Also, the
preferred way to have inline scripts is to surround the contents of a
<html:script> element a CDATA marked section (<![CDATA[ ... ]]>) rather than use
character entities (&lt; &gt; etc.) in the script.

Either way, I couldn't reproduce the crash. I suspect that Eric Pollmann's
changes to the relevant code over the past several weeks has helped.
Adding crash keyword
Keywords: crash
I do not see crash anymore.
Marking it verified.
Status: RESOLVED → VERIFIED
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.