Bug 35180 - [V8] V8LocationCustom.cpp doesn't handle location.hash updates properly
Summary: [V8] V8LocationCustom.cpp doesn't handle location.hash updates properly
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Platform (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Dirk Pranke
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-19 14:43 PST by Dirk Pranke
Modified: 2010-02-26 08:36 PST (History)
6 users (show)

See Also:


Attachments
tentative patch for this fix - don't review / land, it doesn't have the changelog entry (967 bytes, patch)
2010-02-22 13:05 PST, Dirk Pranke
no flags Details | Formatted Diff | Diff
Patch (6.09 KB, patch)
2010-02-24 19:48 PST, Dirk Pranke
no flags Details | Formatted Diff | Diff
Patch (4.77 KB, patch)
2010-02-25 12:52 PST, Dirk Pranke
no flags Details | Formatted Diff | Diff
revised patch - fix js indentation in test file. (3.09 KB, patch)
2010-02-25 16:38 PST, Dirk Pranke
no flags Details | Formatted Diff | Diff
whoops - lost the changelogs; reattaching (4.80 KB, patch)
2010-02-25 16:42 PST, Dirk Pranke
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Pranke 2010-02-19 14:43:55 PST
See http://crbug.com/32633 .

If we update the hash on an "about:blank" URL, the code first decides that we're changing the location and then thinks that we're changing it in a way that triggers a navigation, producing an infinite loop in the following HTML:

<script> 
  function displayPrivacy() {
    alert(trm2.location);
    trm2.location.hash = 'Privacy';
  }
</script>
<iframe name=trm2 id=trm2 onload="displayPrivacy()" 
src="about:blank"></iframe>
Comment 1 Dirk Pranke 2010-02-22 13:05:16 PST
Created attachment 49238 [details]
tentative patch for this fix - don't review / land, it doesn't have the changelog entry
Comment 2 Darin Fisher (:fishd, Google) 2010-02-22 13:38:53 PST
This change looks good to me.
Comment 3 Dirk Pranke 2010-02-24 19:48:10 PST
Created attachment 49462 [details]
Patch
Comment 4 Darin Fisher (:fishd, Google) 2010-02-24 23:08:31 PST
Comment on attachment 49462 [details]
Patch

> +++ b/LayoutTests/fast/loader/about-blank-hash-change.html
> @@ -0,0 +1,34 @@
> +<script>
> +if (window.layoutTestController) {
> +    layoutTestController.dumpAsText();
> +}
> +
> +function onload_callback() {
> +  var old_hash = inner.location.hash;
> +  inner.location.hash = 'hash-ref';
> +  var c = document.getElementById('content');
> +  if (c.innerHTML.match(/^No callback/)) {
> +    c.innerHTML = 'PASS: inner.location.hash = "' + inner.location.hash + '"';
> +  } else if (c.innerHTML.match(/^PASS/)) {
> +    c.innerHTML = c.innerHTML + 'FAIL: inner.location.hash = "' + inner.location.hash + '"';
> +  }

up top you use 4 space indent, but here you use 2 spaces.  it'd be
good to use consistent indentation.


> +++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
> @@ -70,15 +70,23 @@ void V8Location::hashAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Va
>      if (!frame)
>          return;
>  
> -    KURL url = frame->loader()->url();
> +    // We copy the URL to avoid accidentally modifying it in place
> +    // and then returning without actually doing anything. This is
> +    // perhaps overly conservative.
> +    KURL url = frame->loader()->url().copy();

This is unnecessary.  The .copy method is used when you need to copy
a KURL to another thread.  The existing code was using the copy ctor
which is perfect for this single threaded use case.
Comment 5 Dirk Pranke 2010-02-25 10:28:31 PST
> > +++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
> > @@ -70,15 +70,23 @@ void V8Location::hashAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Va
> >      if (!frame)
> >          return;
> >  
> > -    KURL url = frame->loader()->url();
> > +    // We copy the URL to avoid accidentally modifying it in place
> > +    // and then returning without actually doing anything. This is
> > +    // perhaps overly conservative.
> > +    KURL url = frame->loader()->url().copy();
> 
> This is unnecessary.  The .copy method is used when you need to copy
> a KURL to another thread.  The existing code was using the copy ctor
> which is perfect for this single threaded use case.

I thought from reading the comments in kurl.h that the copy ctor was only doing a shallow copy and so when I updated the .hash in the copy the original would also be updated. I'm wrong?
Comment 6 Darin Fisher (:fishd, Google) 2010-02-25 10:41:51 PST
Right.  It does a shallow copy of objects that are copy-on-write.  Those objects (String, CString) do not implement threadsafe copy-on-write, so it is not safe to use the copy constructor to create a KURL instance that you can then pass to another thread.
Comment 7 Dirk Pranke 2010-02-25 12:52:11 PST
Created attachment 49526 [details]
Patch
Comment 8 Dirk Pranke 2010-02-25 16:38:05 PST
Created attachment 49545 [details]
revised patch - fix js indentation in test file.
Comment 9 Dirk Pranke 2010-02-25 16:42:36 PST
Created attachment 49546 [details]
whoops - lost the changelogs; reattaching
Comment 10 WebKit Commit Bot 2010-02-26 08:36:38 PST
Comment on attachment 49546 [details]
whoops - lost the changelogs; reattaching

Clearing flags on attachment: 49546

Committed r55285: <http://trac.webkit.org/changeset/55285>
Comment 11 WebKit Commit Bot 2010-02-26 08:36:43 PST
All reviewed patches have been landed.  Closing bug.