All string resources from UserAgentStyleSheets / UserAgentScripts should be used as non-copying StringImpl
https://bugs.webkit.org/show_bug.cgi?id=223685

Reviewed by Saam Barati.

Source/WebCore:

We use StringImpl::createWithoutCopying for string resources from UserAgentStyleSheets / UserAgentScripts to make sure that
these resources do not allocate heap strings.

This patch also fixes HTMLMeterElement's bug (and imageOverlayUserAgentStyleSheet's bug). Previously, we are using String::ConstructFromLiteral,
but this only accepts string literal as it says. As a result, we are dropping the last character since UserAgentStyleSheets's last character is not \0.

* Modules/plugins/QuickTimePluginReplacement.mm:
(WebCore::quickTimePluginReplacementScript):
* WebCoreMacros.cmake:
* dom/Document.cpp:
(WebCore::Document::ensurePlugInsInjectedScript):
* html/HTMLElement.cpp:
(WebCore::HTMLElement::updateWithImageExtractionResult):
* html/HTMLMeterElement.cpp:
(WebCore::HTMLMeterElement::didAddUserAgentShadowRoot):
* rendering/RenderThemeAdwaita.cpp:
(WebCore::RenderThemeAdwaita::extraDefaultStyleSheet):
(WebCore::RenderThemeAdwaita::extraMediaControlsStyleSheet):
(WebCore::RenderThemeAdwaita::mediaControlsScripts):
* rendering/RenderThemeCocoa.mm:
(WebCore::RenderThemeCocoa::mediaControlsStyleSheet):
(WebCore::RenderThemeCocoa::mediaControlsScripts):
* rendering/RenderThemeWin.cpp:
(WebCore::RenderThemeWin::extraDefaultStyleSheet):
(WebCore::RenderThemeWin::extraQuirksStyleSheet):
* style/UserAgentStyle.cpp:
(WebCore::Style::UserAgentStyle::initDefaultStyleSheet):
(WebCore::Style::UserAgentStyle::ensureDefaultStyleSheetsForElement):

Source/WebDriver:

* Session.cpp:
(WebDriver::Session::fullscreenWindow):
(WebDriver::Session::findElements):
(WebDriver::Session::isElementSelected):
(WebDriver::Session::isElementEnabled):
(WebDriver::Session::isElementDisplayed):
(WebDriver::Session::getElementAttribute):
(WebDriver::Session::elementClear):

Source/WTF:

Add StringImpl::createWithoutCopying for `const char*`.

* wtf/text/StringImpl.h:
(WTF::StringImpl::createWithoutCopying):

LayoutTests:

* fast/dom/HTMLMeterElement/meter-element-markup-expected.txt:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@274997 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index c3d36b9..551ec0a 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,12 @@
+2021-03-24  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        All string resources from UserAgentStyleSheets / UserAgentScripts should be used as non-copying StringImpl
+        https://bugs.webkit.org/show_bug.cgi?id=223685
+
+        Reviewed by Saam Barati.
+
+        * fast/dom/HTMLMeterElement/meter-element-markup-expected.txt:
+
 2021-03-24  Robert Jenner  <jenner@apple.com>
 
         [ macOS Wk2 ]inspector/indexeddb/clearObjectStore.html is a flakey timeout
diff --git a/LayoutTests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt b/LayoutTests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt
index 06dc0d8..633d950 100644
--- a/LayoutTests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt
+++ b/LayoutTests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt
@@ -6,7 +6,7 @@
 |   value="70"
 |   <shadow:root>
 |     <style>
