Bug 1890277: part 4) Add CSPParser support for the `trusted-types` directive, guarded...
[gecko.git] / netwerk / dns / IDNBlocklistUtils.cpp
blob92c73d09976cb27a8ad122b58f028a1d060d6ac9
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "IDNBlocklistUtils.h"
7 #include "mozilla/Preferences.h"
8 #include "nsStringFwd.h"
10 namespace mozilla {
11 namespace net {
13 static constexpr char16_t sBlocklistPairs[][2] = {
14 #include "IDNCharacterBlocklist.inc"
17 void RemoveCharFromBlocklist(char16_t aChar,
18 nsTArray<BlocklistRange>& aBlocklist) {
19 auto pos = aBlocklist.BinaryIndexOf(aChar, BlocklistPairToCharComparator());
20 if (pos == nsTArray<BlocklistRange>::NoIndex) {
21 return;
24 auto& pair = aBlocklist[pos];
26 // If the matched range has a length of one, we can just remove it
27 if (pair.second == pair.first) {
28 aBlocklist.RemoveElementAt(pos);
29 return;
32 // If the character matches the first element in the range, just update
33 // the range.
34 if (aChar == pair.first) {
35 pair.first = pair.first + 1;
36 return;
39 // Also if it matches the last character in the range, we just update it.
40 if (aChar == pair.second) {
41 pair.second = pair.second - 1;
42 return;
45 // Our character is in the middle of the range, splitting it in two.
46 // We update the matched range to reflect the values before the character,
47 // and insert a new range that represents the values after.
48 char16_t lastElement = pair.second;
49 pair.second = aChar - 1;
50 aBlocklist.InsertElementAt(pos + 1,
51 std::make_pair(char16_t(aChar + 1), lastElement));
54 void InitializeBlocklist(nsTArray<BlocklistRange>& aBlocklist) {
55 aBlocklist.Clear();
56 for (auto const& arr : sBlocklistPairs) {
57 // The hardcoded pairs are already sorted.
58 aBlocklist.AppendElement(std::make_pair(arr[0], arr[1]));
61 nsAutoString extraAllowed;
62 nsresult rv =
63 Preferences::GetString("network.IDN.extra_allowed_chars", extraAllowed);
64 if (NS_SUCCEEDED(rv) && !extraAllowed.IsEmpty()) {
65 const char16_t* cur = extraAllowed.BeginReading();
66 const char16_t* end = extraAllowed.EndReading();
67 // Characters in the allowed list are removed from the blocklist.
68 for (; cur < end; ++cur) {
69 RemoveCharFromBlocklist(*cur, aBlocklist);
73 nsAutoString extraBlocked;
74 rv = Preferences::GetString("network.IDN.extra_blocked_chars", extraBlocked);
75 // We add each extra blocked character to the blocklist as a separate range.
76 if (NS_SUCCEEDED(rv) && !extraBlocked.IsEmpty()) {
77 for (size_t i = 0; i < extraBlocked.Length(); ++i) {
78 aBlocklist.AppendElement(
79 std::make_pair(extraBlocked[i], extraBlocked[i]));
81 aBlocklist.Sort(BlocklistEntryComparator());
85 } // namespace net
86 } // namespace mozilla