Bug 1746645 - Generate EscapeChars array programmatically. r=xpcom-reviewers,nika

Differential Revision: https://phabricator.services.mozilla.com/D136222
This commit is contained in:
Paul Zuehlcke 2022-01-19 10:21:05 +00:00
Родитель d6cedea199
Коммит 47129a9cd9
1 изменённых файлов: 64 добавлений и 23 удалений

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

@ -244,21 +244,63 @@ void nsAppendEscapedHTML(const nsACString& aSrc, nsACString& aDst) {
// The following table encodes which characters needs to be escaped for which
// parts of an URL. The bits are the "url components" in the enum EscapeMask,
// see nsEscape.h.
//
// esc_Scheme = 1
// esc_Username = 2
// esc_Password = 4
// esc_Host = 8
// esc_Directory = 16
// esc_FileBaseName = 32
// esc_FileExtension = 64
// esc_Param = 128
// esc_Query = 256
// esc_Ref = 512
// esc_ExtHandler = 131072
static const uint32_t EscapeChars[256] =
// clang-format off
template <size_t N>
static constexpr void AddUnescapedChars(const char (&aChars)[N],
uint32_t aFlags,
std::array<uint32_t, 256>& aTable) {
for (size_t i = 0; i < N - 1; ++i) {
aTable[static_cast<unsigned char>(aChars[i])] |= aFlags;
}
}
static constexpr std::array<uint32_t, 256> BuildEscapeChars() {
constexpr uint32_t kAllModes = esc_Scheme | esc_Username | esc_Password |
esc_Host | esc_Directory | esc_FileBaseName |
esc_FileExtension | esc_Param | esc_Query |
esc_Ref | esc_ExtHandler;
std::array<uint32_t, 256> table{0};
// Alphanumerics shouldn't be escaped in all escape modes.
AddUnescapedChars("0123456789", kAllModes, table);
AddUnescapedChars("ABCDEFGHIJKLMNOPQRSTUVWXYZ", kAllModes, table);
AddUnescapedChars("abcdefghijklmnopqrstuvwxyz", kAllModes, table);
AddUnescapedChars("!$&()*+,-_~", kAllModes, table);
// Extra characters which aren't escaped in particular escape modes.
AddUnescapedChars(".", esc_Scheme, table);
// esc_Username has no additional unescaped characters.
AddUnescapedChars("|", esc_Password, table);
AddUnescapedChars(".", esc_Host, table);
AddUnescapedChars("'./:;=@[]|", esc_Directory, table);
AddUnescapedChars("'.:;=@[]|", esc_FileBaseName, table);
AddUnescapedChars("':;=@[]|", esc_FileExtension, table);
AddUnescapedChars(".:;=@[\\]^`{|}", esc_Param, table);
AddUnescapedChars("./:;=?@[\\]^`{|}", esc_Query, table);
AddUnescapedChars("#'./:;=?@[\\]^{|}", esc_Ref, table);
AddUnescapedChars("#'./:;=?@[]", esc_ExtHandler, table);
return table;
}
static constexpr std::array<uint32_t, 256> EscapeChars = BuildEscapeChars();
static bool dontNeedEscape(unsigned char aChar, uint32_t aFlags) {
return EscapeChars[(size_t)aChar] & aFlags;
}
static bool dontNeedEscape(uint16_t aChar, uint32_t aFlags) {
return aChar < EscapeChars.size() ? (EscapeChars[(size_t)aChar] & aFlags)
: false;
}
// Temporary static assert to make sure that the rewrite to using
// `BuildEscapeChars` didn't change the final array in memory.
// It will be removed in Bug 1750945.
static_assert([]() constexpr {
constexpr uint32_t OldEscapeChars[256] =
// clang-format off
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
@ -271,16 +313,15 @@ static const uint32_t EscapeChars[256] =
132095,132095,132095,132095,132095,132095,132095,132095,132095,132095,132095, 896, 1012, 896,132095, 0, // 7x pqrstuvwxyz{|}~ DEL
0 // 80 to FF are zero
};
// clang-format on
// clang-format on
static bool dontNeedEscape(unsigned char aChar, uint32_t aFlags) {
return EscapeChars[(uint32_t)aChar] & aFlags;
}
static bool dontNeedEscape(uint16_t aChar, uint32_t aFlags) {
return aChar < mozilla::ArrayLength(EscapeChars)
? (EscapeChars[(uint32_t)aChar] & aFlags)
: false;
}
for (size_t i = 0; i < EscapeChars.size(); ++i) {
if (OldEscapeChars[i] != EscapeChars[i]) {
return false;
}
}
return true;
}());
//----------------------------------------------------------------------------------------