Closed Bug 336147 Opened 18 years ago Closed 18 years ago

Changing innerHTML for <input type="button"> causes miss-rendering

Categories

(Core :: Layout: Form Controls, defect)

x86
All
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: sciguyryan, Assigned: sciguyryan)

References

()

Details

(Keywords: testcase)

Attachments

(3 files, 2 obsolete files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20060501 Minefield/3.0a1
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20060501 Minefield/3.0a1

When the design mode for the document is set explicitly to be off then clicking on  the button in the test case URL above accesses the innerHTML property of a HTML element that should not have an innerHTML property.

Setting design mode too on fixes this problem:

http://standards.spiralmindsinc.com/misc/designmode-testcases/innerhtml-02-designmode-on.html

Has been confirned on:

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20060501 Minefield/3.0a1
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8) Gecko/20060430
BonEcho/2.0a1
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.2)
Gecko/20060308 Firefox/1.5.0.2

Reproducible: Always

Steps to Reproduce:
1. Go the the URL above.
2. Click the button.

Actual Results:  
Somehow the innerHTML property is accessed for an element that should not have it and changed breaking the button.

Expected Results:  
Nothing, innerHTML is invalid for this element so should have returned a Javascript error.
Component: General → JavaScript Engine
Product: Firefox → Core
Version: unspecified → Trunk
Setting designMode to on disables javascript, so that's why it 'fixes' the problem.
DesignMode is not related to this.
innerHTML should work just fine for this replaced element, but it's probably more logical when the contents wouldn't show up.
The text input you get to see also, is because of bug 291047.