-|       "div#inner { -webkit-appearance: inherit; box-sizing: inherit; height: 100%; width: 100%; } div#bar { background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd), color-stop(0.20, #eee), color-stop(0.45, #ccc), color-stop(0.55, #ccc)); height: 100%; width: 100%; box-sizing: border-box; } div#value { height: 100%; box-sizing: border-box; } div#value.optimum { background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3)); } div#value.suboptimum { background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3)); height: 100%; box-sizing: border-box; } div#value.even-less-good { background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44)); height: 100%; box-sizing: border-box; "
+|       "div#inner { -webkit-appearance: inherit; box-sizing: inherit; height: 100%; width: 100%; } div#bar { background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd), color-stop(0.20, #eee), color-stop(0.45, #ccc), color-stop(0.55, #ccc)); height: 100%; width: 100%; box-sizing: border-box; } div#value { height: 100%; box-sizing: border-box; } div#value.optimum { background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3)); } div#value.suboptimum { background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3)); height: 100%; box-sizing: border-box; } div#value.even-less-good { background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44)); height: 100%; box-sizing: border-box; }"
 |     <div>
 |       id="inner"
 |       pseudo="-webkit-meter-inner-element"
@@ -31,7 +31,7 @@
 |   value="10"
 |   <shadow:root>
 |     <style>
-|       "div#inner { -webkit-appearance: inherit; box-sizing: inherit; height: 100%; width: 100%; } div#bar { background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd), color-stop(0.20, #eee), color-stop(0.45, #ccc), color-stop(0.55, #ccc)); height: 100%; width: 100%; box-sizing: border-box; } div#value { height: 100%; box-sizing: border-box; } div#value.optimum { background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3)); } div#value.suboptimum { background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3)); height: 100%; box-sizing: border-box; } div#value.even-less-good { background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44)); height: 100%; box-sizing: border-box; "
+|       "div#inner { -webkit-appearance: inherit; box-sizing: inherit; height: 100%; width: 100%; } div#bar { background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd), color-stop(0.20, #eee), color-stop(0.45, #ccc), color-stop(0.55, #ccc)); height: 100%; width: 100%; box-sizing: border-box; } div#value { height: 100%; box-sizing: border-box; } div#value.optimum { background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3)); } div#value.suboptimum { background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3)); height: 100%; box-sizing: border-box; } div#value.even-less-good { background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44)); height: 100%; box-sizing: border-box; }"
 |     <div>
 |       id="inner"
 |       pseudo="-webkit-meter-inner-element"
@@ -56,7 +56,7 @@
 |   value="10"
 |   <shadow:root>
 |     <style>
-|       "div#inner { -webkit-appearance: inherit; box-sizing: inherit; height: 100%; width: 100%; } div#bar { background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd), color-stop(0.20, #eee), color-stop(0.45, #ccc), color-stop(0.55, #ccc)); height: 100%; width: 100%; box-sizing: border-box; } div#value { height: 100%; box-sizing: border-box; } div#value.optimum { background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3)); } div#value.suboptimum { background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3)); height: 100%; box-sizing: border-box; } div#value.even-less-good { background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44)); height: 100%; box-sizing: border-box; "
+|       "div#inner { -webkit-appearance: inherit; box-sizing: inherit; height: 100%; width: 100%; } div#bar { background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd), color-stop(0.20, #eee), color-stop(0.45, #ccc), color-stop(0.55, #ccc)); height: 100%; width: 100%; box-sizing: border-box; } div#value { height: 100%; box-sizing: border-box; } div#value.optimum { background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3)); } div#value.suboptimum { background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3)); height: 100%; box-sizing: border-box; } div#value.even-less-good { background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44)); height: 100%; box-sizing: border-box; }"
 |     <div>
 |       id="inner"
 |       pseudo="-webkit-meter-inner-element"
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index cf26b6a..f0bf4d1 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,15 @@
+2021-03-24  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        All string resources from UserAgentStyleSheets / UserAgentScripts should be used as non-copying StringImpl
+        https://bugs.webkit.org/show_bug.cgi?id=223685
+
+        Reviewed by Saam Barati.
+
+        Add StringImpl::createWithoutCopying for `const char*`.
+
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::createWithoutCopying):
+
 2021-03-24  Eric Carlson  <eric.carlson@apple.com>
 
         [Cocoa] Add Experimental MediaSession coordinator
diff --git a/Source/WTF/wtf/text/StringImpl.h b/Source/WTF/wtf/text/StringImpl.h
index 196000c..afdd3e0 100644
--- a/Source/WTF/wtf/text/StringImpl.h
+++ b/Source/WTF/wtf/text/StringImpl.h
@@ -252,6 +252,7 @@
 
     WTF_EXPORT_PRIVATE static Ref<StringImpl> createWithoutCopying(const UChar*, unsigned length);
     WTF_EXPORT_PRIVATE static Ref<StringImpl> createWithoutCopying(const LChar*, unsigned length);
+    static Ref<StringImpl> createWithoutCopying(const char* characters, unsigned length) { return createWithoutCopying(reinterpret_cast<const LChar*>(characters), length); }
     WTF_EXPORT_PRIVATE static Ref<StringImpl> createUninitialized(unsigned length, LChar*&);
     WTF_EXPORT_PRIVATE static Ref<StringImpl> createUninitialized(unsigned length, UChar*&);
     template<typename CharacterType> static RefPtr<StringImpl> tryCreateUninitialized(unsigned length, CharacterType*&);
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 65958b7..230272d 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,39 @@
+2021-03-24  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        All string resources from UserAgentStyleSheets / UserAgentScripts should be used as non-copying StringImpl
+        https://bugs.webkit.org/show_bug.cgi?id=223685
+
+        Reviewed by Saam Barati.
+
+        We use StringImpl::createWithoutCopying for string resources from UserAgentStyleSheets / UserAgentScripts to make sure that
+        these resources do not allocate heap strings.
+
+        This patch also fixes HTMLMeterElement's bug (and imageOverlayUserAgentStyleSheet's bug). Previously, we are using String::ConstructFromLiteral,
+        but this only accepts string literal as it says. As a result, we are dropping the last character since UserAgentStyleSheets's last character is not \0.
+
+        * Modules/plugins/QuickTimePluginReplacement.mm:
+        (WebCore::quickTimePluginReplacementScript):
+        * WebCoreMacros.cmake:
+        * dom/Document.cpp:
+        (WebCore::Document::ensurePlugInsInjectedScript):
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::updateWithImageExtractionResult):
+        * html/HTMLMeterElement.cpp:
+        (WebCore::HTMLMeterElement::didAddUserAgentShadowRoot):
+        * rendering/RenderThemeAdwaita.cpp:
+        (WebCore::RenderThemeAdwaita::extraDefaultStyleSheet):
+        (WebCore::RenderThemeAdwaita::extraMediaControlsStyleSheet):
+        (WebCore::RenderThemeAdwaita::mediaControlsScripts):
+        * rendering/RenderThemeCocoa.mm:
+        (WebCore::RenderThemeCocoa::mediaControlsStyleSheet):
+        (WebCore::RenderThemeCocoa::mediaControlsScripts):
+        * rendering/RenderThemeWin.cpp:
+        (WebCore::RenderThemeWin::extraDefaultStyleSheet):
+        (WebCore::RenderThemeWin::extraQuirksStyleSheet):
+        * style/UserAgentStyle.cpp:
+        (WebCore::Style::UserAgentStyle::initDefaultStyleSheet):
+        (WebCore::Style::UserAgentStyle::ensureDefaultStyleSheetsForElement):
+
 2021-03-24  Chris Dumez  <cdumez@apple.com>
 
         bindings/js/JSEventListener.cpp:281:91: runtime error: reference binding to null pointer of type 'WebCore::ScriptExecutionContext'
diff --git a/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm b/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
index e8559beb..0ad2f76 100644
--- a/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
+++ b/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
@@ -67,7 +67,7 @@
 
 static String quickTimePluginReplacementScript()
 {
-    static NeverDestroyed<String> script(StringImpl::createStaticStringImpl(QuickTimePluginReplacementJavaScript, sizeof(QuickTimePluginReplacementJavaScript)));
+    static NeverDestroyed<String> script(StringImpl::createWithoutCopying(QuickTimePluginReplacementJavaScript, sizeof(QuickTimePluginReplacementJavaScript)));
     return script;
 }
 
