Skip to content

Commit e3bc809

Browse files
committed
Further reduce use of memcmp()
https://bugs.webkit.org/show_bug.cgi?id=285060 Reviewed by Darin Adler. * Source/JavaScriptCore/API/JSValue.mm: (createStructHandlerMap): * Source/JavaScriptCore/builtins/BuiltinExecutables.cpp: (JSC::BuiltinExecutables::createExecutable): * Source/JavaScriptCore/fuzzilli/Fuzzilli.cpp: (Fuzzilli::initializeReprl): * Source/WebCore/html/parser/HTMLDocumentParserFastPath.cpp: (WebCore::HTMLFastPathParser::parseContainerElement): * Source/WebCore/html/parser/ParsingUtilities.h: (WebCore::skipLettersExactlyIgnoringASCIICase): (WebCore::skipCharactersExactly): * Source/WebCore/loader/appcache/ApplicationCacheManifestParser.cpp: (WebCore::parseApplicationCacheManifest): * Source/WebCore/svg/SVGPreserveAspectRatioValue.cpp: (WebCore::SVGPreserveAspectRatioValue::parseInternal): * Source/WebCore/svg/SVGTransformable.cpp: (WebCore::parseTransformTypeGeneric): * Source/WebCore/svg/SVGViewSpec.cpp: (WebCore::SVGViewSpec::parseViewSpec): * Source/WebCore/svg/SVGZoomAndPan.cpp: (WebCore::parseZoomAndPanGeneric): * Tools/TestWebKitAPI/Tests/IPC/ArgumentCoderTests.cpp: (TestWebKitAPI::TYPED_TEST_P): Canonical link: https://commits.webkit.org/288228@main
1 parent 2dd4425 commit e3bc809

24 files changed

Lines changed: 150 additions & 145 deletions

File tree

‎Source/JavaScriptCore/API/JSValue.mm‎

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#import <wtf/HashMap.h>
4747
#import <wtf/HashSet.h>
4848
#import <wtf/Lock.h>
49+
#import <wtf/StdLibExtras.h>
4950
#import <wtf/Vector.h>
5051
#import <wtf/text/WTFString.h>
5152
#import <wtf/text/StringHash.h>
@@ -1261,10 +1262,9 @@ - (JSValue *)initWithValue:(JSValueRef)value inContext:(JSContext *)context
12611262
// Step 1: find all valueWith<Foo>:inContext: class methods in JSValue.
12621263
forEachMethodInClass(object_getClass([JSValue class]), ^(Method method){
12631264
SEL selector = method_getName(method);
1264-
const char* name = sel_getName(selector);
1265-
size_t nameLength = strlen(name);
1265+
auto name = span(sel_getName(selector));
12661266
// Check for valueWith<Foo>:context:
1267-
if (nameLength < valueWithXinContextLength || memcmp(name, "valueWith", 9) || memcmp(name + nameLength - 11, ":inContext:", 11))
1267+
if (name.size() < valueWithXinContextLength || !spanHasPrefix(name, "valueWith"_span) || !spanHasSuffix(name, ":inContext:"_span))
12681268
return;
12691269
// Check for [ id, SEL, <type>, <contextType> ]
12701270
if (method_getNumberOfArguments(method) != 4)
@@ -1289,10 +1289,9 @@ - (JSValue *)initWithValue:(JSValueRef)value inContext:(JSContext *)context
12891289
// Step 2: find all to<Foo> instance methods in JSValue.
12901290
forEachMethodInClass([JSValue class], ^(Method method){
12911291
SEL selector = method_getName(method);
1292-
const char* name = sel_getName(selector);
1293-
size_t nameLength = strlen(name);
1292+
auto name = span(sel_getName(selector));
12941293
// Check for to<Foo>
1295-
if (nameLength < toXLength || memcmp(name, "to", 2))
1294+
if (name.size() < toXLength || !spanHasPrefix(name, "to"_span))
12961295
return;
12971296
// Check for [ id, SEL ]
12981297
if (method_getNumberOfArguments(method) != 2)
@@ -1305,12 +1304,12 @@ - (JSValue *)initWithValue:(JSValueRef)value inContext:(JSContext *)context
13051304
StructTagHandler& handler = iter->value;
13061305

13071306
// check that strlen(<foo>) == strlen(<Foo>)
1308-
const char* valueWithName = sel_getName(handler.typeToValueSEL);
1309-
size_t valueWithLength = strlen(valueWithName);
1310-
if (valueWithLength - valueWithXinContextLength != nameLength - toXLength)
1307+
auto valueWithName = span(sel_getName(handler.typeToValueSEL));
1308+
if (valueWithName.size() - valueWithXinContextLength != name.size() - toXLength)
13111309
return;
13121310
// Check that <Foo> == <Foo>
1313-
if (memcmp(valueWithName + 9, name + 2, nameLength - toXLength - 1))
1311+
auto lengthToCheck = name.size() - toXLength - 1;
1312+
if (!equalSpans(valueWithName.subspan(9, lengthToCheck), name.subspan(2, lengthToCheck)))
13141313
return;
13151314
handler.valueToTypeSEL = selector;
13161315
});

‎Source/JavaScriptCore/builtins/BuiltinExecutables.cpp‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "JSCJSValueInlines.h"
3232
#include "Parser.h"
3333
#include <wtf/NeverDestroyed.h>
34+
#include <wtf/StdLibExtras.h>
3435
#include <wtf/TZoneMallocInlines.h>
3536

3637
WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
@@ -93,11 +94,11 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const S
9394
RELEASE_ASSERT(!view.isNull());
9495
RELEASE_ASSERT(view.is8Bit());
9596
auto characters = view.span8();
96-
const char* regularFunctionBegin = "(function (";
97-
const char* asyncFunctionBegin = "(async function (";
97+
auto regularFunctionBegin = "(function ("_span;
98+
auto asyncFunctionBegin = "(async function ("_span;
9899
RELEASE_ASSERT(view.length() >= strlen("(function (){})"));
99-
bool isAsyncFunction = view.length() >= strlen("(async function (){})") && !memcmp(characters.data(), asyncFunctionBegin, strlen(asyncFunctionBegin));
100-
RELEASE_ASSERT(isAsyncFunction || !memcmp(characters.data(), regularFunctionBegin, strlen(regularFunctionBegin)));
100+
bool isAsyncFunction = view.length() >= strlen("(async function (){})") && spanHasPrefix(characters, asyncFunctionBegin);
101+
RELEASE_ASSERT(isAsyncFunction || spanHasPrefix(characters, regularFunctionBegin));
101102

102103
unsigned asyncOffset = isAsyncFunction ? strlen("async ") : 0;
103104
unsigned parametersStart = strlen("function (") + asyncOffset;
@@ -166,11 +167,11 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const S
166167
++endColumn;
167168

168169
if (!isInStrictContext && (characters[i] == '"' || characters[i] == '\'')) {
169-
const unsigned useStrictLength = strlen("use strict");
170-
if (i + 1 + useStrictLength < view.length()) {
171-
if (!memcmp(characters.data() + i + 1, "use strict", useStrictLength)) {
170+
const auto useStrict = "use strict"_span;
171+
if (i + 1 + useStrict.size() < view.length()) {
172+
if (spanHasPrefix(characters.subspan(i + 1), useStrict)) {
172173
isInStrictContext = true;
173-
i += 1 + useStrictLength;
174+
i += 1 + useStrict.size();
174175
}
175176
}
176177
}

‎Source/JavaScriptCore/fuzzilli/Fuzzilli.cpp‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <wtf/Compiler.h>
2727
#include <wtf/DataLog.h>
2828
#include <wtf/NeverDestroyed.h>
29+
#include <wtf/StdLibExtras.h>
2930

3031
#if ENABLE(FUZZILLI)
3132

@@ -133,12 +134,12 @@ void Fuzzilli::flushReprl(int32_t result)
133134

134135
void Fuzzilli::initializeReprl()
135136
{
136-
char helo[] = "HELO";
137+
std::array<char, 4> helo { 'H', 'E', 'L', 'O' };
137138

138-
WRITE_TO_FUZZILLI(helo, 4);
139-
READ_FROM_FUZZILLI(helo, 4);
139+
WRITE_TO_FUZZILLI(helo.data(), helo.size());
140+
READ_FROM_FUZZILLI(helo.data(), helo.size());
140141

141-
RELEASE_ASSERT_WITH_MESSAGE(!memcmp(helo, "HELO", 4), "[REPRL] Invalid response from parent");
142+
RELEASE_ASSERT_WITH_MESSAGE(equalSpans(helo, "HELO"_span), "[REPRL] Invalid response from parent");
142143

143144
// Mmap the data input buffer.
144145
reprlInputData = static_cast<char*>(mmap(0, REPRL_MAX_DATA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, REPRL_DRFD, 0));

‎Source/WTF/wtf/StdLibExtras.h‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,28 @@ bool equalSpans(std::span<T, TExtent> a, std::span<U, UExtent> b)
898898
return !memcmp(a.data(), b.data(), a.size_bytes());
899899
}
900900

901+
template<typename T, std::size_t TExtent, typename U, std::size_t UExtent>
902+
bool spanHasPrefix(std::span<T, TExtent> span, std::span<U, UExtent> prefix)
903+
{
904+
static_assert(sizeof(T) == sizeof(U));
905+
static_assert(std::has_unique_object_representations_v<T>);
906+
static_assert(std::has_unique_object_representations_v<U>);
907+
if (span.size() < prefix.size())
908+
return false;
909+
return !memcmp(span.data(), prefix.data(), prefix.size_bytes());
910+
}
911+
912+
template<typename T, std::size_t TExtent, typename U, std::size_t UExtent>
913+
bool spanHasSuffix(std::span<T, TExtent> span, std::span<U, UExtent> suffix)
914+
{
915+
static_assert(sizeof(T) == sizeof(U));
916+
static_assert(std::has_unique_object_representations_v<T>);
917+
static_assert(std::has_unique_object_representations_v<U>);
918+
if (span.size() < suffix.size())
919+
return false;
920+
return !memcmp(span.last(suffix.size()).data(), suffix.data(), suffix.size_bytes());
921+
}
922+
901923
template<typename T, std::size_t TExtent, typename U, std::size_t UExtent>
902924
int compareSpans(std::span<T, TExtent> a, std::span<U, UExtent> b)
903925
{
@@ -1247,6 +1269,8 @@ using WTF::safeCast;
12471269
using WTF::secureMemsetSpan;
12481270
using WTF::singleElementSpan;
12491271
using WTF::spanConstCast;
1272+
using WTF::spanHasPrefix;
1273+
using WTF::spanHasSuffix;
12501274
using WTF::spanReinterpretCast;
12511275
using WTF::toTwosComplement;
12521276
using WTF::tryBinarySearch;

‎Source/WTF/wtf/URLHelpers.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ static inline bool isSecondLevelDomainNameAllowedByTLDRules(std::span<const UCha
454454
#define CHECK_RULES_IF_SUFFIX_MATCHES(suffix, function) \
455455
{ \
456456
static constexpr size_t suffixLength = suffix.size(); \
457-
if (buffer.size() > suffixLength && equalSpans(buffer.last(suffixLength), std::span { suffix })) \
457+
if (spanHasSuffix(buffer, std::span { suffix })) \
458458
return isSecondLevelDomainNameAllowedByTLDRules(buffer.first(buffer.size() - suffixLength), function); \
459459
}
460460

‎Source/WebCore/crypto/cocoa/CryptoKeyECMac.cpp‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,13 @@ RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier id
302302
index += bytesUsedToEncodedLength(keyData[index]); // Read length
303303
if (keyData.size() < index + sizeof(IdEcPublicKey))
304304
return nullptr;
305-
if (!equalSpans(keyData.subspan(index, sizeof(IdEcPublicKey)), std::span { IdEcPublicKey }))
305+
if (!spanHasPrefix(keyData.subspan(index), std::span { IdEcPublicKey }))
306306
return nullptr;
307307
index += std::size(IdEcPublicKey); // Read id-ecPublicKey
308308
auto oid = getOID(curve);
309309
if (keyData.size() < index + oid.size())
310310
return nullptr;
311-
if (!equalSpans(keyData.subspan(index, oid.size()), oid))
311+
if (!spanHasPrefix(keyData.subspan(index), oid))
312312
return nullptr;
313313
index += oid.size() + 1; // Read named curve OID, BIT STRING
314314
if (keyData.size() < index + 1)
@@ -392,13 +392,13 @@ RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier i
392392
index += bytesUsedToEncodedLength(keyData[index]); // Read length
393393
if (keyData.size() < index + sizeof(IdEcPublicKey))
394394
return nullptr;
395-
if (!equalSpans(keyData.subspan(index, sizeof(IdEcPublicKey)), std::span { IdEcPublicKey }))
395+
if (!spanHasPrefix(keyData.subspan(index), std::span { IdEcPublicKey }))
396396
return nullptr;
397397
index += std::size(IdEcPublicKey); // Read id-ecPublicKey
398398
auto oid = getOID(curve);
399399
if (keyData.size() < index + oid.size())
400400
return nullptr;
401-
if (!equalSpans(keyData.subspan(index, oid.size()), oid))
401+
if (!spanHasPrefix(keyData.subspan(index), oid))
402402
return nullptr;
403403
index += oid.size() + 1; // Read named curve OID, OCTET STRING
404404
if (keyData.size() < index + 1)

‎Source/WebCore/css/parser/CSSPropertyParser.cpp‎

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,6 @@ bool isCustomPropertyName(StringView propertyName)
104104
return propertyName.length() > 2 && propertyName.characterAt(0) == '-' && propertyName.characterAt(1) == '-';
105105
}
106106

107-
static bool hasPrefix(std::span<const char> string, std::span<const LChar> prefix)
108-
{
109-
if (string.size() < prefix.size())
110-
return false;
111-
return equalSpans(string.first(prefix.size()), prefix);
112-
}
113-
114107
template<typename CharacterType> static CSSPropertyID cssPropertyID(std::span<const CharacterType> characters)
115108
{
116109
char buffer[maxCSSPropertyNameLength];
@@ -126,10 +119,10 @@ template<typename CharacterType> static CSSPropertyID cssPropertyID(std::span<co
126119
// FIXME: Remove this mechanism entirely once we can do it without breaking the web.
127120
static bool isAppleLegacyCSSValueKeyword(std::span<const char> characters)
128121
{
129-
return hasPrefix(characters.subspan(1), "apple-"_span)
130-
&& !hasPrefix(characters.subspan(7), "system"_span)
131-
&& !hasPrefix(characters.subspan(7), "pay"_span)
132-
&& !hasPrefix(characters.subspan(7), "wireless"_span);
122+
return spanHasPrefix(characters.subspan(1), "apple-"_span)
123+
&& !spanHasPrefix(characters.subspan(7), "system"_span)
124+
&& !spanHasPrefix(characters.subspan(7), "pay"_span)
125+
&& !spanHasPrefix(characters.subspan(7), "wireless"_span);
133126
}
134127

135128
template<typename CharacterType> static CSSValueID cssValueKeywordID(std::span<const CharacterType> characters)

‎Source/WebCore/html/parser/HTMLDocumentParserFastPath.cpp‎

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ class HTMLFastPathParser {
307307

308308
struct A : ContainerTag<HTMLAnchorElement, PermittedParents::FlowContent> {
309309
static constexpr ElementName tagName = ElementNames::HTML::a;
310-
static constexpr CharacterType tagNameCharacters[] = { 'a' };
310+
static constexpr std::array<CharacterType, 1> tagNameCharacters { 'a' };
311311

312312
static RefPtr<HTMLElement> parseChild(ContainerNode& parent, HTMLFastPathParser& self)
313313
{
@@ -321,7 +321,7 @@ class HTMLFastPathParser {
321321

322322
struct AWithPhrasingContent : ContainsPhrasingContentTag<HTMLAnchorElement, PermittedParents::PhrasingOrFlowContent> {
323323
static constexpr ElementName tagName = ElementNames::HTML::a;
324-
static constexpr CharacterType tagNameCharacters[] = { 'a' };
324+
static constexpr std::array<CharacterType, 1> tagNameCharacters { 'a' };
325325

326326
static RefPtr<HTMLElement> parseChild(ContainerNode& parent, HTMLFastPathParser& self)
327327
{
@@ -335,7 +335,7 @@ class HTMLFastPathParser {
335335

336336
struct B : ContainsPhrasingContentTag<HTMLElement, PermittedParents::PhrasingOrFlowContent> {
337337
static constexpr ElementName tagName = ElementNames::HTML::b;
338-
static constexpr CharacterType tagNameCharacters[] = { 'b' };
338+
static constexpr std::array<CharacterType, 1> tagNameCharacters { 'b' };
339339

340340
static Ref<HTMLElement> create(Document& document)
341341
{
@@ -345,27 +345,27 @@ class HTMLFastPathParser {
345345

346346
struct Br : VoidTag<HTMLBRElement, PermittedParents::PhrasingOrFlowContent> {
347347
static constexpr ElementName tagName = ElementNames::HTML::br;
348-
static constexpr CharacterType tagNameCharacters[] = { 'b', 'r' };
348+
static constexpr std::array<CharacterType, 2> tagNameCharacters { 'b', 'r' };
349349
};
350350

351351
struct Button : ContainsPhrasingContentTag<HTMLButtonElement, PermittedParents::PhrasingOrFlowContent> {
352352
static constexpr ElementName tagName = ElementNames::HTML::button;
353-
static constexpr CharacterType tagNameCharacters[] = { 'b', 'u', 't', 't', 'o', 'n' };
353+
static constexpr std::array<CharacterType, 6> tagNameCharacters { 'b', 'u', 't', 't', 'o', 'n' };
354354
};
355355

356356
struct Div : ContainerTag<HTMLDivElement, PermittedParents::FlowContent> {
357357
static constexpr ElementName tagName = ElementNames::HTML::div;
358-
static constexpr CharacterType tagNameCharacters[] = { 'd', 'i', 'v' };
358+
static constexpr std::array<CharacterType, 3> tagNameCharacters { 'd', 'i', 'v' };
359359
};
360360

361361
struct Body : ContainerTag<HTMLBodyElement, PermittedParents::Special> {
362362
static constexpr ElementName tagName = ElementNames::HTML::body;
363-
static constexpr CharacterType tagNameCharacters[] = { 'b', 'o', 'd', 'y' };
363+
static constexpr std::array<CharacterType, 4> tagNameCharacters { 'b', 'o', 'd', 'y' };
364364
};
365365

366366
struct Footer : ContainerTag<HTMLElement, PermittedParents::FlowContent> {
367367
static constexpr ElementName tagName = ElementNames::HTML::footer;
368-
static constexpr CharacterType tagNameCharacters[] = { 'f', 'o', 'o', 't', 'e', 'r' };
368+
static constexpr std::array<CharacterType, 6> tagNameCharacters { 'f', 'o', 'o', 't', 'e', 'r' };
369369

370370
static Ref<HTMLElement> create(Document& document)
371371
{
@@ -375,7 +375,7 @@ class HTMLFastPathParser {
375375

376376
struct I : ContainsPhrasingContentTag<HTMLElement, PermittedParents::PhrasingOrFlowContent> {
377377
static constexpr ElementName tagName = ElementNames::HTML::i;
378-
static constexpr CharacterType tagNameCharacters[] = { 'i' };
378+
static constexpr std::array<CharacterType, 1> tagNameCharacters { 'i' };
379379

380380
static Ref<HTMLElement> create(Document& document)
381381
{
@@ -385,7 +385,7 @@ class HTMLFastPathParser {
385385

386386
struct Input : VoidTag<HTMLInputElement, PermittedParents::PhrasingOrFlowContent> {
387387
static constexpr ElementName tagName = ElementNames::HTML::input;
388-
static constexpr CharacterType tagNameCharacters[] = { 'i', 'n', 'p', 'u', 't' };
388+
static constexpr std::array<CharacterType, 5> tagNameCharacters { 'i', 'n', 'p', 'u', 't' };
389389

390390
static Ref<HTMLInputElement> create(Document& document)
391391
{
@@ -395,17 +395,17 @@ class HTMLFastPathParser {
395395

396396
struct Li : ContainerTag<HTMLLIElement, PermittedParents::FlowContent> {
397397
static constexpr ElementName tagName = ElementNames::HTML::li;
398-
static constexpr CharacterType tagNameCharacters[] = { 'l', 'i' };
398+
static constexpr std::array<CharacterType, 2> tagNameCharacters { 'l', 'i' };
399399
};
400400

401401
struct Label : ContainsPhrasingContentTag<HTMLLabelElement, PermittedParents::PhrasingOrFlowContent> {
402402
static constexpr ElementName tagName = ElementNames::HTML::label;
403-
static constexpr CharacterType tagNameCharacters[] = { 'l', 'a', 'b', 'e', 'l' };
403+
static constexpr std::array<CharacterType, 5> tagNameCharacters { 'l', 'a', 'b', 'e', 'l' };
404404
};
405405

406406
struct Option : ContainerTag<HTMLOptionElement, PermittedParents::Special> {
407407
static constexpr ElementName tagName = ElementNames::HTML::option;
408-
static constexpr CharacterType tagNameCharacters[] = { 'o', 'p', 't', 'i', 'o', 'n' };
408+
static constexpr std::array<CharacterType, 6> tagNameCharacters { 'o', 'p', 't', 'i', 'o', 'n' };
409409

410410
static RefPtr<HTMLElement> parseChild(ContainerNode&, HTMLFastPathParser& self)
411411
{
@@ -416,7 +416,7 @@ class HTMLFastPathParser {
416416

417417
struct Ol : ContainerTag<HTMLOListElement, PermittedParents::FlowContent> {
418418
static constexpr ElementName tagName = ElementNames::HTML::ol;
419-
static constexpr CharacterType tagNameCharacters[] = { 'o', 'l' };
419+
static constexpr std::array<CharacterType, 2> tagNameCharacters { 'o', 'l' };
420420

421421
static RefPtr<HTMLElement> parseChild(ContainerNode& parent, HTMLFastPathParser& self)
422422
{
@@ -426,12 +426,12 @@ class HTMLFastPathParser {
426426

427427
struct P : ContainsPhrasingContentTag<HTMLParagraphElement, PermittedParents::FlowContent> {
428428
static constexpr ElementName tagName = ElementNames::HTML::p;
429-
static constexpr CharacterType tagNameCharacters[] = { 'p' };
429+
static constexpr std::array<CharacterType, 1> tagNameCharacters { 'p' };
430430
};
431431

432432
struct Select : ContainerTag<HTMLSelectElement, PermittedParents::PhrasingOrFlowContent> {
433433
static constexpr ElementName tagName = ElementNames::HTML::select;
434-
static constexpr CharacterType tagNameCharacters[] = { 's', 'e', 'l', 'e', 'c', 't' };
434+
static constexpr std::array<CharacterType, 6> tagNameCharacters { 's', 'e', 'l', 'e', 'c', 't' };
435435

436436
static RefPtr<HTMLElement> parseChild(ContainerNode& parent, HTMLFastPathParser& self)
437437
{
@@ -441,12 +441,12 @@ class HTMLFastPathParser {
441441

442442
struct Span : ContainsPhrasingContentTag<HTMLSpanElement, PermittedParents::PhrasingOrFlowContent> {
443443
static constexpr ElementName tagName = ElementNames::HTML::span;
444-
static constexpr CharacterType tagNameCharacters[] = { 's', 'p', 'a', 'n' };
444+
static constexpr std::array<CharacterType, 4> tagNameCharacters { 's', 'p', 'a', 'n' };
445445
};
446446

447447
struct Strong : ContainsPhrasingContentTag<HTMLElement, PermittedParents::PhrasingOrFlowContent> {
448448
static constexpr ElementName tagName = ElementNames::HTML::strong;
449-
static constexpr CharacterType tagNameCharacters[] = { 's', 't', 'r', 'o', 'n', 'g' };
449+
static constexpr std::array<CharacterType, 6> tagNameCharacters { 's', 't', 'r', 'o', 'n', 'g' };
450450

451451
static Ref<HTMLElement> create(Document& document)
452452
{
@@ -456,7 +456,7 @@ class HTMLFastPathParser {
456456

457457
struct Ul : ContainerTag<HTMLUListElement, PermittedParents::FlowContent> {
458458
static constexpr ElementName tagName = ElementNames::HTML::ul;
459-
static constexpr CharacterType tagNameCharacters[] = { 'u', 'l' };
459+
static constexpr std::array<CharacterType, 2> tagNameCharacters { 'u', 'l' };
460460

461461
static RefPtr<HTMLElement> parseChild(ContainerNode& parent, HTMLFastPathParser& self)
462462
{
@@ -930,8 +930,8 @@ class HTMLFastPathParser {
930930
ASSERT(*m_parsingBuffer == '/');
931931
m_parsingBuffer.advance();
932932

933-
if (UNLIKELY(!skipCharactersExactly(m_parsingBuffer, Tag::tagNameCharacters))) {
934-
if (UNLIKELY(!skipLettersExactlyIgnoringASCIICase(m_parsingBuffer, Tag::tagNameCharacters)))
933+
if (UNLIKELY(!skipCharactersExactly(m_parsingBuffer, std::span { Tag::tagNameCharacters }))) {
934+
if (UNLIKELY(!skipLettersExactlyIgnoringASCIICase(m_parsingBuffer, std::span { Tag::tagNameCharacters })))
935935
return didFail(HTMLFastPathResult::FailedEndTagNameMismatch, element);
936936
}
937937
skipWhile<isASCIIWhitespace>(m_parsingBuffer);

0 commit comments

Comments
 (0)