Title: [292680] trunk
Revision
292680
Author
cdu...@apple.com
Date
2022-04-09 12:05:27 -0700 (Sat, 09 Apr 2022)

Log Message

The Youtube plugin replacement should only work for actual Youtube URLs
https://bugs.webkit.org/show_bug.cgi?id=239003
<rdar://91323230>

Reviewed by Brent Fulgham.

Source/WebCore:

The Youtube plugin replacement was too permissive and was falling back to using
the original URL in cases there the original URL wasn't an expected Youtube
URL. This patch hardens the plugin replacement and drops the URL if it is not
a valid youtube URL instead.

Covered by new API test.

* Modules/plugins/YouTubePluginReplacement.cpp:
(WebCore::isYouTubeURL):
(WebCore::processAndCreateYouTubeURL):
(WebCore::YouTubePluginReplacement::youTubeURLFromAbsoluteURL):

Tools:

Add API test coverage.

* TestWebKitAPI/SourcesCocoa.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/YouTubePluginReplacement.cpp:
(TestWebKitAPI::test):
(TestWebKitAPI::TEST_F):
* TestWebKitAPI/Tests/WebKitCocoa/YoutubeReplacementPlugin.mm: Added.
(TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (292679 => 292680)


--- trunk/Source/WebCore/ChangeLog	2022-04-09 17:55:18 UTC (rev 292679)
+++ trunk/Source/WebCore/ChangeLog	2022-04-09 19:05:27 UTC (rev 292680)
@@ -1,3 +1,23 @@
+2022-04-09  Chris Dumez  <cdu...@apple.com>
+
+        The Youtube plugin replacement should only work for actual Youtube URLs
+        https://bugs.webkit.org/show_bug.cgi?id=239003
+        <rdar://91323230>
+
+        Reviewed by Brent Fulgham.
+
+        The Youtube plugin replacement was too permissive and was falling back to using
+        the original URL in cases there the original URL wasn't an expected Youtube
+        URL. This patch hardens the plugin replacement and drops the URL if it is not
+        a valid youtube URL instead.
+
+        Covered by new API test.
+
+        * Modules/plugins/YouTubePluginReplacement.cpp:
+        (WebCore::isYouTubeURL):
+        (WebCore::processAndCreateYouTubeURL):
+        (WebCore::YouTubePluginReplacement::youTubeURLFromAbsoluteURL):
+
 2022-04-09  Alan Bujtas  <za...@apple.com>
 
         REGRESSION (Safari 15.4): Focused element doesn't render outline when it has an underline

Modified: trunk/Source/WebCore/Modules/plugins/YouTubePluginReplacement.cpp (292679 => 292680)


--- trunk/Source/WebCore/Modules/plugins/YouTubePluginReplacement.cpp	2022-04-09 17:55:18 UTC (rev 292679)
+++ trunk/Source/WebCore/Modules/plugins/YouTubePluginReplacement.cpp	2022-04-09 19:05:27 UTC (rev 292680)
@@ -169,6 +169,9 @@
     
 static bool isYouTubeURL(const URL& url)
 {
+    if (!url.protocolIsInHTTPFamily())
+        return false;
+
     auto hostName = url.host();
     return equalLettersIgnoringASCIICase(hostName, "m.youtube.com")
         || equalLettersIgnoringASCIICase(hostName, "youtu.be")
@@ -189,8 +192,7 @@
 
 static URL processAndCreateYouTubeURL(const URL& url, bool& isYouTubeShortenedURL, String& outPathAfterFirstAmpersand)
 {
-    if (!url.protocolIsInHTTPFamily())
-        return URL();
+    ASSERT(isYouTubeURL(url));
 
     // Bail out early if we aren't even on www.youtube.com or youtube.com.
     if (!isYouTubeURL(url))
@@ -282,10 +284,14 @@
 
 String YouTubePluginReplacement::youTubeURLFromAbsoluteURL(const URL& srcURL, const String& srcString)
 {
+    // Validate URL to make sure it is a Youtube URL.
+    if (!isYouTubeURL(srcURL))
+        return emptyString();
+
     bool isYouTubeShortenedURL = false;
     String possiblyMalformedQuery;
     URL youTubeURL = processAndCreateYouTubeURL(srcURL, isYouTubeShortenedURL, possiblyMalformedQuery);
-    if (srcURL.isEmpty() || youTubeURL.isEmpty())
+    if (youTubeURL.isEmpty())
         return srcString;
 
     // Transform the youtubeURL (youtube:VideoID) to iframe embed url which has the format: http://www.youtube.com/embed/VideoID

Modified: trunk/Tools/ChangeLog (292679 => 292680)


--- trunk/Tools/ChangeLog	2022-04-09 17:55:18 UTC (rev 292679)
+++ trunk/Tools/ChangeLog	2022-04-09 19:05:27 UTC (rev 292680)
@@ -1,3 +1,21 @@
+2022-04-09  Chris Dumez  <cdu...@apple.com>
+
+        The Youtube plugin replacement should only work for actual Youtube URLs
+        https://bugs.webkit.org/show_bug.cgi?id=239003
+        <rdar://91323230>
+
+        Reviewed by Brent Fulgham.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/SourcesCocoa.txt:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/YouTubePluginReplacement.cpp:
+        (TestWebKitAPI::test):
+        (TestWebKitAPI::TEST_F):
+        * TestWebKitAPI/Tests/WebKitCocoa/YoutubeReplacementPlugin.mm: Added.
+        (TEST):
+
 2022-04-08  Elliott Williams  <e...@apple.com>
 
         [Xcode] Avoid targeting 32-bit iOS and Mac architectures

Modified: trunk/Tools/TestWebKitAPI/SourcesCocoa.txt (292679 => 292680)


--- trunk/Tools/TestWebKitAPI/SourcesCocoa.txt	2022-04-09 17:55:18 UTC (rev 292679)
+++ trunk/Tools/TestWebKitAPI/SourcesCocoa.txt	2022-04-09 19:05:27 UTC (rev 292680)
@@ -309,6 +309,7 @@
 Tests/WebKitCocoa/WebSocket.mm
 Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm
 Tests/WebKitCocoa/WebsitePolicies.mm
+Tests/WebKitCocoa/YoutubeReplacementPlugin.mm
 Tests/WebKitCocoa/_WKInputDelegate.mm
 Tests/WebKitCocoa/_WKUserContentExtensionStore.mm
 Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (292679 => 292680)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2022-04-09 17:55:18 UTC (rev 292679)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2022-04-09 19:05:27 UTC (rev 292680)
@@ -2026,6 +2026,7 @@
 		463F4722255B49B600D9E0CC /* VisibilityState.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = VisibilityState.mm; sourceTree = "<group>"; };
 		4647B1251EBA3B730041D7EF /* ProcessDidTerminate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessDidTerminate.cpp; sourceTree = "<group>"; };
 		464C764C230DF83200AFB020 /* BadServiceWorkerRegistrations-4.sqlite3 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "BadServiceWorkerRegistrations-4.sqlite3"; sourceTree = "<group>"; };
+		465A08FD280096F80028FD0E /* YoutubeReplacementPlugin.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = YoutubeReplacementPlugin.mm; sourceTree = "<group>"; };
 		465C23AE2640C3C500F2FC7F /* postMessage-regularly.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "postMessage-regularly.html"; sourceTree = "<group>"; };
 		465E2806255B2A690063A787 /* GPUProcess.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GPUProcess.mm; sourceTree = "<group>"; };
 		466AF38826FE393200CE2EB8 /* ServiceWorkerPagePlugIn.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ServiceWorkerPagePlugIn.mm; sourceTree = "<group>"; };
@@ -3764,6 +3765,7 @@
 				9984FACA1CFFAEEE008D198C /* WKWebViewTextInput.mm */,
 				95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */,
 				953ABB3425C0D681004C8B73 /* WKWebViewUnderPageBackgroundColor.mm */,
+				465A08FD280096F80028FD0E /* YoutubeReplacementPlugin.mm */,
 			);
 			name = "WebKit Cocoa";
 			path = WebKitCocoa;

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/YouTubePluginReplacement.cpp (292679 => 292680)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/YouTubePluginReplacement.cpp	2022-04-09 17:55:18 UTC (rev 292679)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/YouTubePluginReplacement.cpp	2022-04-09 19:05:27 UTC (rev 292680)
@@ -24,6 +24,7 @@
  */
 
 #include "config.h"
+#include "PlatformUtilities.h"
 #include <WebCore/YouTubePluginReplacement.h>
 #include <wtf/MainThread.h>
 #include <wtf/URL.h>
@@ -40,48 +41,50 @@
     }
 };
 
-static bool test(ASCIILiteral inputURLString, ASCIILiteral expectedURLString)
+static void test(ASCIILiteral inputURLString, ASCIILiteral expectedURLString)
 {
     URL inputURL { inputURLString };
     String actualURLString = YouTubePluginReplacement::youTubeURLFromAbsoluteURL(inputURL, inputURLString);
-    return actualURLString == expectedURLString;
+    EXPECT_WK_STREQ(expectedURLString.characters(), actualURLString.utf8().data());
 }
 
 TEST_F(YouTubePluginReplacementTest, YouTubeURLFromAbsoluteURL)
 {
     // YouTube non-video URL, not expected to be transformed.
-    EXPECT_TRUE(test("https://www.youtube.com"_s, "https://www.youtube.com"_s));
+    test("https://www.youtube.com"_s, "https://www.youtube.com"_s);
 
     // Basic YouTube video links, expected to be transformed.
-    EXPECT_TRUE(test("https://www.youtube.com/v/dQw4w9WgXcQ"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ"_s));
-    EXPECT_TRUE(test("http://www.youtube.com/v/dQw4w9WgXcQ"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ"_s));
-    EXPECT_TRUE(test("https://youtube.com/v/dQw4w9WgXcQ"_s, "https://youtube.com/embed/dQw4w9WgXcQ"_s));
-    EXPECT_TRUE(test("http://youtube.com/v/dQw4w9WgXcQ"_s, "http://youtube.com/embed/dQw4w9WgXcQ"_s));
+    test("https://www.youtube.com/v/dQw4w9WgXcQ"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ"_s);
+    test("http://www.youtube.com/v/dQw4w9WgXcQ"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ"_s);
+    test("https://youtube.com/v/dQw4w9WgXcQ"_s, "https://youtube.com/embed/dQw4w9WgXcQ"_s);
+    test("http://youtube.com/v/dQw4w9WgXcQ"_s, "http://youtube.com/embed/dQw4w9WgXcQ"_s);
 
     // With start time, preserved.
-    EXPECT_TRUE(test("http://www.youtube.com/v/dQw4w9WgXcQ?start=4"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s));
-    EXPECT_TRUE(test("http://www.youtube.com/v/dQw4w9WgXcQ?start=4&fs=1"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4&fs=1"_s));
+    test("http://www.youtube.com/v/dQw4w9WgXcQ?start=4"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s);
+    test("http://www.youtube.com/v/dQw4w9WgXcQ?start=4&fs=1"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4&fs=1"_s);
 
     // With an invalid query (see & instead of ?), we preserve and fix the query.
-    EXPECT_TRUE(test("http://www.youtube.com/v/dQw4w9WgXcQ&start=4"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s));
-    EXPECT_TRUE(test("http://www.youtube.com/v/dQw4w9WgXcQ&start=4&fs=1"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4&fs=1"_s));
+    test("http://www.youtube.com/v/dQw4w9WgXcQ&start=4"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s);
+    test("http://www.youtube.com/v/dQw4w9WgXcQ&start=4&fs=1"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?start=4&fs=1"_s);
 
     // Non-Flash URL is untouched.
-    EXPECT_TRUE(test("https://www.youtube.com/embed/dQw4w9WgXcQ"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ"_s));
-    EXPECT_TRUE(test("http://www.youtube.com/embed/dQw4w9WgXcQ"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ"_s));
-    EXPECT_TRUE(test("https://youtube.com/embed/dQw4w9WgXcQ"_s, "https://youtube.com/embed/dQw4w9WgXcQ"_s));
-    EXPECT_TRUE(test("http://youtube.com/embed/dQw4w9WgXcQ"_s, "http://youtube.com/embed/dQw4w9WgXcQ"_s));
+    test("https://www.youtube.com/embed/dQw4w9WgXcQ"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ"_s);
+    test("http://www.youtube.com/embed/dQw4w9WgXcQ"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ"_s);
+    test("https://youtube.com/embed/dQw4w9WgXcQ"_s, "https://youtube.com/embed/dQw4w9WgXcQ"_s);
+    test("http://youtube.com/embed/dQw4w9WgXcQ"_s, "http://youtube.com/embed/dQw4w9WgXcQ"_s);
     // Even with extra parameters.
-    EXPECT_TRUE(test("https://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s));
-    EXPECT_TRUE(test("http://www.youtube.com/embed/dQw4w9WgXcQ?enablejsapi=1"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?enablejsapi=1"_s));
+    test("https://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ?start=4"_s);
+    test("http://www.youtube.com/embed/dQw4w9WgXcQ?enablejsapi=1"_s, "http://www.youtube.com/embed/dQw4w9WgXcQ?enablejsapi=1"_s);
     // Even with an invalid "query".
-    EXPECT_TRUE(test("https://www.youtube.com/embed/dQw4w9WgXcQ&start=4"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ&start=4"_s));
+    test("https://www.youtube.com/embed/dQw4w9WgXcQ&start=4"_s, "https://www.youtube.com/embed/dQw4w9WgXcQ&start=4"_s);
 
     // Don't transform anything with a non "/v/" path component immediately following the domain.
-    EXPECT_TRUE(test("https://www.youtube.com/something/v/dQw4w9WgXcQ"_s, "https://www.youtube.com/something/v/dQw4w9WgXcQ"_s));
+    test("https://www.youtube.com/something/v/dQw4w9WgXcQ"_s, "https://www.youtube.com/something/v/dQw4w9WgXcQ"_s);
 
-    // Non-YouTube domain whose path looks like a Flash video shouldn't be transformed.
-    EXPECT_TRUE(test("https://www.notyoutube.com/v/dQw4w9WgXcQ"_s, "https://www.notyoutube.com/v/dQw4w9WgXcQ"_s));
+    // Non-valid Youtube URLs should be dropped.
+    test("https://www.notyoutube.com/v/dQw4w9WgXcQ"_s, ""_s);
+    test("data:,Hello%2C%20World%21"_s, ""_s);
+    test("_javascript_:foo()"_s, ""_s);
 }
 
 } // namespace TestWebKitAPI

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/YoutubeReplacementPlugin.mm (0 => 292680)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/YoutubeReplacementPlugin.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/YoutubeReplacementPlugin.mm	2022-04-09 19:05:27 UTC (rev 292680)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+
+TEST(YoutubeReplacementPlugin, CannotRunScript)
+{
+    auto configuration = adoptNS([WKWebViewConfiguration new]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration.get()]);
+    NSString *body = @"PASS<object data="" type=\"application/futuresplash\"><param name=\"src\" value=\"_javascript_:top.document.write('FAIL');\"></param></object>";
+    [webView synchronouslyLoadHTMLString:body];
+    NSString *bodyHTML = [webView stringByEvaluatingJavaScript:@"document.body.innerText"];
+    EXPECT_WK_STREQ(bodyHTML, @"PASS");
+    TestWebKitAPI::Util::spinRunLoop(100);
+    bodyHTML = [webView stringByEvaluatingJavaScript:@"document.body.innerText"];
+    EXPECT_WK_STREQ(bodyHTML, @"PASS");
+}
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to