diff --git a/Source/WebCore/WebCoreMacros.cmake b/Source/WebCore/WebCoreMacros.cmake
index 3abffee..89df6b6 100644
--- a/Source/WebCore/WebCoreMacros.cmake
+++ b/Source/WebCore/WebCoreMacros.cmake
@@ -36,7 +36,7 @@
     add_custom_command(
         OUTPUT ${_output_h} ${_output_cpp}
         DEPENDS ${JavaScriptCore_SCRIPTS_DIR}/make-js-file-arrays.py ${${_scripts}}
-        COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_SCRIPTS_DIR}/make-js-file-arrays.py -n ${_namespace} ${_output_h} ${_output_cpp} ${${_scripts}}
+        COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_SCRIPTS_DIR}/make-js-file-arrays.py --fail-if-non-ascii -n ${_namespace} ${_output_h} ${_output_cpp} ${${_scripts}}
         VERBATIM)
     WEBKIT_ADD_SOURCE_DEPENDENCIES(${${_scripts_dependencies}} ${_output_h} ${_output_cpp})
 endmacro()
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 534130e..e1c799b 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -7449,7 +7449,7 @@
     // Use the JS file provided by the Chrome client, or fallback to the default one.
     String jsString = page()->chrome().client().plugInExtraScript();
     if (!jsString || !scriptController.shouldAllowUserAgentScripts(*this))
-        jsString = String(plugInsJavaScript, sizeof(plugInsJavaScript));
+        jsString = StringImpl::createWithoutCopying(plugInsJavaScript, sizeof(plugInsJavaScript));
 
     setHasEvaluatedUserAgentScripts();
     scriptController.evaluateInWorldIgnoringException(ScriptSourceCode(jsString), world);
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index 8d3773f..1fbe639 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -1301,7 +1301,7 @@
 
     auto shadowRoot = makeRef(ensureUserAgentShadowRoot());
     if (!previousContainer) {
-        static NeverDestroyed<const String> shadowStyle(imageOverlayUserAgentStyleSheet, String::ConstructFromLiteral);
+        static MainThreadNeverDestroyed<const String> shadowStyle(StringImpl::createWithoutCopying(imageOverlayUserAgentStyleSheet, sizeof(imageOverlayUserAgentStyleSheet)));
         auto style = HTMLStyleElement::create(HTMLNames::styleTag, document(), false);
         style->setTextContent(shadowStyle);
         shadowRoot->appendChild(WTFMove(style));
diff --git a/Source/WebCore/html/HTMLMeterElement.cpp b/Source/WebCore/html/HTMLMeterElement.cpp
index 983db54..22954c5 100644
--- a/Source/WebCore/html/HTMLMeterElement.cpp
+++ b/Source/WebCore/html/HTMLMeterElement.cpp
@@ -225,7 +225,7 @@
 {
     ASSERT(!m_value);
 
-    static NeverDestroyed<String> shadowStyle(meterElementShadowUserAgentStyleSheet, String::ConstructFromLiteral);
+    static MainThreadNeverDestroyed<const String> shadowStyle(StringImpl::createWithoutCopying(meterElementShadowUserAgentStyleSheet, sizeof(meterElementShadowUserAgentStyleSheet)));
 
     auto style = HTMLStyleElement::create(HTMLNames::styleTag, document(), false);
     style->setTextContent(shadowStyle);
diff --git a/Source/WebCore/rendering/RenderThemeAdwaita.cpp b/Source/WebCore/rendering/RenderThemeAdwaita.cpp
index 80fea6f..59195c6 100644
--- a/Source/WebCore/rendering/RenderThemeAdwaita.cpp
+++ b/Source/WebCore/rendering/RenderThemeAdwaita.cpp
@@ -163,18 +163,18 @@
 
 String RenderThemeAdwaita::extraDefaultStyleSheet()
 {
-    return String(themeAdwaitaUserAgentStyleSheet, sizeof(themeAdwaitaUserAgentStyleSheet));
+    return StringImpl::createWithoutCopying(themeAdwaitaUserAgentStyleSheet, sizeof(themeAdwaitaUserAgentStyleSheet));
 }
 
 #if ENABLE(VIDEO)
 String RenderThemeAdwaita::extraMediaControlsStyleSheet()
 {
-    return String(mediaControlsAdwaitaUserAgentStyleSheet, sizeof(mediaControlsAdwaitaUserAgentStyleSheet));
+    return StringImpl::createWithoutCopying(mediaControlsAdwaitaUserAgentStyleSheet, sizeof(mediaControlsAdwaitaUserAgentStyleSheet));
 }
 
 Vector<String, 3> RenderThemeAdwaita::mediaControlsScripts()
 {
-    return { String(mediaControlsAdwaitaJavaScript, sizeof(mediaControlsAdwaitaJavaScript)) };
+    return { StringImpl::createWithoutCopying(mediaControlsAdwaitaJavaScript, sizeof(mediaControlsAdwaitaJavaScript)) };
 }
 #endif
 
diff --git a/Source/WebCore/rendering/RenderThemeCocoa.mm b/Source/WebCore/rendering/RenderThemeCocoa.mm
index 1ba4f55..9e208dd 100644
--- a/Source/WebCore/rendering/RenderThemeCocoa.mm
+++ b/Source/WebCore/rendering/RenderThemeCocoa.mm
@@ -184,7 +184,7 @@
 String RenderThemeCocoa::mediaControlsStyleSheet()
 {
     if (m_mediaControlsStyleSheet.isEmpty())
-        m_mediaControlsStyleSheet = StringImpl::createStaticStringImpl(ModernMediaControlsUserAgentStyleSheet, sizeof(ModernMediaControlsUserAgentStyleSheet));
+        m_mediaControlsStyleSheet = StringImpl::createWithoutCopying(ModernMediaControlsUserAgentStyleSheet, sizeof(ModernMediaControlsUserAgentStyleSheet));
     return m_mediaControlsStyleSheet;
 }
 
@@ -197,7 +197,7 @@
     }
 
     if (m_mediaControlsScript.isEmpty())
-        m_mediaControlsScript = StringImpl::createStaticStringImpl(ModernMediaControlsJavaScript, sizeof(ModernMediaControlsJavaScript));
+        m_mediaControlsScript = StringImpl::createWithoutCopying(ModernMediaControlsJavaScript, sizeof(ModernMediaControlsJavaScript));
 
 #if defined(RenderThemeCocoaAdditions_mediaControlsAdditionalScript)
     if (m_mediaControlsAdditionalScript.isEmpty())
diff --git a/Source/WebCore/rendering/RenderThemeWin.cpp b/Source/WebCore/rendering/RenderThemeWin.cpp
index d0fd2a6..2e60b7d 100644
--- a/Source/WebCore/rendering/RenderThemeWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeWin.cpp
@@ -271,12 +271,12 @@
 
 String RenderThemeWin::extraDefaultStyleSheet()
 {
-    return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
+    return StringImpl::createWithoutCopying(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
 }
 
 String RenderThemeWin::extraQuirksStyleSheet()
 {
-    return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet));
+    return StringImpl::createWithoutCopying(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet));
 }
 
 bool RenderThemeWin::supportsHover(const RenderStyle&) const
