nsresult nsIDNService::decodeACE(const nsACString& in, nsACString& out, bool allowUnassigned) { bool isAce; IsACE(in, &isAce); if (!isAce) { out.Assign(in); return NS_OK; } // RFC 3490 - 4.2 ToUnicode // The ToUnicode output never contains more code points than its input. punycode_uint output_length = in.Length() - kACEPrefixLen + 1; punycode_uint *output = new punycode_uint[output_length]; NS_ENSURE_TRUE(output, NS_ERROR_OUT_OF_MEMORY); enum punycode_status status = punycode_decode(in.Length() - kACEPrefixLen, PromiseFlatCString(in).get() + kACEPrefixLen, &output_length, output, nullptr); if (status != punycode_success) { delete [] output; return NS_ERROR_FAILURE; } // UCS4 -> UTF8 output[output_length] = 0; nsAutoString utf16; ucs4toUtf16(output, utf16); delete [] output; if (!isOnlySafeChars(utf16, mIDNBlacklist)) return NS_ERROR_FAILURE; CopyUTF16toUTF8(utf16, out); // Validation: encode back to ACE and compare the strings nsAutoCString ace; nsresult rv = UTF8toACE(out, ace, allowUnassigned); NS_ENSURE_SUCCESS(rv, rv); if (!ace.Equals(in, nsCaseInsensitiveCStringComparator())) return NS_ERROR_FAILURE; return NS_OK; }
NS_IMETHODIMP nsIDNService::Normalize(const nsACString & input, nsACString & output) { // protect against bogus input NS_ENSURE_TRUE(IsUTF8(input), NS_ERROR_UNEXPECTED); NS_ConvertUTF8toUTF16 inUTF16(input); normalizeFullStops(inUTF16); nsAutoString outUTF16; nsresult rv = stringPrep(inUTF16, outUTF16); if (NS_FAILED(rv)) return rv; CopyUTF16toUTF8(outUTF16, output); if (!isOnlySafeChars(outUTF16, mIDNBlacklist)) return ConvertUTF8toACE(output, output); return NS_OK; }
/* AUTF8String normalize(in AUTF8String input); */ NS_IMETHODIMP nsIDNService::Normalize(const nsACString & input, nsACString & output) { // protect against bogus input NS_ENSURE_TRUE(IsUTF8(input), NS_ERROR_UNEXPECTED); NS_ConvertUTF8toUTF16 inUTF16(input); normalizeFullStops(inUTF16); // pass the domain name to stringprep label by label nsAutoString outUTF16, outLabel; PRUint32 len = 0, offset = 0; nsresult rv; nsAString::const_iterator start, end; inUTF16.BeginReading(start); inUTF16.EndReading(end); while (start != end) { len++; if (*start++ == PRUnichar('.')) { rv = stringPrep(Substring(inUTF16, offset, len - 1), outLabel); NS_ENSURE_SUCCESS(rv, rv); outUTF16.Append(outLabel); outUTF16.Append(PRUnichar('.')); offset += len; len = 0; } } if (len) { rv = stringPrep(Substring(inUTF16, offset, len), outLabel); NS_ENSURE_SUCCESS(rv, rv); outUTF16.Append(outLabel); } CopyUTF16toUTF8(outUTF16, output); if (!isOnlySafeChars(outUTF16, mIDNBlacklist)) return ConvertUTF8toACE(output, output); return NS_OK; }