Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,624 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
grammar fuzzer_regexp_grammar;
////////////////////////////////////////////////////////////////////////////////
// Non RegExp specific rules
////////////////////////////////////////////////////////////////////////////////
SourceCharacter
: .
;
IdentifierStartChar
// \p{ID_Start} is not supported by RE2. We overapproximate.
: [\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}]
| '$'
| '_'
;
IdentifierPartChar
// \p{ID_Continue} is not supported by RE2. We overapproximate.
: [\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}]
| '$'
| [\x{200C}\x{200D}]
;
AsciiLetter
: [a-zA-Z]
;
NumericLiteralSeparator
: '_'
;
DecimalDigits
: DecimalDigit+ (NumericLiteralSeparator ? DecimalDigit+)*
;
DecimalDigit
: [0-9]
;
NonZeroDigit
: [1-9]
;
HexDigit
: [0-9a-fA-F]
;
HexDigits
: (HexDigit (NumericLiteralSeparator HexDigit) ? ) +
;
CodePoint
: HexDigits
;
HexEscapeSequence
: 'u' Hex4Digits
| 'u{' CodePoint '}'
;
Hex4Digits
: HexDigit HexDigit HexDigit HexDigit
;
////////////////////////////////////////////////////////////////////////////////
// Regular Expression Grammar
////////////////////////////////////////////////////////////////////////////////
// Pattern[UnicodeMode, UnicodeSetsMode, N] ::
// Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N]
pattern
: Disjunction
;
// Disjunction[UnicodeMode, UnicodeSetsMode, N] ::
// Alternative[?UnicodeMode, ?UnicodeSetsMode, ?N]
// Alternative[?UnicodeMode, ?UnicodeSetsMode, ?N] | Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N]
Disjunction
: Alternative+
;
// Alternative[UnicodeMode, UnicodeSetsMode, N] ::
// [empty]
// Alternative[?UnicodeMode, ?UnicodeSetsMode, ?N] Term[?UnicodeMode, ?UnicodeSetsMode, ?N]
Alternative
: Term+
;
// Term[UnicodeMode, UnicodeSetsMode, N] ::
// Assertion[?UnicodeMode, ?UnicodeSetsMode, ?N]
// Atom[?UnicodeMode, ?UnicodeSetsMode, ?N]
// Atom[?UnicodeMode, ?UnicodeSetsMode, ?N] Quantifier
Term
: Assertion
| Atom Quantifier ?
;
// Assertion[UnicodeMode, UnicodeSetsMode, N] ::
// ^
// $
// \b
// \B
// (?= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N] )
// (?! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N] )
// (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N] )
// (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N] )
Assertion
: [^$]
| [\\] 'b'
| [\\] 'B'
| '(?=' Disjunction ')'
| '(?!' Disjunction ')'
| '(?<=' Disjunction ')'
| '(?<!' Disjunction ')'
;
// Quantifier ::
// QuantifierPrefix
// QuantifierPrefix ?
Quantifier
: QuantifierPrefix '?' ?
;
// QuantifierPrefix ::
// *
// +
// ?
// { DecimalDigits[~Sep] }
// { DecimalDigits[~Sep] ,}
// { DecimalDigits[~Sep] , DecimalDigits[~Sep] }
QuantifierPrefix
: [*+?]
| '{' DecimalDigits ',' ? DecimalDigits ? '}'
;
// Atom[UnicodeMode, UnicodeSetsMode, N] ::
// PatternCharacter
// .
// \ AtomEscape[?UnicodeMode, ?N]
// CharacterClass[?UnicodeMode, ?UnicodeSetsMode]
// ( GroupSpecifier[?UnicodeMode]opt Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N] )
// (?: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?N] )
Atom
: PatternCharacter
| '.'
| [\\] AtomEscape
| CharacterClass
| '(' GroupSpecifier ? Disjunction ')'
| '(?:' Disjunction ')'
;
// SyntaxCharacter :: one of
// ^ $ \ . * + ? ( ) [ ] { } |
SyntaxCharacter
: [^$\\.*+?()[\]{}|]
;
// PatternCharacter ::
// SourceCharacter but not SyntaxCharacter
PatternCharacter
: SourceCharacter
;
// AtomEscape[UnicodeMode, N] ::
// DecimalEscape
// CharacterClassEscape[?UnicodeMode]
// CharacterEscape[?UnicodeMode]
// [+N] k GroupName[?UnicodeMode]
AtomEscape
: DecimalEscape
| CharacterClassEscape
| CharacterEscape
| 'k' GroupName
;
// CharacterEscape[UnicodeMode] ::
// ControlEscape
// c AsciiLetter
// 0 [lookahead ∉ DecimalDigit]
// HexEscapeSequence
// RegExpUnicodeEscapeSequence[?UnicodeMode]
// IdentityEscape[?UnicodeMode]
CharacterEscape
: ControlEscape
| 'c' AsciiLetter
| '0'
| HexEscapeSequence
| RegExpUnicodeEscapeSequence
| IdentityEscape
;
// ControlEscape :: one of
// f n r t v
ControlEscape
: [fnrtv]
;
// GroupSpecifier[UnicodeMode] ::
// ? GroupName[?UnicodeMode]
GroupSpecifier
: '?' GroupName
;
// GroupName[UnicodeMode] ::
// < RegExpIdentifierName[?UnicodeMode] >
GroupName
: '<' RegExpIdentifierName '>'
;
// RegExpIdentifierName[UnicodeMode] ::
// RegExpIdentifierStart[?UnicodeMode]
// RegExpIdentifierName[?UnicodeMode] RegExpIdentifierPart[?UnicodeMode]
RegExpIdentifierName
: RegExpIdentifierStart RegExpIdentifierPart +
;
// RegExpIdentifierStart[UnicodeMode] ::
// IdentifierStartChar
// \ RegExpUnicodeEscapeSequence[+UnicodeMode]
// [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate
RegExpIdentifierStart
: IdentifierStartChar
| [\\] RegExpUnicodeEscapeSequence
| UnicodeLeadSurrogate UnicodeTrailSurrogate
;
// RegExpIdentifierPart[UnicodeMode] ::
// IdentifierPartChar
// \ RegExpUnicodeEscapeSequence[+UnicodeMode]
// [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate
RegExpIdentifierPart
: IdentifierPartChar
| [\\] RegExpUnicodeEscapeSequence
| UnicodeLeadSurrogate UnicodeTrailSurrogate
;
// RegExpUnicodeEscapeSequence[UnicodeMode] ::
// [+UnicodeMode] u HexLeadSurrogate \u HexTrailSurrogate
// [+UnicodeMode] u HexLeadSurrogate
// [+UnicodeMode] u HexTrailSurrogate
// [+UnicodeMode] u HexNonSurrogate
// [~UnicodeMode] u Hex4Digits
// [+UnicodeMode] u{ CodePoint }
RegExpUnicodeEscapeSequence
: 'u' HexLeadSurrogate '\\u' HexTrailSurrogate
| 'u' HexLeadSurrogate
| 'u' HexTrailSurrogate
| 'u' HexNonSurrogate
| 'u' Hex4Digits
| 'u{' CodePoint '}'
;
// UnicodeLeadSurrogate ::
// any Unicode code point in the inclusive interval from U+D800 to U+DBFF
UnicodeLeadSurrogate
: [\x{D800}-\x{DBFF}]
;
// UnicodeTrailSurrogate ::
// any Unicode code point in the inclusive interval from U+DC00 to U+DFFF
UnicodeTrailSurrogate
: [\x{DC00}-\x{DFFF}]
;
// HexLeadSurrogate ::
// Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to 0xDBFF
HexLeadSurrogate
: Hex4Digits
;
// HexTrailSurrogate ::
// Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xDC00 to 0xDFFF
HexTrailSurrogate
: Hex4Digits
;
// HexNonSurrogate ::
// Hex4Digits but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to 0xDFFF
HexNonSurrogate
: Hex4Digits
;
// IdentityEscape[UnicodeMode] ::
// [+UnicodeMode] SyntaxCharacter
// [+UnicodeMode] /
// [~UnicodeMode] SourceCharacter but not UnicodeIDContinue
IdentityEscape
: SyntaxCharacter
| '/'
| SourceCharacter
;
// DecimalEscape ::
// NonZeroDigit DecimalDigits[~Sep]opt [lookahead ∉ DecimalDigit]
DecimalEscape
: NonZeroDigit DecimalDigits ?
;
// CharacterClassEscape[UnicodeMode] ::
// d
// D
// s
// S
// w
// W
// [+UnicodeMode] p{ UnicodePropertyValueExpression }
// [+UnicodeMode] P{ UnicodePropertyValueExpression }
CharacterClassEscape
: [dDsSwW]
| [pP] '{' UnicodePropertyValueExpression '}'
;
// UnicodePropertyValueExpression ::
// UnicodePropertyName = UnicodePropertyValue
// LoneUnicodePropertyNameOrValue
UnicodePropertyValueExpression
: UnicodePropertyName '=' UnicodePropertyValue
| LoneUnicodePropertyNameOrValue
;
// UnicodePropertyName ::
// UnicodePropertyNameCharacters
UnicodePropertyName
: UnicodePropertyNameCharacters
;
// UnicodePropertyNameCharacters ::
// UnicodePropertyNameCharacter UnicodePropertyNameCharactersopt
UnicodePropertyNameCharacters
: UnicodePropertyNameCharacter+
;
// UnicodePropertyValue ::
// UnicodePropertyValueCharacters
UnicodePropertyValue
: UnicodePropertyValueCharacters
;
// LoneUnicodePropertyNameOrValue ::
// UnicodePropertyValueCharacters
LoneUnicodePropertyNameOrValue
: UnicodePropertyValueCharacters
;
// UnicodePropertyValueCharacters ::
// UnicodePropertyValueCharacter UnicodePropertyValueCharactersopt
UnicodePropertyValueCharacters
: UnicodePropertyValueCharacter+
;
// UnicodePropertyValueCharacter ::
// UnicodePropertyNameCharacter
// DecimalDigit
UnicodePropertyValueCharacter
: UnicodePropertyNameCharacter
| DecimalDigit
;
// UnicodePropertyNameCharacter ::
// AsciiLetter
// _
UnicodePropertyNameCharacter
: AsciiLetter
| '-'
;
// CharacterClass[UnicodeMode, UnicodeSetsMode] ::
// [ [lookahead ≠ ^] ClassContents[?UnicodeMode, ?UnicodeSetsMode] ]
// [^ ClassContents[?UnicodeMode, ?UnicodeSetsMode] ]
CharacterClass
: '[' '^' ? ClassContents ']'
;
// ClassContents[UnicodeMode, UnicodeSetsMode] ::
// [empty]
// [~UnicodeSetsMode] NonemptyClassRanges[?UnicodeMode]
// [+UnicodeSetsMode] ClassSetExpression
ClassContents
: NonemptyClassRanges ?
| ClassSetExpression ?
;
// NonemptyClassRanges[UnicodeMode] ::
// ClassAtom[?UnicodeMode]
// ClassAtom[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode]
// ClassAtom[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode]
NonemptyClassRanges
: ClassAtom
| ClassAtom NonemptyClassRangesNoDash
| ClassAtom '-' ClassAtom ClassContents
;
// NonemptyClassRangesNoDash[UnicodeMode] ::
// ClassAtom[?UnicodeMode]
// ClassAtomNoDash[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode]
// ClassAtomNoDash[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode]
NonemptyClassRangesNoDash
: ClassAtom
| ClassAtomNoDash NonemptyClassRangesNoDash
| ClassAtomNoDash '-' ClassAtom ClassContents
;
// ClassAtom[UnicodeMode] ::
// -
// ClassAtomNoDash[?UnicodeMode]
ClassAtom
: '-'
| ClassAtomNoDash
;
// ClassAtomNoDash[UnicodeMode] ::
// SourceCharacter but not one of \ or ] or -
// \ ClassEscape[?UnicodeMode]
ClassAtomNoDash
// We can't model 'none of...' easily. So just overapproximate.
: SourceCharacter
| [\\] ClassEscape
;
// ClassEscape[UnicodeMode] ::
// b
// [+UnicodeMode] -
// CharacterClassEscape[?UnicodeMode]
// CharacterEscape[?UnicodeMode]
ClassEscape
: 'b'
| '-'
| CharacterClassEscape
| CharacterEscape
;
// ClassSetExpression ::
// ClassUnion
// ClassIntersection
// ClassSubtraction
ClassSetExpression
: ClassUnion
| ClassIntersection
| ClassSubtraction
;
// ClassUnion ::
// ClassSetRange ClassUnionopt
// ClassSetOperand ClassUnionopt
ClassUnion
: ClassSetRange ClassUnion ?
| ClassSetOperand ClassUnion ?
;
// ClassIntersection ::
// ClassSetOperand && [lookahead ≠ &] ClassSetOperand
// ClassIntersection && [lookahead ≠ &] ClassSetOperand
ClassIntersection
: ClassSetOperand ('&&' ClassSetOperand) +
;
// ClassSubtraction ::
// ClassSetOperand -- ClassSetOperand
// ClassSubtraction -- ClassSetOperand
ClassSubtraction
: ClassSetOperand ('--' ClassSetOperand) +
;
// ClassSetRange ::
// ClassSetCharacter - ClassSetCharacter
ClassSetRange
: ClassSetCharacter '-' ClassSetCharacter
;
// ClassSetOperand ::
// NestedClass
// ClassStringDisjunction
// ClassSetCharacter
ClassSetOperand
: NestedClass
| ClassStringDisjunction
| ClassSetCharacter
;
// NestedClass ::
// [ [lookahead ≠ ^] ClassContents[+UnicodeMode, +UnicodeSetsMode] ]
// [^ ClassContents[+UnicodeMode, +UnicodeSetsMode] ]
// \ CharacterClassEscape[+UnicodeMode]
NestedClass
: '[' '^' ? ClassContents ']'
| [\\] CharacterClassEscape
;
// ClassStringDisjunction ::
// \q{ ClassStringDisjunctionContents }
ClassStringDisjunction
: [\\] 'q{' ClassStringDisjunctionContents '}'
;
// ClassStringDisjunctionContents ::
// ClassString
// ClassString | ClassStringDisjunctionContents
ClassStringDisjunctionContents
: ClassString+
;
// ClassString ::
// [empty]
// NonEmptyClassString
ClassString
: NonEmptyClassString
// |
;
// NonEmptyClassString ::
// ClassSetCharacter NonEmptyClassStringopt
NonEmptyClassString
: ClassSetCharacter NonEmptyClassString ?
;
// ClassSetCharacter ::
// [lookahead ∉ ClassSetReservedDoublePunctuator] SourceCharacter but not ClassSetSyntaxCharacter
// \ CharacterEscape[+UnicodeMode]
// \ ClassSetReservedPunctuator
// \b
ClassSetCharacter
: SourceCharacter
| [\\] CharacterEscape
| [\\] ClassSetReservedPunctuator
| [\\] 'b'
;
// ClassSetReservedDoublePunctuator :: one of
// && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~
ClassSetReservedDoublePunctuator
: '&&'
| '!!'
| '##'
| '$$'
| '%%'
| '**'
| '++'
| ',,'
| '..'
| '::'
| ';;'
| '<<'
| '=='
| '>>'
| '??'
| '@@'
| '^^'
| '``'
| '~~'
;
// ClassSetSyntaxCharacter :: one of
// ( ) [ ] { } / - \ |
ClassSetSyntaxCharacter
: [()[\]{}/\\|-]
;
// ClassSetReservedPunctuator :: one of
// & - ! # % , : ; < = > @ ` ~
ClassSetReservedPunctuator
: [&!#%,:;<=>@`~-]
;

View File

@ -0,0 +1,179 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/regexp/regexp.h"
#include "test/unittests/fuzztest.h"
#include "test/unittests/regexp/regexp-grammar.h"
#include "test/unittests/test-utils.h"
namespace v8 {
namespace {
using RegExpFlag = internal::RegExpFlag;
template <class T>
class RegExpTest : public fuzztest::PerFuzzTestFixtureAdapter<TestWithContext> {
public:
RegExpTest()
: context_(context()),
isolate_(isolate()),
i_isolate_(reinterpret_cast<i::Isolate*>(isolate_)),
factory_(i_isolate_->factory()) {
internal::v8_flags.expose_gc = true;
}
~RegExpTest() override = default;
void RunRegExp(const std::string&, const i::RegExpFlags&,
const std::vector<T>&);
protected:
virtual i::Handle<i::String> CreateString(v8::base::Vector<const T>) = 0;
void Test(i::DirectHandle<i::JSRegExp>, i::DirectHandle<i::String>);
Local<Context> context_;
Isolate* isolate_;
i::Isolate* i_isolate_;
i::Factory* factory_;
};
// Domain over all combinations of regexp flags.
static fuzztest::Domain<i::RegExpFlags> ArbitraryFlags() {
// The unicode and unicode_sets bits are incompatible.
auto bits_supporting_unicode = fuzztest::BitFlagCombinationOf(
{RegExpFlag::kHasIndices, RegExpFlag::kGlobal, RegExpFlag::kIgnoreCase,
RegExpFlag::kMultiline, RegExpFlag::kSticky, RegExpFlag::kUnicode,
RegExpFlag::kDotAll});
auto bits_supporting_unicode_sets = fuzztest::BitFlagCombinationOf(
{RegExpFlag::kHasIndices, RegExpFlag::kGlobal, RegExpFlag::kIgnoreCase,
RegExpFlag::kMultiline, RegExpFlag::kSticky, RegExpFlag::kUnicodeSets,
RegExpFlag::kDotAll});
auto bits =
fuzztest::OneOf(bits_supporting_unicode, bits_supporting_unicode_sets);
auto flags = fuzztest::Map(
[](auto bits) { return static_cast<i::RegExpFlags>(bits); }, bits);
// Filter out any other incompatibilities.
return fuzztest::Filter(
[](i::RegExpFlags f) { return i::RegExp::VerifyFlags(f); }, flags);
}
// Domain over bytes for a test string to test regular expressions on.
// The resulting strings will consist of a fixed example, simple strings
// of just a, b and space, strings with printable ascii characters and
// strings with arbitrary characters.
template <typename T>
static fuzztest::Domain<std::vector<T>> ArbitraryBytes(
const std::vector<T>& example) {
auto signed_to_unsigned = [](const char& cr) { return static_cast<T>(cr); };
auto just_example = fuzztest::Just(example);
auto simple_char = fuzztest::Map(
signed_to_unsigned,
fuzztest::OneOf(fuzztest::InRange('a', 'b'), fuzztest::Just(' ')));
auto simple_chars =
fuzztest::ContainerOf<std::vector<T>>(simple_char).WithMaxSize(10);
auto printable_char =
fuzztest::Map(signed_to_unsigned, fuzztest::PrintableAsciiChar());
auto printable_chars =
fuzztest::ContainerOf<std::vector<T>>(printable_char).WithMaxSize(10);
auto arbitrary_chars =
fuzztest::ContainerOf<std::vector<T>>(fuzztest::Arbitrary<T>())
.WithMaxSize(10);
return fuzztest::OneOf(just_example, simple_chars, printable_chars,
arbitrary_chars);
}
static fuzztest::Domain<std::vector<uint8_t>> ArbitraryOneBytes() {
return ArbitraryBytes<uint8_t>(
std::vector<uint8_t>{'f', 'o', 'o', 'b', 'a', 'r'});
}
static fuzztest::Domain<std::vector<v8::base::uc16>> ArbitraryTwoBytes() {
return ArbitraryBytes<v8::base::uc16>(
std::vector<v8::base::uc16>{'f', 0xD83D, 0xDCA9, 'b', 'a', 0x2603});
}
template <class T>
void RegExpTest<T>::Test(i::DirectHandle<i::JSRegExp> regexp,
i::DirectHandle<i::String> subject) {
v8::TryCatch try_catch(isolate_);
// Exceptions will be swallowed by the try/catch above.
USE(i::RegExp::Exec_Single(i_isolate_, regexp, subject, 0,
i::RegExpMatchInfo::New(i_isolate_, 2)));
}
template <class T>
void RegExpTest<T>::RunRegExp(const std::string& regexp_input,
const i::RegExpFlags& flags,
const std::vector<T>& test_input) {
CHECK(!i_isolate_->has_exception());
if (regexp_input.size() > INT_MAX) return;
// Convert input string.
i::MaybeDirectHandle<i::String> maybe_source =
factory_->NewStringFromUtf8(v8::base::CStrVector(regexp_input.c_str()));
i::DirectHandle<i::String> source;
if (!maybe_source.ToHandle(&source)) {
i_isolate_->clear_exception();
return;
}
// Create regexp.
i::DirectHandle<i::JSRegExp> regexp;
{
CHECK(!i_isolate_->has_exception());
v8::TryCatch try_catch_inner(isolate_);
i::MaybeDirectHandle<i::JSRegExp> maybe_regexp = i::JSRegExp::New(
i_isolate_, source, i::JSRegExp::AsJSRegExpFlags(flags),
/*backtrack_limit*/ 1000000);
if (!maybe_regexp.ToHandle(&regexp)) {
i_isolate_->clear_exception();
return;
}
}
// Convert input bytes for the subject string.
auto subject = CreateString(
v8::base::Vector<const T>(test_input.data(), test_input.size()));
// Test the regexp on the subject, itself and an empty string.
Test(regexp, subject);
Test(regexp, source);
Test(regexp, factory_->empty_string());
isolate_->RequestGarbageCollectionForTesting(
v8::Isolate::kFullGarbageCollection);
CHECK(!i_isolate_->has_exception());
}
class RegExpOneByteTest : public RegExpTest<uint8_t> {
protected:
i::Handle<i::String> CreateString(
v8::base::Vector<const uint8_t> test_input) {
return factory_->NewStringFromOneByte(test_input).ToHandleChecked();
}
};
V8_FUZZ_TEST_F(RegExpOneByteTest, RunRegExp)
.WithDomains(fuzztest::internal_no_adl::InPatternGrammar(),
ArbitraryFlags(), ArbitraryOneBytes());
class RegExpTwoByteTest : public RegExpTest<v8::base::uc16> {
protected:
i::Handle<i::String> CreateString(
v8::base::Vector<const v8::base::uc16> test_input) {
return factory_->NewStringFromTwoByte(test_input).ToHandleChecked();
}
};
V8_FUZZ_TEST_F(RegExpTwoByteTest, RunRegExp)
.WithDomains(fuzztest::internal_no_adl::InPatternGrammar(),
ArbitraryFlags(), ArbitraryTwoBytes());
} // namespace
} // namespace v8

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff