From 1a599ceb9835faa3d85525ce932fba6b89b60188 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 23 Jul 2025 10:51:23 +0100 Subject: [PATCH] LibWeb/CSS: Reject `@font-face` and margin rules that have a prelude I couldn't find any WPT coverage for this, so here's a homemade test. --- Libraries/LibWeb/CSS/Parser/RuleParsing.cpp | 21 +++++++++++++++++-- .../css/font-face-with-prelude-is-invalid.txt | 1 + .../margin-rule-with-prelude-is-invalid.txt | 2 ++ .../font-face-with-prelude-is-invalid.html | 10 +++++++++ .../margin-rule-with-prelude-is-invalid.html | 15 +++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/css/font-face-with-prelude-is-invalid.txt create mode 100644 Tests/LibWeb/Text/expected/css/margin-rule-with-prelude-is-invalid.txt create mode 100644 Tests/LibWeb/Text/input/css/font-face-with-prelude-is-invalid.html create mode 100644 Tests/LibWeb/Text/input/css/margin-rule-with-prelude-is-invalid.html diff --git a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp index 2812159f2ec..8a56ac35b9e 100644 --- a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp @@ -767,7 +767,16 @@ GC::Ptr Parser::convert_to_font_face_rule(AtRule const& rule) }); return nullptr; } - // FIXME: Prelude must be empty + + prelude_stream.discard_whitespace(); + if (prelude_stream.has_next_token()) { + ErrorReporter::the().report(CSS::Parser::InvalidRuleError { + .rule_name = "@font-face"_fly_string, + .prelude = prelude_stream.dump_string(), + .description = "Prelude is not allowed."_string, + }); + return {}; + } DescriptorList descriptors { AtRuleID::FontFace }; rule.for_each_as_declaration_list([&](auto& declaration) { @@ -834,7 +843,15 @@ GC::Ptr Parser::convert_to_margin_rule(AtRule const& rule) return nullptr; } - // FIXME: Reject if there's a prelude + prelude_stream.discard_whitespace(); + if (prelude_stream.has_next_token()) { + ErrorReporter::the().report(CSS::Parser::InvalidRuleError { + .rule_name = MUST(String::formatted("@{}", rule.name)), + .prelude = prelude_stream.dump_string(), + .description = "Prelude is not allowed."_string, + }); + return {}; + } // https://drafts.csswg.org/css-page-3/#syntax-page-selector // There are lots of these, but they're all in the format: diff --git a/Tests/LibWeb/Text/expected/css/font-face-with-prelude-is-invalid.txt b/Tests/LibWeb/Text/expected/css/font-face-with-prelude-is-invalid.txt new file mode 100644 index 00000000000..84a85adabd0 --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/font-face-with-prelude-is-invalid.txt @@ -0,0 +1 @@ +`@font-face foo {}` should be invalid: PASS diff --git a/Tests/LibWeb/Text/expected/css/margin-rule-with-prelude-is-invalid.txt b/Tests/LibWeb/Text/expected/css/margin-rule-with-prelude-is-invalid.txt new file mode 100644 index 00000000000..6866ef4b77d --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/margin-rule-with-prelude-is-invalid.txt @@ -0,0 +1,2 @@ +`@page {}` should be valid: PASS +`@top-left foo {}` in `@page` should be invalid: PASS diff --git a/Tests/LibWeb/Text/input/css/font-face-with-prelude-is-invalid.html b/Tests/LibWeb/Text/input/css/font-face-with-prelude-is-invalid.html new file mode 100644 index 00000000000..e9ca85091c6 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/font-face-with-prelude-is-invalid.html @@ -0,0 +1,10 @@ + + + + diff --git a/Tests/LibWeb/Text/input/css/margin-rule-with-prelude-is-invalid.html b/Tests/LibWeb/Text/input/css/margin-rule-with-prelude-is-invalid.html new file mode 100644 index 00000000000..18bd5a21bca --- /dev/null +++ b/Tests/LibWeb/Text/input/css/margin-rule-with-prelude-is-invalid.html @@ -0,0 +1,15 @@ + + + + +