Bug 18951

Summary: all DOM operations stop working when location.hash set to '#'
Product: WebKit Reporter: Nick Santos <nicksantos>
Component: New BugsAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: brettw, ian.eng.webkit, mrowe
Priority: P2 Keywords: InRadar
Version: 525.x (Safari 3.1)   
Hardware: PC   
OS: OS X 10.5   
URL: http://www.nick-santos.com/tests/safari_hash_test.html

Description Nick Santos 2008-05-08 14:04:40 PDT
The following javascript code:

     window.location.hash = '#b=BBB';

     var node = document.createElement('span');
     node.innerHTML = 'Safari ';
     document.body.appendChild(node);

     window.location.hash = '#';
  
     var node2 = document.createElement('span');
     node2.innerHTML = 'can\'t take the heat!';
     document.body.appendChild(node2);

makes all subsequent DOM operations fail. Weird.
Comment 1 Mark Rowe (bdash) 2008-05-08 14:06:18 PDT
<rdar://problem/5921760>
Comment 2 Feng Qian 2008-05-08 15:02:34 PDT
KURL::setRef drops "#" if the hash string is empty, but FF appends '#' to the end of URL.

Is it safe to just append "#" to new url even when the hash string is empty?

Comment 3 Feng Qian 2008-05-08 15:36:33 PDT
I tried this patch on my local build, and it fixes the issue described by Nick.
Does this change has side-effect? and why '#' makes difference?

Index: KURL.cpp
===================================================================
--- KURL.cpp	(revision 32987)
+++ KURL.cpp	(working copy)
@@ -705,7 +705,7 @@ void KURL::setRef(const String& s)
 {
     if (!m_isValid)
         return;
-    parse(m_string.left(m_queryEnd) + (s.isEmpty() ? "" : "#" + s));
+    parse(m_string.left(m_queryEnd) + "#" + s);
 }
Comment 4 Brett Wilson (Google) 2008-05-09 11:36:01 PDT
You could change the setter to clear the # when you pass a NULL string, but make the ref empty (leaving the #) when you pass an empty string. I think this pattern would be good to use for the other setters as well (at least, the query) so that "foo?" and "foo" can be differentiated in the setter.
Comment 5 Feng Qian 2008-05-09 13:12:22 PDT
(In reply to comment #4)
> You could change the setter to clear the # when you pass a NULL string, but
> make the ref empty (leaving the #) when you pass an empty string. I think this
> pattern would be good to use for the other setters as well (at least, the
> query) so that "foo?" and "foo" can be differentiated in the setter.
> 

That's good point. What's the difference between a URL with '#' and empty hash, and the same URL without '#' and hash? It seems changed loader behavior.
Comment 6 Brady Eidson 2008-07-07 12:28:57 PDT
Working on this right now - seems that a tweak inside KURL will be the solution.
Comment 7 Brady Eidson 2008-07-07 13:36:38 PDT
Fixed in http://trac.webkit.org/changeset/35040