Closed Bug 371563 Opened 17 years ago Closed 17 years ago

Crash [@ nsCSSFrameConstructor::FindFrameWithContent] with SVG marker, float, overflow: scroll

Categories

(Core :: SVG, defect)

x86
macOS
defect
Not set
critical

Tracking

()

RESOLVED FIXED

People

(Reporter: jruderman, Assigned: longsonr)

References

Details

(Keywords: crash, testcase, Whiteboard: [sg:critical?] 1.9-only)

Crash Data

Attachments

(2 files, 5 obsolete files)

Security-sensitive because this bug causes Firefox (debug) to dereference 0xdddddddd.
Whiteboard: [sg:critical?]
This testcase does not crash Firefox 2.0.0.2

roc: if you are not the right assignee please find a home for this critical bug.
Assignee: general → roc
Flags: blocking1.9?
Whiteboard: [sg:critical?] → [sg:critical?] 1.9-only
I'll take a stab at replacing the marker observer code with a mutation observer implementation (c.f. bug 359516 which did it for filters) to see if that fixes it.
Won't that cause problems for DOM mutations that occur during load?  Or did bug 90983 only apply to DOM events, not nsIMutationObserver?
Yes. nsIMutationObserver events are always sent out. Layout is built almost entierly on top of those notifications.
Attached patch patch (obsolete) — Splinter Review
Assignee: roc → longsonr
Status: NEW → ASSIGNED
Attachment #257530 - Flags: review?(tor)
Won't this have the problems that Jesse has pointed out with similar implementations, namely hanging references if an ancestor of the <marker> is deleted?
(In reply to comment #6)
> Won't this have the problems that Jesse has pointed out with similar
> implementations, namely hanging references if an ancestor of the <marker> is
> deleted?
> 

Wouldn't NodeWillBeDestroyed be called, causing everything to be destroyed?

If not, your comment applies to filters too doesn't it? In any case I'm not sure what I, if anything I should do?
(In reply to comment #7)
> (In reply to comment #6)
> > Won't this have the problems that Jesse has pointed out with similar
> > implementations, namely hanging references if an ancestor of the <marker> is
> > deleted?
> 
> Wouldn't NodeWillBeDestroyed be called, causing everything to be destroyed?

That only gets called when the object is really destroyed (last reference is dropped).  Due to lazy JS garbage collection this could happen some time after it is removed from the tree.  

> If not, your comment applies to filters too doesn't it? In any case I'm not
> sure what I, if anything I should do?

Yes, it is a problem with filters - see bug 369438.

(In reply to comment #8)
> Yes, it is a problem with filters - see bug 369438.
> 

Could you cc me to that one please? I can't access it.

(In reply to comment #9)
> (In reply to comment #8)
> > Yes, it is a problem with filters - see bug 369438.
> 
> Could you cc me to that one please? I can't access it.

CC'd.
Comment on attachment 257530 [details] [diff] [review]
patch

I'll see how bug 369438 pans out then. Should this one block on that?
Attachment #257530 - Flags: review?(tor)
Attached patch update for changed API (obsolete) — Splinter Review
Attachment #257530 - Attachment is obsolete: true
Attachment #258288 - Flags: review?(tor)
Blocks: 309220
If you're removing the observers on the nsSVGMarkerFrame, you can remove that frame's inheritance of nsSVGValue.
Attached patch address review comment (obsolete) — Splinter Review
Attachment #258288 - Attachment is obsolete: true
Attachment #258406 - Flags: review?(tor)
Attachment #258288 - Flags: review?(tor)
Attachment #258406 - Flags: review?(tor) → review+
Attachment #258406 - Flags: superreview?(roc)
Comment on attachment 258406 [details] [diff] [review]
address review comment

Request review from myself to remind me to see if I'm happy to review this instead of roc.
Attachment #258406 - Flags: review?(jwatt)
Comment on attachment 258406 [details] [diff] [review]
address review comment

+  void GetMarkerFromStyle(MarkerPosition markerPosition,

aMarkerPosition

+  if (markerFrame &&
+      mMarkerStartFrame != markerFrame &&
+      mMarkerMidFrame != markerFrame &&
+      mMarkerEndFrame != markerFrame) {

This is a bit weird. Why not just compare to *aMarkerFrame here? Then we know when we're done that *aMarkerFrame is set to markerFrame. As it is, it could keep its old value if the new frame is used for one of the other markers.

With that, sr=roc
Attachment #258406 - Flags: superreview?(roc) → superreview+
Attached patch version for check in (obsolete) — Splinter Review
with sr comments addressed.
Attachment #258406 - Attachment is obsolete: true
Attachment #258406 - Flags: review?(jwatt)
That's not what I meant!

The test should be
  if (markerFrame && *aMarkerFrame != markerFrame)
... right?
(In reply to comment #18)
> That's not what I meant!
> 
> The test should be
>   if (markerFrame && *aMarkerFrame != markerFrame)
> ... right?
> 

I don't think so *aMarkerFrame  would always be null here.

If you have <rect  marker-mid="url(#marker1)" marker-end="url(#marker1)" ... /> then marker-mid and marker-end will get the same pointer from the NS_GetSVGMarkerFrame call. I want to avoid having two observers in that case so I to check whether the marker frame is the same as any of the existing marker frames. If it is then the existing marker would have an observer so I don't need to create another one.

You were correct that the original code did have a bug that if there was an existing identical marker frame the new code would not return the correct pointer.


I don't think you should do this optimization. It's too tricky and I don't see any reason why it would be important. The mObserverMarker* values should always match the mMarker*Frame values.

In particular, I think your latest code has a bug where e.g. if I set the start marker and then the end marker to the same element E, and then set the start marker to another element, we're not observing E anymore even though we should be because it's still the end marker.
Comment on attachment 258981 [details] [diff] [review]
version for check in

Please don't check this in until things are sorted out.
Attachment #258981 - Flags: superreview-
Attachment #258981 - Flags: review-
Attached patch address further sr comments (obsolete) — Splinter Review
(In reply to comment #20)
> I don't think you should do this optimization. It's too tricky and I don't see
> any reason why it would be important. The mObserverMarker* values should always
> match the mMarker*Frame values.

True, it is not required as AddMutationObserver already checks for duplicates. FWIW the code it replaces did not do that at the time I wrote it. I've removed the check and also updated RemoveMutationObserver so that it nulls out the observed marker once the observer has been removed.

> 
> In particular, I think your latest code has a bug where e.g. if I set the start
> marker and then the end marker to the same element E, and then set the start
> marker to another element, we're not observing E anymore even though we should
> be because it's still the end marker.
> 

That's not a problem. Marker changes are style updates so if you change one nsSVGPathGeometryFrame::DidSetStyleContext is called and all the marker observers are discarded so you start again each time.
Attachment #258981 - Attachment is obsolete: true
Attachment #258986 - Flags: superreview?(roc)
Oops, I'm too slow. BTW roc, requesting review from myself wasn't a hint that you're to slow. On the contrary, you do an awesome job of getting through your review queue considering the number of review requests you get. Rather my review request was an acknowledgment that your do get a lot of requests, and we should try and take some of that load where possible.
Comment on attachment 258986 [details] [diff] [review]
address further sr comments

+    nsCOMPtr<nsIContent> markerContent = (*aMarkerFrame)->GetContent();

I think this could just be an nsIContent*.

jwatt: thanks, but this was an sr request so I need to do it, right?
Attachment #258986 - Flags: superreview?(roc) → superreview+
tor's review could have counted as sr and mine as peer review - anyway, that's academic now.
(In reply to comment #24)
> (From update of attachment 258986 [details] [diff] [review])
> +    nsCOMPtr<nsIContent> markerContent = (*aMarkerFrame)->GetContent();
> 
> I think this could just be an nsIContent*.
> 

Changed as suggested.

I also reverted RemoveMutationObserver not to null its argument as it is only called from the destructor so the pointers are going away anyway. RemoveMutationObserver is now back to what it was when tor reviewed it.
Attachment #258986 - Attachment is obsolete: true
Without having looked at the code, that sounds like a bad idea to me. Functions should not make assumptions about who is calling them, and besides, that could change in future. I'm also against being "clever"/"optimizing" where pointers to freed memory is concerned. Somewhere, sometime it'll go wrong and the consequences are potentially way, way too serious to make it worth the negligible optimizations. IMHO pointers to freed memory should always be nulled out. Always.
When I say "freed memory" I mean that in the most general sense. I.e. I'm including out param pointers that aren't assigned anything valid.
We're not freeing any memory in RemoveMutationObserver just using the pointer to remove the mutation observer. The pointer is still valid.
Okay, I was just going on what your comment sounded like. Anyway, you guys know what you're doing.
checked in.
Status: ASSIGNED → RESOLVED
Closed: 17 years ago
Resolution: --- → FIXED
Blocks: 374766
Flags: wanted1.8.1.x-
Group: security
Flags: in-testsuite?
Crashtest checked in.
Flags: in-testsuite? → in-testsuite+
Crash Signature: [@ nsCSSFrameConstructor::FindFrameWithContent]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: