OSSCA Chromium

기여 목록 / 8468010

[Blink] Ignore <head> start tags in "in head noscript" insertion mode

BlinkfixMerged

HTML 스펙에 따르면 in head noscript insertion mode에서는 head와 noscript 시작 태그를 무시해야 합니다. 기존에는 이 모드에서 head 시작 태그를 만나면 잘못해서 in head 모드로 전환했습니다. head 시작 태그를 무시하도록 수정했습니다.

변경은 기본 활성화된 runtime flag로 제어하며, 필요하면 flag를 비활성화해 기존 동작으로 되돌릴 수 있습니다.

문제 설명

scripting이 비활성화된 상태에서 <head><noscript><head><style></style>을 파싱하면, 중첩된 <head> 때문에 in head noscript 모드를 벗어나 이후 <style>이 <noscript>의 자식으로 생성되지 않았습니다. 이로 인해 inhead-noscript-head.html WPT가 실패했습니다.

해결 내용

  • HTMLTreeBuilder::ProcessStartTag()의 kInHeadNoscriptMode 처리에 HTMLTag::kHead 분기를 추가했습니다.
  • 해당 시작 태그를 parse error로 처리하고 반환해, insertion mode를 유지한 채 태그를 무시하도록 했습니다.
  • HTMLParserIgnoreHeadInNoscript를 stable 상태의 runtime flag로 추가했습니다. flag가 꺼져 있으면 기존 처리 경로를 따릅니다.
  • 해당 WPT의 실패 기대 결과 파일을 제거했습니다.

전체 코드 diff는 다음과 같습니다.

diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
index 9ef1fd9..e7c4768 100644
--- a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
+++ b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
@@ -1628,6 +1628,12 @@
           DCHECK(did_process);
           return;
         }
+        case HTMLTag::kHead:
+          if (!RuntimeEnabledFeatures::
+                  HTMLParserIgnoreHeadInNoscriptEnabled()) {
+            break;
+          }
+          [[fallthrough]];
         case HTMLTag::kNoscript:
           ParseError(token);
           return;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index aadf02124..4a2c1de 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -3654,6 +3654,12 @@
       status: "stable",
     },
     {
+      // Kill switch for ignoring head start tags in the "in head noscript"
+      // insertion mode. https://crbug.com/40775952
+      name: "HTMLParserIgnoreHeadInNoscript",
+      status: "stable",
+    },
+    {
       // Killswitch for crbug.com/40727112: emit a bogus comment for an
       // incomplete markup declaration at end of input instead of dropping the
       // rest of the document.
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/inhead-noscript-head-expected.txt b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/inhead-noscript-head-expected.txt
deleted file mode 100644
index 9b05679a..0000000
--- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/inhead-noscript-head-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] When the scripting flag is disabled, a head start tag in "in head noscript" mode should be ignored
-  assert_equals: expected "[object HTMLStyleElement]" but got "null"
-Harness: the test ran to completion.
-

테스트 방법

CL에 기록한 검증 대상은 다음 WPT입니다.

  • external/wpt/html/syntax/parsing/inhead-noscript-head.html

이 테스트는 scripting이 비활성화된 iframe에서 중첩된 <head>를 파싱한 뒤, <noscript>의 첫 자식이 HTMLStyleElement인지 확인합니다.

CQ를 통해 2026년 10월 1일(한국 시간) Chromium main에 병합되었습니다.

배운 점

  • HTML parser는 잘못된 태그를 만났을 때도 스펙에 정해진 오류 처리와 insertion mode를 따라야 이후 DOM을 올바르게 구성할 수 있습니다.
  • 기본 활성화된 runtime flag를 두면, 문제가 발견됐을 때 flag를 비활성화해 기존 파싱 동작으로 되돌릴 수 있습니다.

참고 자료