Revert of Don't preload scripts with invalid type/language attributes (patchset #5 id:80001 of https://codereview.chromium.org/2099853002/ )

Reason for revert:
Some compat risk for this change was brought up. Going to send a note to blink-dev before re-landing.

Original issue's description:
> Don't preload scripts with invalid type/language attributes
>
> This patch keeps track of a script tag's type and language attributes,
> and gates preloading if they are invalid. This aligns the preload scanner's
> policy with the ScriptLoader's policy.
>
> BUG=623109
>
> Committed: https://crrev.com/23f4df7587f338837a709afb192900102584fc0a
> Cr-Commit-Position: refs/heads/master@{#403182}

TBR=yoav@yoav.ws
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=623109

Review-Url: https://codereview.chromium.org/2130773002
Cr-Commit-Position: refs/heads/master@{#404153}
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index 6ae5e2c..a8337a8d 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -121,7 +121,7 @@
     m_pendingScript = nullptr;
 }
 
-// Helper function. Must take a lowercase language as input.
+// Helper function
 static bool isLegacySupportedJavaScriptLanguage(const String& language)
 {
     // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only javascript1.1 - javascript1.3.
@@ -131,19 +131,24 @@
     // We want to accept all the values that either of these browsers accept, but not other values.
 
     // FIXME: This function is not HTML5 compliant. These belong in the MIME registry as "text/javascript<version>" entries.
-    DCHECK_EQ(language, language.lower());
-    return language == "javascript"
-        || language == "javascript1.0"
-        || language == "javascript1.1"
-        || language == "javascript1.2"
-        || language == "javascript1.3"
-        || language == "javascript1.4"
-        || language == "javascript1.5"
-        || language == "javascript1.6"
-        || language == "javascript1.7"
-        || language == "livescript"
-        || language == "ecmascript"
-        || language == "jscript";
+    typedef HashSet<String, CaseFoldingHash> LanguageSet;
+    DEFINE_STATIC_LOCAL(LanguageSet, languages, ());
+    if (languages.isEmpty()) {
+        languages.add("javascript");
+        languages.add("javascript1.0");
+        languages.add("javascript1.1");
+        languages.add("javascript1.2");
+        languages.add("javascript1.3");
+        languages.add("javascript1.4");
+        languages.add("javascript1.5");
+        languages.add("javascript1.6");
+        languages.add("javascript1.7");
+        languages.add("livescript");
+        languages.add("ecmascript");
+        languages.add("jscript");
+    }
+
+    return languages.contains(language);
 }
 
 void ScriptLoader::dispatchErrorEvent()
@@ -158,30 +163,29 @@
     setHaveFiredLoadEvent(true);
 }
 
-bool ScriptLoader::isValidScriptTypeAndLanguage(const String& type, const String& language, LegacyTypeSupport supportLegacyTypes)
+bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) const
 {
     // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used here to maintain backwards compatibility with existing layout tests. The specific violations are:
     // - Allowing type=javascript. type= should only support MIME types, such as text/javascript.
     // - Allowing a different set of languages for language= and type=. language= supports Javascript 1.1 and 1.4-1.6, but type= does not.
+
+    String type = client()->typeAttributeValue();
+    String language = client()->languageAttributeValue();
+    if (type.isEmpty() && language.isEmpty())
+        return true; // Assume text/javascript.
     if (type.isEmpty()) {
-        String lowerLanguage = language.lower();
-        return language.isEmpty() // assume text/javascript.
-            || MIMETypeRegistry::isSupportedJavaScriptMIMEType("text/" + lowerLanguage)
-            || isLegacySupportedJavaScriptLanguage(lowerLanguage);
+        type = "text/" + language.lower();
+        if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySupportedJavaScriptLanguage(language))
+            return true;
     } else if (RuntimeEnabledFeatures::moduleScriptsEnabled() && type == "module") {
         return true;
-    } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type.lower()))) {
+    } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
         return true;
     }
 
     return false;
 }
 
-bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) const
-{
-    return isValidScriptTypeAndLanguage(client()->typeAttributeValue(), client()->languageAttributeValue(), supportLegacyTypes);
-}
-
 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script
 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, LegacyTypeSupport supportLegacyTypes)
 {
@@ -340,10 +344,9 @@
 
 void ScriptLoader::logScriptMimetype(ScriptResource* resource, LocalFrame* frame, String mimetype)
 {
-    String lowerMimetype = mimetype.lower();
-    bool text = lowerMimetype.startsWith("text/");
-    bool application = lowerMimetype.startsWith("application/");
-    bool expectedJs = MIMETypeRegistry::isSupportedJavaScriptMIMEType(lowerMimetype) || (text && isLegacySupportedJavaScriptLanguage(lowerMimetype.substring(5)));
+    bool text = mimetype.lower().startsWith("text/");
+    bool application = mimetype.lower().startsWith("application/");
+    bool expectedJs = MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimetype) || (text && isLegacySupportedJavaScriptLanguage(mimetype.substring(5)));
     bool sameOrigin = m_element->document().getSecurityOrigin()->canRequest(m_resource->url());
     if (expectedJs) {
         return;
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.h b/third_party/WebKit/Source/core/dom/ScriptLoader.h
index 1fc84c7..0af9f42 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.h
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.h
@@ -50,8 +50,6 @@
     Element* element() const { return m_element; }
 
     enum LegacyTypeSupport { DisallowLegacyTypeInTypeAttribute, AllowLegacyTypeInTypeAttribute };
-    static bool isValidScriptTypeAndLanguage(const String& typeAttributeValue, const String& languageAttributeValue, LegacyTypeSupport supportLegacyTypes);
-
     bool prepareScript(const TextPosition& scriptStartPosition = TextPosition::minimumPosition(), LegacyTypeSupport = DisallowLegacyTypeInTypeAttribute);
 
     String scriptCharset() const { return m_characterEncoding; }
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
index a6b5992..14ecba3 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -34,7 +34,6 @@
 #include "core/css/MediaValuesCached.h"
 #include "core/css/parser/SizesAttributeParser.h"
 #include "core/dom/Document.h"
-#include "core/dom/ScriptLoader.h"
 #include "core/fetch/IntegrityMetadata.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
@@ -222,6 +221,7 @@
             }
         }
 
+
         TextPosition position = TextPosition(source.currentLine(), source.currentColumn());
         FetchRequest::ResourceWidth resourceWidth;
         float sourceSize = m_sourceSize;
@@ -272,10 +272,6 @@
         // explanation.
         else if (match(attributeName, integrityAttr))
             SubresourceIntegrity::parseIntegrityAttribute(attributeValue, m_integrityMetadata);
-        else if (match(attributeName, typeAttr))
-            m_typeAttributeValue = attributeValue;
-        else if (match(attributeName, languageAttr))
-            m_languageAttributeValue = attributeValue;
     }
 
     template<typename NameType>
@@ -444,8 +440,6 @@
             return false;
         if (match(m_tagImpl, inputTag) && !m_inputIsImage)
             return false;
-        if (match(m_tagImpl, scriptTag) && !ScriptLoader::isValidScriptTypeAndLanguage(m_typeAttributeValue, m_languageAttributeValue, ScriptLoader::AllowLegacyTypeInTypeAttribute))
-            return false;
         return true;
     }
 
@@ -477,8 +471,6 @@
     String m_imgSrcUrl;
     String m_srcsetAttributeValue;
     String m_asAttributeValue;
-    String m_typeAttributeValue;
-    String m_languageAttributeValue;
     float m_sourceSize;
     bool m_sourceSizeSet;
     FetchRequest::DeferOption m_defer;
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp
index 8932e76..bc584d1e 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp
@@ -414,33 +414,4 @@
         test(testCase);
 }
 
-// The preload scanner should follow the same policy that the ScriptLoader does
-// with regard to the type and language attribute.
-TEST_F(HTMLPreloadScannerTest, testScriptTypeAndLanguage)
-{
-    TestCase testCases[] = {
-        // Allow empty src and language attributes.
-        {"http://example.test", "<script src='test.js'></script>", "test.js", "http://example.test/", Resource::Script, 0},
-        {"http://example.test", "<script type='' language='' src='test.js'></script>", "test.js", "http://example.test/", Resource::Script, 0},
-        // Allow standard language and type attributes.
-        {"http://example.test", "<script type='text/javascript' src='test.js'></script>", "test.js", "http://example.test/", Resource::Script, 0},
-        {"http://example.test", "<script type='text/javascript' language='javascript' src='test.js'></script>", "test.js", "http://example.test/", Resource::Script, 0},
-        // Allow legacy languages in the "language" attribute with an empty
-        // type.
-        {"http://example.test", "<script language='javascript1.1' src='test.js'></script>", "test.js", "http://example.test/", Resource::Script, 0},
-        // Allow legacy languages in the "type" attribute.
-        {"http://example.test", "<script type='javascript' src='test.js'></script>", "test.js", "http://example.test/", Resource::Script, 0},
-        {"http://example.test", "<script type='javascript1.7' src='test.js'></script>", "test.js", "http://example.test/", Resource::Script, 0},
-        // Do not allow invalid types in the "type" attribute.
-        {"http://example.test", "<script type='invalid' src='test.js'></script>", nullptr, "http://example.test/", Resource::Script, 0},
-        {"http://example.test", "<script type='asdf' src='test.js'></script>", nullptr, "http://example.test/", Resource::Script, 0},
-        // Do not allow invalid languages.
-        {"http://example.test", "<script language='french' src='test.js'></script>", nullptr, "http://example.test/", Resource::Script, 0},
-        {"http://example.test", "<script language='python' src='test.js'></script>", nullptr, "http://example.test/", Resource::Script, 0},
-    };
-
-    for (const auto& testCase : testCases)
-        test(testCase);
-}
-
 } // namespace blink