google-code-export / gwt-platform

Automatically exported from code.google.com/p/gwt-platform
1 stars 0 forks source link

PlaceRequest parameters encoding causes history not to work as expected #440

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
PlaceManagerImpl.updateHistory() does not work properly when tokens contain 
some special characters (GWTP 0.7).

I encountered the bug with parameters that contain characters such as  '=' and  
'"'.

The problem is at line 497. Indeed, I noticed getBrowserHistoryToken() does not 
return exactly the token that was pushed in the History but a decoded version 
of it. After investigating, I discovered History.getToken() decodes it. It 
sounds like browsers do not have the same behavior with History and GWT decided 
to return a decoded version of the token.

The default permutation uses this method to decode:
  protected native String decodeFragment(String encodedFragment) /*-{
    // decodeURI() does *not* decode the '#' character.
    return decodeURI(encodedFragment.replace("%23", "#"));
  }-*/;

In Mozilla permutation, there is this comment:
    // Mozilla browsers pre-decode the result of location.hash, so there's no
    // need to decode it again (which would in fact be incorrect).

I did not expect GWT to return a decoded version of tokens (there may be a 
technical reason).

Anyway, line 497 compares two String that do not have the same encoding. I 
reached to fix the problem by decoding also the historyToken variable using the 
same encoding algorithm as in the JSNI method above.

String decodedNewToken =                        
URL.decode(historyToken.replace("%23", "#"));
Then equals becomes: !browserHistoryToken.equals(decodedNewToken)

It fixed the problem in my case. I did not test with other special characters 
but as I use the same encoding algorithm, I should work.

Original issue reported on code.google.com by benoit.sautel@gmail.com on 26 Sep 2012 at 8:57

GoogleCodeExporter commented 9 years ago
After more tests with parameter values that contain some URLs, I discovered 
this code does not work with Firefox.

The comment in the Mozilla permutation indicates that no decoding is necessary 
because Firefox already decodes it. In fact, it's not absolutely right. Firefox 
decodes but not with the same decoding algorithm. While other browsers use 
decodeURIComponent() Javascript function, Firefox seems to decode with 
decodeURI().

I reached to fix the problem with URL in parameters with the following code:
  /**
     * Firefox does not decode history like the other browsers. It uses
     * decodeURI() Javascript function whereas other browsers use
     * decodeURIComponent().
     */
    private String decodeTokenAsHistoryDecodesToken(String historyToken)
    {
        if (Navigator.getUserAgent().contains("Firefox/")) {
            return URL.decodeQueryString(historyToken);
        }
        return URL.decode(historyToken.replace("%23", "#"));
    }

My decodedNewVersion variable is assigned to this method return.

I did not use differed binding to get a different behavior with browsers but it 
would be a good practice.

But I believe this fix is a workaround for GWT's History.getToken() method that 
does not have the same behavior on browsers.

Original comment by benoit.sautel@gmail.com on 27 Sep 2012 at 9:59

GoogleCodeExporter commented 9 years ago

Original comment by goudreau...@gmail.com on 27 Nov 2012 at 2:36