diff --git a/Source/WebCore/style/UserAgentStyle.cpp b/Source/WebCore/style/UserAgentStyle.cpp
index 2961c71..ced18a3 100644
--- a/Source/WebCore/style/UserAgentStyle.cpp
+++ b/Source/WebCore/style/UserAgentStyle.cpp
@@ -105,11 +105,6 @@
     return &sheet;
 }
 
-static StyleSheetContents* parseUASheet(const char* characters, unsigned size)
-{
-    return parseUASheet(String(characters, size));
-}
-
 void UserAgentStyle::addToDefaultStyle(StyleSheetContents& sheet)
 {
     defaultStyle->addRulesFromSheet(sheet, screenEval());
@@ -143,12 +138,12 @@
     mediaQueryStyleSheet = &StyleSheetContents::create(CSSParserContext(UASheetMode)).leakRef();
 
     // Strict-mode rules.
-    String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::singleton().extraDefaultStyleSheet();
+    String defaultRules = String(StringImpl::createWithoutCopying(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet))) + RenderTheme::singleton().extraDefaultStyleSheet();
     defaultStyleSheet = parseUASheet(defaultRules);
     addToDefaultStyle(*defaultStyleSheet);
 
     // Quirks-mode rules.
-    String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::singleton().extraQuirksStyleSheet();
+    String quirksRules = String(StringImpl::createWithoutCopying(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet))) + RenderTheme::singleton().extraQuirksStyleSheet();
     quirksStyleSheet = parseUASheet(quirksRules);
     defaultQuirksStyle->addRulesFromSheet(*quirksStyleSheet, screenEval());
 