Reporter, could you attach the testcase to the bug?
Status: UNCONFIRMED → NEW
Component: JavaScript Engine → Layout
Ever confirmed: true
Keywords: testcase
QA Contact: general → layout
(In reply to comment #2)
> Created an attachment (id=220412) [edit]
> Testcase attatched as per Martijn Warger' request.
> 

Done. Anything else needed?
(In reply to comment #3)
> (In reply to comment #2)
> > Created an attachment (id=220412) [edit]
> > Testcase attatched as per Martijn Warger' request.
> > 
> 
> Done. Anything else needed?

A patch? ;)
(In reply to comment #4)
> A patch? ;)
> 

I'll have to start learning C++ then ;)
Summary: Illegal changing of the innerHTML property when designMode set too off. → Can change innerHTML of <input type="button">, and strange things happen when I do
So the problem is that our IsLeaf() checks are performed on the "parent" frame in  nsCSSFrameConstructor::ContentAppended/ContentInserted.  But that "parent" is the content insertion frame for the primary frame of our parent content.  And of course the content insertion frame of a button is an Area, which is not a leaf.

We could try to hack the frame constructor to look at both frames, I guess, but I think a possibly better approach is to change nsFrame::IsLeaf from |return PR_FALSE| to |return mParent && mParent->GetContentInsertionFrame() == this && mParent->IsLeaf()|.  At least assuming that our content insertion frames are always direct kids of the parent; are they?
Flags: blocking1.9?
I wouldn't bet on it. For example an overflow:auto column-count:2 block would have a nsGfxScrollFrame wrapping an nsColumnSetFrame wrapping one or more block frames.

I think the IsLeaf check should simply be performed on the primary frame for the content.
Ok.  So we basically need to change all the callers of IsLeaf() to do that (probably in addition to looking at the content insertion frame).

Ryan, you feeling up to doing that?
I'll take a shot :)
Summary: Can change innerHTML of <input type="button">, and strange things happen when I do → Changing innerHTML for <input type="button"> causes miss-renderin
Component: Layout → Layout: Form Controls
OS: Windows XP → All
Summary: Changing innerHTML for <input type="button"> causes miss-renderin → Changing innerHTML for <input type="button"> causes miss-rendering
I don't think we should look at the content insertion frame, just at the primary.
If we don't look at the insertion frame and it _is_ by some chance a leaf (like not a container frame), we'll crash in exploitable ways after trying to append frames to it.  So we should either be looking at it, or asserting in all GetContentInsertionFrame implementations that the return value is either |this| or a non-leaf.
I guess you're right and we should check both, although that seems incredibly lame.

Actually it seems strange that <input type="button"> implements GetContentInsertionFrame() at all, since we shouldn't be inserting content under it, except for the anonymous content. And I believe we don't use GetContentInsertionFrame when creating anonymous content, we always plug it in under the frame that created it. So I think nsGfxButtonControlFrame could just override GetContentInsertionFrame and return "this"...
Hmm.  That's a good point.  I guess it really doesn't make sense for leaves to implement GetContentInsertionFrame().

How about we do that, and have GetFrameFor() assert that either the insertion frame is the primary frame, or the primary is not a leaf?
Attached patch Patch v1 (obsolete) — Splinter Review
Patch v1

* Overrides the |GetContentInsertionFrame| method in |nsGfxButtonControlFrame|. Asserts in |nsCSSFrameConstructor::GetFrameFor| if the insertion frame is the primary frame or the primary frame isn't a leaf.
Assignee: nobody → sciguyryan
Status: NEW → ASSIGNED
Attachment #255273 - Flags: superreview?(roc)
Attachment #255273 - Flags: review?(roc)
+  return NS_STATIC_CAST(nsIFrame*, this);

You shouldn't need the cast here. Otherwise fine.
Nix the whitespace changes?
Attached patch Patch v1.1Splinter Review
Patch v1.1

* Reverted the space changes (thanks bz) and no longer use |NS_STATIC_CAST(nsIFrame*, this)| in favour of just returning |this| directly.
Attachment #255273 - Attachment is obsolete: true
Attachment #255327 - Flags: superreview?(roc)
Attachment #255327 - Flags: review?(bzbarsky)
Attachment #255273 - Flags: superreview?(roc)
Attachment #255273 - Flags: review?(roc)
Comment on attachment 255327 [details] [diff] [review]
Patch v1.1

I think roc can happily r+sr this.  ;)
Attachment #255327 - Flags: review?(bzbarsky) → review?(roc)
Attachment #255327 - Flags: superreview?(roc)
Attachment #255327 - Flags: superreview+
Attachment #255327 - Flags: review?(roc)
Attachment #255327 - Flags: review+
Whiteboard: [checkin needed]
Checking in base/nsCSSFrameConstructor.cpp;
/cvsroot/mozilla/layout/base/nsCSSFrameConstructor.cpp,v  <--  nsCSSFrameConstru
ctor.cpp
new revision: 1.1313; previous revision: 1.1312
done
Checking in forms/nsGfxButtonControlFrame.cpp;
/cvsroot/mozilla/layout/forms/nsGfxButtonControlFrame.cpp,v  <--  nsGfxButtonCon
trolFrame.cpp
new revision: 1.139; previous revision: 1.138
done
Checking in forms/nsGfxButtonControlFrame.h;
/cvsroot/mozilla/layout/forms/nsGfxButtonControlFrame.h,v  <--  nsGfxButtonContr
olFrame.h
new revision: 1.49; previous revision: 1.48
done

Checked into trunk.

Thanks for the patch, Ryan!
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Flags: blocking1.9?
Whiteboard: [checkin needed]
Flags: in-testsuite?
Attached patch Reftest v1 (obsolete) — Splinter Review
First shot at a reftest for this.
Attachment #257528 - Flags: review?(bzbarsky)
Attached patch Reftest v1Splinter Review
Get rid of the new line warning.
Attachment #257528 - Attachment is obsolete: true
Attachment #257529 - Flags: review?(bzbarsky)
Attachment #257528 - Flags: review?(bzbarsky)
Comment on attachment 257529 [details] [diff] [review]
Reftest v1

Looks good.
Attachment #257529 - Flags: review?(bzbarsky) → review+
Checked in the test.
Flags: in-testsuite? → in-testsuite+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: