Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#9518 closed bug (fixed)

Tabs: URLs encoded in anything other than UTF-8 will throw an error

Reported by: badatos Owned by: badatos
Priority: minor Milestone: 1.11.0
Component: ui.tabs Version: 1.10.3
Keywords: Cc:
Blocked by: Blocking:

Description

Hello, I detected (and found a correction) for a bug in jquery UI 1.10.3 tabs.

Tabs doesn't work at all if a special char is present in URL. If your URL looks like that :

http://localhost/index.php?search_keywords=alg%E8bre

(it contains %E8, for accented letter "è" in french word "algèbre" )

... you get an error "URIError: URI error (tested on Safari Version 5.1.9 ) or the more precise one :

"URIError: malformed URI sequence

decodeURIComponent(anchor_href ) ===" (tested on Firefox 23.0.1 with firebug )

Here is the function now :

function isLocal( anchor ) {
	var anchor_href=encodeURIComponent();
	var loc_href=encodeURIComponent();

	return anchor.hash.length > 1 &&
		decodeURIComponent(anchor.href.replace( rhash, "" )) ===
			decodeURIComponent( location.href.replace( rhash, "" ) );
}

.. and here is what i propose, which works very fine for me :

function isLocal( anchor ) {
	var anchor_href=encodeURIComponent(anchor.href.replace( rhash, "" ));
	var loc_href=encodeURIComponent(location.href.replace( rhash, "" ));

	return anchor.hash.length > 1 &&
		decodeURIComponent(anchor_href  ) ===
			decodeURIComponent( loc_href );
}

Or , in a "write less" way :

function isLocal( anchor ) {
	return anchor.hash.length > 1 &&
		decodeURIComponent( encodeURIComponent(anchor.href.replace( rhash, "" )) ) ===
			decodeURIComponent( encodeURIComponent(location.href.replace( rhash, "" )) );
}

Change History (15)

comment:1 Changed 4 years ago by badatos

Sorry, i did a bad copy/paste, here's the actual code by now :

function isLocal( anchor ) {
	return anchor.hash.length > 1 &&
		decodeURIComponent(anchor.href.replace( rhash, "" )) ===
			decodeURIComponent( location.href.replace( rhash, "" ) );
}

;)

comment:2 Changed 4 years ago by tj.vantoll

Owner: set to badatos
Status: newpending

Hi badatos,

Thanks for taking the time to contribute to the jQuery UI project. I'm not seeing the behavior that you're describing: http://jsfiddle.net/tj_vantoll/6sK7H/.

Could you alter my test case so that it shows the issue you're experiencing?

Thanks.

comment:3 Changed 4 years ago by badatos

Status: pendingnew

Hi tj.vantoll ! Thank you for your quick response.

In fact, the bug comes when the special char is in the page URL itself.

You can easily check the bug with this URL :

http://fiddle.jshell.net/6sK7H/show/?variable=alg%E8bre

i added a fake variable in your fiddle URL, and the 2 contents are melted now !

Just remove the %E8, and it works again :

http://fiddle.jshell.net/6sK7H/show/?variable=algebre

With my correction, it will works in both cases.

comment:4 Changed 4 years ago by Scott González

Status: newpending

Well, your proposed fix is obviously not the correct fix as you're effectively removing the decoding. How did you get the %E8 in the first place? The proper encoding for è is %C3%A8.

comment:5 in reply to:  4 Changed 4 years ago by badatos

Status: pendingnew

Replying to scott.gonzalez:

Well, your proposed fix is obviously not the correct fix as you're effectively removing the decoding. How did you get the %E8 in the first place? The proper encoding for è is %C3%A8.