@@ -162,14 +157,14 @@
             if (!plugInsStyleSheet && element.document().page()) {
                 String plugInsRules = RenderTheme::singleton().extraPlugInsStyleSheet() + element.document().page()->chrome().client().plugInExtraStyleSheet();
                 if (plugInsRules.isEmpty())
-                    plugInsRules = String(plugInsUserAgentStyleSheet, sizeof(plugInsUserAgentStyleSheet));
+                    plugInsRules = String(StringImpl::createWithoutCopying(plugInsUserAgentStyleSheet, sizeof(plugInsUserAgentStyleSheet)));
                 plugInsStyleSheet = parseUASheet(plugInsRules);
                 addToDefaultStyle(*plugInsStyleSheet);
             }
         }
         else if (is<HTMLDialogElement>(element) && RuntimeEnabledFeatures::sharedFeatures().dialogElementEnabled()) {
             if (!dialogStyleSheet) {
-                dialogStyleSheet = parseUASheet(dialogUserAgentStyleSheet, sizeof(dialogUserAgentStyleSheet));
+                dialogStyleSheet = parseUASheet(StringImpl::createWithoutCopying(dialogUserAgentStyleSheet, sizeof(dialogUserAgentStyleSheet)));
                 addToDefaultStyle(*dialogStyleSheet);
             }
         }
@@ -178,7 +173,7 @@
             if (!mediaControlsStyleSheet) {
                 String mediaRules = RenderTheme::singleton().mediaControlsStyleSheet();
                 if (mediaRules.isEmpty())
-                    mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::singleton().extraMediaControlsStyleSheet();
+                    mediaRules = String(StringImpl::createWithoutCopying(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet))) + RenderTheme::singleton().extraMediaControlsStyleSheet();
                 mediaControlsStyleSheet = parseUASheet(mediaRules);
                 addToDefaultStyle(*mediaControlsStyleSheet);
 
@@ -200,7 +195,7 @@
     } else if (is<SVGElement>(element)) {
         if (!svgStyleSheet) {
             // SVG rules.
-            svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
+            svgStyleSheet = parseUASheet(StringImpl::createWithoutCopying(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet)));
             addToDefaultStyle(*svgStyleSheet);
         }
     }
@@ -208,7 +203,7 @@
     else if (is<MathMLElement>(element)) {
         if (!mathMLStyleSheet) {
             // MathML rules.
-            mathMLStyleSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet));
+            mathMLStyleSheet = parseUASheet(StringImpl::createWithoutCopying(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet)));
             addToDefaultStyle(*mathMLStyleSheet);
         }
     }
@@ -228,7 +223,7 @@
 
 #if ENABLE(IOS_FORM_CONTROL_REFRESH)
     if (!legacyFormControlsIOSStyleSheet && !element.document().settings().iOSFormControlRefreshEnabled()) {
-        legacyFormControlsIOSStyleSheet = parseUASheet(legacyFormControlsIOSUserAgentStyleSheet, sizeof(legacyFormControlsIOSUserAgentStyleSheet));
+        legacyFormControlsIOSStyleSheet = parseUASheet(StringImpl::createWithoutCopying(legacyFormControlsIOSUserAgentStyleSheet, sizeof(legacyFormControlsIOSUserAgentStyleSheet)));
         addToDefaultStyle(*legacyFormControlsIOSStyleSheet);
     }
 #endif
