Bug 1793521 - Make sure URLs with invalid IDNA labels parse the same round-trip r=necko-reviewers,kershaw

This was regressed by bug 1788115, which allowed us to parse ASCII labels
again to enforce they're valid. However, the existing code only checked for
invalid punycode (that fails decoding), not ACE labels that are invalid.

If we don't check for this condition uidna_labelToUnicode will add a U+FFFD
character to the end of the label, making us encode it again, changing the URL.
When that happens, the principal's origin may change between serializations,
which is not OK.

Depends on D159373

Differential Revision: https://phabricator.services.mozilla.com/D160785
This commit is contained in:
Valentin Gosu 2022-11-01 09:50:18 +00:00
Родитель 00b54695c2
Коммит f4e5d22860
3 изменённых файлов: 16 добавлений и 2 удалений

Просмотреть файл

@ -65,6 +65,15 @@ class IDNA final {
return (mErrorCode & UIDNA_ERROR_PUNYCODE) != 0;
}
/* The label was successfully ACE (Punycode) decoded but the resulting
* string had severe validation errors. For example,
* it might contain characters that are not allowed in ACE labels,
* or it might not be normalized.
*/
bool HasInvalidAceLabel() const {
return (mErrorCode & UIDNA_ERROR_INVALID_ACE_LABEL) != 0;
}
/**
* Checks if the domain name label has any invalid hyphen characters.
*

Просмотреть файл

@ -188,8 +188,8 @@ nsresult nsIDNService::IDNA2008StringPrep(const nsAString& input,
// appears to get an appended U+FFFD REPLACEMENT CHARACTER, which will
// confuse our subsequent processing, so we drop that.
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1399540#c9)
if (info.HasInvalidPunycode() && !output.IsEmpty() &&
output.Last() == 0xfffd) {
if ((info.HasInvalidPunycode() || info.HasInvalidAceLabel()) &&
!output.IsEmpty() && output.Last() == 0xfffd) {
output.Truncate(output.Length() - 1);
}

Просмотреть файл

@ -1036,3 +1036,8 @@ add_task(function test_iconURI_serialization() {
add_task(function test_jarURI_serialization() {
check_round_trip_serialization("jar:http://example.com/bar.jar!/");
});
add_task(async function round_trip_invalid_ace_label() {
let uri = Services.io.newURI("http://xn--xn--d--fg4n-5y45d/");
Assert.equal(uri.spec, "http://xn--xn--d--fg4n-5y45d/");
});