|
|
|
@ -2083,10 +2083,10 @@ function URLBarSetURI(aURI, aValid) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function losslessDecodeURI(aURI) { |
|
|
|
|
let scheme = aURI.scheme; |
|
|
|
|
var value = aURI.spec; |
|
|
|
|
var scheme = aURI.scheme; |
|
|
|
|
|
|
|
|
|
var decodeASCIIOnly = !["https", "http", "file", "ftp"].includes(scheme); |
|
|
|
|
let decodeASCIIOnly = !["https", "http", "file", "ftp"].includes(scheme); |
|
|
|
|
// Try to decode as UTF-8 if there's no encoding sequence that we would break.
|
|
|
|
|
if (!/%25(?:3B|2F|3F|3A|40|26|3D|2B|24|2C|23)/i.test(value)) { |
|
|
|
|
if (decodeASCIIOnly) { |
|
|
|
@ -2098,26 +2098,36 @@ function losslessDecodeURI(aURI) {
|
|
|
|
|
} else { |
|
|
|
|
try { |
|
|
|
|
value = decodeURI(value) |
|
|
|
|
// decodeURI decodes %25 to %, which creates unintended
|
|
|
|
|
// encoding sequences. Re-encode it, unless it's part of
|
|
|
|
|
// a sequence that survived decodeURI, i.e. one for:
|
|
|
|
|
// ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#'
|
|
|
|
|
// (RFC 3987 section 3.2)
|
|
|
|
|
.replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)/ig, |
|
|
|
|
// 1. decodeURI decodes %25 to %, which creates unintended
|
|
|
|
|
// encoding sequences. Re-encode it, unless it's part of
|
|
|
|
|
// a sequence that survived decodeURI, i.e. one for:
|
|
|
|
|
// ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#'
|
|
|
|
|
// (RFC 3987 section 3.2)
|
|
|
|
|
// 2. Re-encode select whitespace so that it doesn't get eaten
|
|
|
|
|
// away by the location bar (bug 410726). Re-encode all
|
|
|
|
|
// adjacent whitespace, to prevent spoofing attempts where
|
|
|
|
|
// invisible characters would push part of the URL to
|
|
|
|
|
// overflow the location bar (bug 1395508).
|
|
|
|
|
.replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)|[\r\n\t]|\s(?=\s)|\s$/ig, |
|
|
|
|
encodeURIComponent); |
|
|
|
|
} catch (e) {} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Encode invisible characters (soft hyphen, zero-width space, BOM,
|
|
|
|
|
// line and paragraph separator, word joiner, invisible times,
|
|
|
|
|
// invisible separator, object replacement character,
|
|
|
|
|
// C0/C1 controls). (bug 452979, bug 909264)
|
|
|
|
|
// Encode bidirectional formatting characters.
|
|
|
|
|
// Encode invisible characters (C0/C1 control characters, U+007F [DEL],
|
|
|
|
|
// U+00A0 [no-break space], line and paragraph separator, braille space
|
|
|
|
|
// object replacement character) (bug 452979, bug 909264, bug 1629506)
|
|
|
|
|
value = value.replace(/[\u0000-\u001f\u007f-\u00a0\u2028\u2029\u2800\ufffc]/g, |
|
|
|
|
encodeURIComponent); |
|
|
|
|
|
|
|
|
|
// Encode default ignorable characters (bug 546013)
|
|
|
|
|
// except ZWNJ (U+200C) and ZWJ (U+200D) (bug 582186).
|
|
|
|
|
// This includes all bidirectional formatting characters.
|
|
|
|
|
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
|
|
|
|
|
// Re-encode whitespace so that it doesn't get eaten away
|
|
|
|
|
// by the location bar (bug 410726).
|
|
|
|
|
return value.replace(/[\u0000-\u001f\u007f-\u00a0\u00ad\u034f\u061c\u115f\u1160\u17b4\u17b5\u180b-\u180d\u200b\u200e\u200f\u2028-\u202e\u2060-\u206f\u3164\ufe00-\ufe0f\ufeff\uffa0\ufff0-\ufff8\ufffc]|\ud834[\udd73-\udd7a]|[\udb40-\udb43][\udc00-\udfff]/g, encodeURIComponent); |
|
|
|
|
value = value.replace(/[\u00ad\u034f\u061c\u115f-\u1160\u17b4-\u17b5\u180b-\u180d\u200b\u200e-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufe00-\ufe0f\ufeff\uffa0\ufff0-\ufff8]|\ud834[\udd73-\udd7a]|[\udb40-\udb43][\udc00-\udfff]/g, |
|
|
|
|
encodeURIComponent); |
|
|
|
|
|
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|