The test was on a page using charset iso 8859-1, and %E8 is "è" in this case. "%C3%A8" is in UTF-8. (n.b. :sadly, i can't change the page to UTF-8. )

comment:6 Changed 4 years ago by Scott González

Status: newpending

How do you end up with the URL? Are you manually encoding it or is a browser encoding it?

comment:7 in reply to:  6 Changed 4 years ago by badatos

Status: pendingnew

Replying to scott.gonzalez:

How do you end up with the URL? Are you manually encoding it or is a browser encoding it?

The page is called by a form like this :

<form action="http://localhost/search_engine.html#searchform" method="get">
  <input name="search_keywords" value="algèbre" >
</form>

Input is completed by user.

For my issue, i just can change method to "post", and the problem is quickly solved, but i thought it was better to warn you about this.

comment:8 Changed 4 years ago by Scott González

Status: newopen
Summary: tabs doesn't work if a special char is present in URLTabs: URLs encoded in anything other than UTF-8 will throw an error

Thanks, that explains it. So here's the problem: The ISO-8859-1 page will generate a URL that is encoded using ISO-8859-1. However, decodeURIComponent() ALWAYS uses UTF-8 for the character set. I honestly don't think this is something we can properly fix. My only thought is that we can wrap the decoding in a try/catch and just accept the fact that there are some situations we can't handle. Perhaps when Safari 5.1 dies out we can just remove the encoding, but we'll need to verify that #8896 is actually limited to spaces in other browsers.

Last edited 4 years ago by Scott González (previous) (diff)

comment:9 Changed 4 years ago by badatos

I agree with you, A try/catch will probably do the job fine.

Anyway, there obviously will be less and less pages in ISO-8859-1, I hope...

Thank's again for the really good job you all do with Jquery UI.

comment:10 Changed 4 years ago by telensky

I have the same problem. I used the following workaround

http://stackoverflow.com/a/19696946/684229

So my patch to jqueryui looks like this:

function isLocal( anchor ) {
        return anchor.hash.length > 1 && 
                decodeURIComponent( unescape( unescape( anchor.href.replace( rhash, "" ) ) ) ) ===
                        decodeURIComponent( unescape( unescape( location.href.replace( rhash, "" ) ) ) );
}

Note that there should probably be repeat-until loop which would call unescape until the result is the same.

But please note that this workaround is not clean and normally only UTF-8 characters should be used in URLs. The clean solution to this problem (appart from changing the page encoding to UTF-8, which is not always possible) is discussed here

http://stackoverflow.com/q/19702662/684229

Please if you know the answer post it there.

comment:11 in reply to:  10 Changed 4 years ago by Scott González

Replying to telensky:

decodeURIComponent( unescape( unescape( anchor.href.replace( rhash, "" ) ) ) ) ===

decodeURIComponent( unescape( unescape( location.href.replace( rhash, "" ) ) ) );

Multiple decoding seems very wrong. Regardless of whether it can result in correct behavior.

Note that there should probably be repeat-until loop which would call unescape until the result is the same.

No, we should just check raw and decoded.

But please note that this workaround is not clean and normally only UTF-8 characters should be used in URLs.

Actually, URLs can't be UTF-8 in all cases, which is what this ticket is all about.

comment:12 Changed 4 years ago by Scott González

Status: openpending

@badatos I actually don't see any way to make this actually work. Is your goal just to avoid getting an error, not to actually support matching URLs?

comment:13 in reply to:  12 Changed 4 years ago by badatos

Status: pendingnew

Replying to scott.gonzalez:

@badatos I actually don't see any way to make this actually work. Is your goal just to avoid getting an error, not to actually support matching URLs?

Me neither... I think it could be just fine if it don't throw an error anymore, just ignoring malformed urls...

comment:14 Changed 4 years ago by Scott González

Resolution: fixed
Status: newclosed

Tabs: Don't decode URLs if they're not UTF-8. Fixes #9518 - Tabs: URLs encoded in anything other than UTF-8 will throw an error.

Changeset: 874865842bdbbf5ec48ee41640951e9f103c0f16

comment:15 Changed 4 years ago by Scott González

Milestone: none1.11.0
Note: See TracTickets for help on using tickets.