ICEfaces
  1. ICEfaces
  2. ICE-8672

ExternalContext.redirect() encodes the URL

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: EE-1.8.2.GA_P04
    • Fix Version/s: EE-1.8.2.GA_P05
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces
    • Assignee Priority:
      P1

      Description


      The implementation of ExternalContext.redirect() encodes the URL that is passed to the method, although it must not. This behavior is not mentioned in the JSF specification, and must not be performed.

      If you encode yourself the URL passed in as a String to redirect(), this means that you consider that the URL is not encoded by the caller. Then, how can you correctly parse that URL ? More precisely, if the URL is not encoded, how do you distinguish that the '?' character found in the URL is actually the separator between the path and the query string, or a character in the value of a query string parameter.

      As an example, the following URL

      /redirector/goto?newUrl=http://some.site.com/pages?id=12

      is parsed by BridgeExternalContext into an URI with the following characteristics:
      path = /redirector/goto?newUrl=http://some.site.com/pages
      querystring = id=12
      and then encoded into this:

      /redirector/goto%3FnewUrl=http://some.site.com/pages?id=12

      This may or may not be correct. Only the client knows it. The client actually makes this clear by encoding the URL before passing it to redirect(). In my example, this means:

      /redirector/goto?newUrl=http://some.site.com/pages%3Fid=12

      Of course, ExternalContext.redirect() must not re-encode the passed in URL, or we will get something like:
      /redirector/goto?newUrl=http://some.site.com/pages%253Fid=12
      because %3F is encoded as %253F.

        Activity

        Hide
        Evgheni Sadovoi added a comment - - edited

        Based on the =C2=A72.4.2 "When to escape and unescape" of the RFC-2396 URI =
        standart:
        "A URI is always in an "escaped" form, since escaping or unescaping a=20
        completed URI might change its semantics. Normally, the only time=20
        escape encodings can safely be made is when the URI is being created=20
        from its component parts; each component may have its own set of=20
        characters that are reserved, so only the mechanism responsible for=20
        generating or interpreting that component can determine whether or=20
        not escaping a character will change its semantics. Likewise, a URI=20
        must be separated into its components before the escaped characters=20
        within those components can be safely decoded. [...] Implementers should be=
        careful not to=20
        escape or unescape the same string more than once, since unescaping=20
        an already unescaped string might lead to misinterpreting a percent=20
        data character as another escaped character, or vice versa in the=20
        case of escaping an already escaped string."=20
        As a comment in the source code for the BridgeExternalContext.redirect() me=
        thod, there's a note about JIRA ICE-3427. I had a look at this JIRA; it ask=
        s to encode the String passed to redirect(), which certainly led to the cur=
        rent implementation of BridgeExternalContext.redirect():=20
        "Besides, encondig URI according to RFC 2396 should be done by ICEFaces imp=
        lementation, exactly like it happens using JSF SUN RI."=20
        This is wrong : neither JSF RI's ExternalContext.redirect(), nor HttpServle=
        tResponse.sendRedirect(), do some sort of encoding, as they know a URL pass=
        ed as a String cannot be encoded; as specified by RFC, this is illegal.=20
        If a navigation rule references a viewId containing blank chars, the view h=
        andler is responsible for encoding this. It is legal to do it at this stage=
        , because the viewId is a component part (actually the final path segment) =
        of the final URI, and as specified by RFC2396 "the only time escape encodin=
        gs can safely be made is when the URI is being created from its component p=
        arts". When the whole URI is created (just like the parameter passed to Ext=
        ernalContext.redirect()), it is too late to encode it.=20
        =20

        Show
        Evgheni Sadovoi added a comment - - edited Based on the =C2=A72.4.2 "When to escape and unescape" of the RFC-2396 URI = standart: "A URI is always in an "escaped" form, since escaping or unescaping a=20 completed URI might change its semantics. Normally, the only time=20 escape encodings can safely be made is when the URI is being created=20 from its component parts; each component may have its own set of=20 characters that are reserved, so only the mechanism responsible for=20 generating or interpreting that component can determine whether or=20 not escaping a character will change its semantics. Likewise, a URI=20 must be separated into its components before the escaped characters=20 within those components can be safely decoded. [...] Implementers should be= careful not to=20 escape or unescape the same string more than once, since unescaping=20 an already unescaped string might lead to misinterpreting a percent=20 data character as another escaped character, or vice versa in the=20 case of escaping an already escaped string."=20 As a comment in the source code for the BridgeExternalContext.redirect() me= thod, there's a note about JIRA ICE-3427 . I had a look at this JIRA; it ask= s to encode the String passed to redirect(), which certainly led to the cur= rent implementation of BridgeExternalContext.redirect():=20 "Besides, encondig URI according to RFC 2396 should be done by ICEFaces imp= lementation, exactly like it happens using JSF SUN RI."=20 This is wrong : neither JSF RI's ExternalContext.redirect(), nor HttpServle= tResponse.sendRedirect(), do some sort of encoding, as they know a URL pass= ed as a String cannot be encoded; as specified by RFC, this is illegal.=20 If a navigation rule references a viewId containing blank chars, the view h= andler is responsible for encoding this. It is legal to do it at this stage= , because the viewId is a component part (actually the final path segment) = of the final URI, and as specified by RFC2396 "the only time escape encodin= gs can safely be made is when the URI is being created from its component p= arts". When the whole URI is created (just like the parameter passed to Ext= ernalContext.redirect()), it is too late to encode it.=20 =20
        Hide
        Jack Van Ooststroom added a comment - - edited

        The described encoding issue is indeed incorrect behavior in ICEfaces. However, the original "fix" (ICE-3427) dated back over 4 years and a recent context parameter was introduced (ICE-8270) in order to be able to disable this encoding. It was discussed that the default of this context parameter might needed to be switched to disable encoding. But due to the incorrect encoding being in there for a long period and user's possible reliance on this old behavior, it was decided to leave the default as is: encode by default. In order to get the correct behavior this context parameter can be set to disable encoding. Marking this one as FIXED.

        Show
        Jack Van Ooststroom added a comment - - edited The described encoding issue is indeed incorrect behavior in ICEfaces. However, the original "fix" ( ICE-3427 ) dated back over 4 years and a recent context parameter was introduced ( ICE-8270 ) in order to be able to disable this encoding. It was discussed that the default of this context parameter might needed to be switched to disable encoding. But due to the incorrect encoding being in there for a long period and user's possible reliance on this old behavior, it was decided to leave the default as is: encode by default. In order to get the correct behavior this context parameter can be set to disable encoding. Marking this one as FIXED.

          People

          • Assignee:
            Deryk Sinotte
            Reporter:
            Evgheni Sadovoi
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: