Bug 45938 - _web_makePluginViewsPerformSelector:: mutates subviews array while iterating it
Summary: _web_makePluginViewsPerformSelector:: mutates subviews array while iterating it
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Plug-ins (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac All
: P2 Normal
Assignee: John Sullivan
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-16 18:07 PDT by John Sullivan
Modified: 2010-09-16 21:07 PDT (History)
0 users

See Also:


Attachments
Patch to avoid mutating array while enumerating it. (3.55 KB, patch)
2010-09-16 18:14 PDT, John Sullivan
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description John Sullivan 2010-09-16 18:07:59 PDT
This is in Radar as <rdar://problem/8395558>

The method -[NSArray _web_makePluginViewsPerformSelector:withObject:], which is implemented in WebHTMLView.mm, uses -[NSArray objectEnumerator] to enumerate the receiver array. The two callers to this method both send it to [self subviews]. [NSView subviews] returns the "live" mutable NSArray holding a view's subviews, so if the selector causes the view's subviews to change, the array will be mutated while it's being enumerated, which is an ObjC no-no that causes an NSException to be thrown (and ensuing havoc).
Comment 1 John Sullivan 2010-09-16 18:14:12 PDT
Created attachment 67870 [details]
Patch to avoid mutating array while enumerating it.
Comment 2 Darin Adler 2010-09-16 19:40:47 PDT
Comment on attachment 67870 [details]
Patch to avoid mutating array while enumerating it.

Historically, objectEnumerator creating a copy of the entire array! Iā€™m surprised that it has changed so that it no longer does so.

Does this work properly when there are no subviews?

Instead of initWithArray: you could have used the copy method.

r=me
Comment 3 John Sullivan 2010-09-16 21:04:09 PDT
The fast enumeration introduced with ObjC-2.0 is used with objectEnumerator; that's when the prohibition against mutating a collection while enumerating it began. Other bugs like this have been fixed in WebKit, though maybe the others were all a long time ago (e.g. <http://trac.webkit.org/changeset/24827>).

initWithArray: will return an empty array when passed nil, but the documentation is not clear about this. -copy will call -initWithArray:, but I guess it's a little bit better because it's unambiguous about what you'll get with a nil initial array, so I'll switch to using that.

Thanks for reviewing!
Comment 4 John Sullivan 2010-09-16 21:07:40 PDT
Fixed in r67691.