diff --git a/Source/WebDriver/ChangeLog b/Source/WebDriver/ChangeLog
index bbe40de..c8fc89d 100644
--- a/Source/WebDriver/ChangeLog
+++ b/Source/WebDriver/ChangeLog
@@ -1,3 +1,19 @@
+2021-03-24  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        All string resources from UserAgentStyleSheets / UserAgentScripts should be used as non-copying StringImpl
+        https://bugs.webkit.org/show_bug.cgi?id=223685
+
+        Reviewed by Saam Barati.
+
+        * Session.cpp:
+        (WebDriver::Session::fullscreenWindow):
+        (WebDriver::Session::findElements):
+        (WebDriver::Session::isElementSelected):
+        (WebDriver::Session::isElementEnabled):
+        (WebDriver::Session::isElementDisplayed):
+        (WebDriver::Session::getElementAttribute):
+        (WebDriver::Session::elementClear):
+
 2021-02-22  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [SOUP] Add support for libsoup3
diff --git a/Source/WebDriver/Session.cpp b/Source/WebDriver/Session.cpp
index 8099a15..49f0807 100644
--- a/Source/WebDriver/Session.cpp
+++ b/Source/WebDriver/Session.cpp
@@ -933,7 +933,7 @@
 
         auto parameters = JSON::Object::create();
         parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
-        parameters->setString("function"_s, String(EnterFullscreenJavaScript, sizeof(EnterFullscreenJavaScript)));
+        parameters->setString("function"_s, StringImpl::createWithoutCopying(EnterFullscreenJavaScript, sizeof(EnterFullscreenJavaScript)));
         parameters->setArray("arguments"_s, JSON::Array::create());
         parameters->setBoolean("expectsImplicitCallbackArgument"_s, true);
         m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
@@ -1101,7 +1101,7 @@
         parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
         if (m_currentBrowsingContext)
             parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
-        parameters->setString("function"_s, String(FindNodesJavaScript, sizeof(FindNodesJavaScript)));
+        parameters->setString("function"_s, StringImpl::createWithoutCopying(FindNodesJavaScript, sizeof(FindNodesJavaScript)));
         parameters->setArray("arguments"_s, WTFMove(arguments));
         parameters->setBoolean("expectsImplicitCallbackArgument"_s, true);
         // If there's an implicit wait, use one second more as callback timeout.
@@ -1222,7 +1222,7 @@
         parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
         if (m_currentBrowsingContext)
             parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
-        parameters->setString("function"_s, String(ElementAttributeJavaScript, sizeof(ElementAttributeJavaScript)));
+        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementAttributeJavaScript, sizeof(ElementAttributeJavaScript)));
         parameters->setArray("arguments"_s, WTFMove(arguments));
         m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
             if (response.isError || !response.responseObject) {
@@ -1393,7 +1393,7 @@
         parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
         if (m_currentBrowsingContext)
             parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
-        parameters->setString("function"_s, String(ElementEnabledJavaScript, sizeof(ElementEnabledJavaScript)));
+        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementEnabledJavaScript, sizeof(ElementEnabledJavaScript)));
         parameters->setArray("arguments"_s, WTFMove(arguments));
         m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
             if (response.isError || !response.responseObject) {
@@ -1437,7 +1437,7 @@
         parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
         if (m_currentBrowsingContext)
             parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
-        parameters->setString("function"_s, String(ElementDisplayedJavaScript, sizeof(ElementDisplayedJavaScript)));
+        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementDisplayedJavaScript, sizeof(ElementDisplayedJavaScript)));
         parameters->setArray("arguments"_s, WTFMove(arguments));
         m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
             if (response.isError || !response.responseObject) {
@@ -1482,7 +1482,7 @@
         parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
         if (m_currentBrowsingContext)
             parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
-        parameters->setString("function"_s, String(ElementAttributeJavaScript, sizeof(ElementAttributeJavaScript)));
+        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementAttributeJavaScript, sizeof(ElementAttributeJavaScript)));
         parameters->setArray("arguments"_s, WTFMove(arguments));
         m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
             if (response.isError || !response.responseObject) {
@@ -1862,7 +1862,7 @@
                 parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
                 if (m_currentBrowsingContext)
                     parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
-                parameters->setString("function"_s, String(FormElementClearJavaScript, sizeof(FormElementClearJavaScript)));
+                parameters->setString("function"_s, StringImpl::createWithoutCopying(FormElementClearJavaScript, sizeof(FormElementClearJavaScript)));
                 parameters->setArray("arguments"_s, WTFMove(arguments));
                 m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
                     if (response.isError) {