Process Swap on Navigation causes many webpages to hang due to attempted process...
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / PasteMixedContent.mm
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if PLATFORM(MAC) && WK_API_ENABLED
29
30 #import "PlatformUtilities.h"
31 #import "TestWKWebView.h"
32 #import <WebKit/WKPreferencesRef.h>
33 #import <WebKit/WKPreferencesRefPrivate.h>
34 #import <wtf/RetainPtr.h>
35 #import <wtf/text/WTFString.h>
36
37 static NSString *imagePath()
38 {
39     return [[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png" inDirectory:@"TestWebKitAPI.resources"];
40 }
41
42 void writeTypesAndDataToPasteboard(id type, ...)
43 {
44     NSMutableArray<NSString *> *types = [NSMutableArray array];
45     NSMutableArray *data = [NSMutableArray array];
46     va_list argumentList;
47     if (type) {
48         ASSERT([type isKindOfClass:[NSString class]]);
49         [types addObject:type];
50         va_start(argumentList, type);
51         NSUInteger index = 1;
52         id object = va_arg(argumentList, id);
53         while (object) {
54             if (index % 2)
55                 [data addObject:object];
56             else {
57                 ASSERT([object isKindOfClass:[NSString class]]);
58                 [types addObject:object];
59             }
60             ++index;
61             object = va_arg(argumentList, id);
62         }
63         va_end(argumentList);
64     }
65
66     if (types.count != data.count) {
67         NSLog(@"Expected number of types: %tu to match number of data items: %tu", types.count, data.count);
68         ASSERT_NOT_REACHED();
69         return;
70     }
71
72     [[NSPasteboard generalPasteboard] declareTypes:types owner:nil];
73     [types enumerateObjectsUsingBlock:[&] (NSString *type, NSUInteger index, BOOL *) {
74         id dataToWrite = data[index];
75         if ([dataToWrite isKindOfClass:[NSData class]])
76             [[NSPasteboard generalPasteboard] setData:dataToWrite forType:type];
77         else if ([dataToWrite isKindOfClass:[NSString class]])
78             [[NSPasteboard generalPasteboard] setString:dataToWrite forType:type];
79         else
80             [[NSPasteboard generalPasteboard] setPropertyList:dataToWrite forType:type];
81     }];
82 }
83
84 static RetainPtr<TestWKWebView> setUpWebView()
85 {
86     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
87     WKPreferencesSetCustomPasteboardDataEnabled((WKPreferencesRef)[webView configuration].preferences, true);
88     [webView synchronouslyLoadTestPageNamed:@"DataTransfer"];
89     return webView;
90 }
91
92 static NSString *markupString()
93 {
94     // The script tag and mouseover listener attribute in the markup string below should be omitted during
95     // sanitization while pasting.
96     return @"<script>foo()</script><strong onmouseover='javascript:void(0)'>HELLO WORLD</strong>";
97 }
98
99 namespace TestWebKitAPI {
100
101 TEST(PasteMixedContent, ImageFileAndPlainText)
102 {
103     auto webView = setUpWebView();
104     writeTypesAndDataToPasteboard(NSFilenamesPboardType, @[ imagePath() ], NSPasteboardTypeString, imagePath(), nil);
105     [webView paste:nil];
106
107     EXPECT_WK_STREQ("Files", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
108     EXPECT_WK_STREQ("(FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
109     EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
110     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
111     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
112     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
113     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"rawHTMLData.textContent"]);
114 }
115
116 TEST(PasteMixedContent, ImageFileAndWebArchive)
117 {
118     auto webView = setUpWebView();
119     NSURL *mainResourceURL = [NSURL fileURLWithPath:@"/some/nonexistent/file.html"];
120     auto mainResource = adoptNS([[WebResource alloc] initWithData:[markupString() dataUsingEncoding:NSUTF8StringEncoding] URL:mainResourceURL MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]);
121     auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:nil subframeArchives:nil]);
122     writeTypesAndDataToPasteboard(NSFilenamesPboardType, @[ imagePath() ], WebArchivePboardType, [archive data], nil);
123     [webView paste:nil];
124
125     EXPECT_WK_STREQ("Files, text/html", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
126     EXPECT_WK_STREQ("(STRING, text/html), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
127     EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
128     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
129     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
130     EXPECT_WK_STREQ("HELLO WORLD", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
131     EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"rawHTMLData.textContent"] containsString:@"script"]);
132 }
133
134 TEST(PasteMixedContent, ImageFileAndHTML)
135 {
136     auto webView = setUpWebView();
137     writeTypesAndDataToPasteboard(NSFilenamesPboardType, @[ imagePath() ], NSPasteboardTypeHTML, markupString(), nil);
138     [webView paste:nil];
139
140     EXPECT_WK_STREQ("Files, text/html", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
141     EXPECT_WK_STREQ("(STRING, text/html), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
142     EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
143     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
144     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
145     EXPECT_WK_STREQ("HELLO WORLD", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
146     EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"rawHTMLData.textContent"] containsString:@"script"]);
147 }
148
149 TEST(PasteMixedContent, ImageFileAndRTF)
150 {
151     auto webView = setUpWebView();
152     auto text = adoptNS([[NSMutableAttributedString alloc] init]);
153     [text appendAttributedString:[[NSAttributedString alloc] initWithString:@"link to "]];
154     [text appendAttributedString:[[NSAttributedString alloc] initWithString:@"apple" attributes:@{ NSLinkAttributeName: [NSURL URLWithString:@"https://www.apple.com/"] }]];
155     NSData *rtfData = [text RTFFromRange:NSMakeRange(0, [text length]) documentAttributes:@{ }];
156     writeTypesAndDataToPasteboard(NSFilenamesPboardType, @[ imagePath() ], NSPasteboardTypeRTF, rtfData, nil);
157     [webView paste:nil];
158
159     EXPECT_WK_STREQ("Files, text/html", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
160     EXPECT_WK_STREQ("(STRING, text/html), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
161     EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
162     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
163     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
164     EXPECT_WK_STREQ("link to apple", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
165     EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"htmlData.querySelector('a').href"]);
166 }
167
168 TEST(PasteMixedContent, ImageFileAndURL)
169 {
170     auto webView = setUpWebView();
171     writeTypesAndDataToPasteboard(NSURLPboardType, @"https://www.webkit.org/", NSFilenamesPboardType, @[ imagePath() ], nil);
172     [webView paste:nil];
173
174     EXPECT_WK_STREQ("Files, text/uri-list", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
175     EXPECT_WK_STREQ("(STRING, text/uri-list), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
176     EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
177     EXPECT_WK_STREQ("https://www.webkit.org/", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
178     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
179     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
180 }
181
182 TEST(PasteMixedContent, ImageFileWithHTMLAndURL)
183 {
184     auto webView = setUpWebView();
185     writeTypesAndDataToPasteboard(NSURLPboardType, @"https://www.webkit.org/", NSPasteboardTypeHTML, markupString(), NSFilenamesPboardType, @[ imagePath() ], nil);
186     [webView paste:nil];
187
188     EXPECT_WK_STREQ("Files, text/uri-list, text/html", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
189     EXPECT_WK_STREQ("(STRING, text/uri-list), (STRING, text/html), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
190     EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
191     EXPECT_WK_STREQ("https://www.webkit.org/", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
192     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
193     EXPECT_WK_STREQ("HELLO WORLD", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
194     EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"rawHTMLData.textContent"] containsString:@"script"]);
195 }
196
197 TEST(PasteMixedContent, ImageDataAndPlainText)
198 {
199     auto webView = setUpWebView();
200     writeTypesAndDataToPasteboard(NSPasteboardTypeString, @"Hello world", NSPasteboardTypePNG, [NSData dataWithContentsOfFile:imagePath()], nil);
201     [webView paste:nil];
202
203     EXPECT_WK_STREQ("Files, text/plain", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
204     EXPECT_WK_STREQ("(STRING, text/plain), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
205     EXPECT_WK_STREQ("('image.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
206     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
207     EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
208     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
209 }
210
211 TEST(PasteMixedContent, ImageDataAndPlainTextAndURL)
212 {
213     auto webView = setUpWebView();
214     writeTypesAndDataToPasteboard(NSPasteboardTypeString, imagePath(), NSURLPboardType, imagePath(), NSPasteboardTypePNG, [NSData dataWithContentsOfFile:imagePath()], nil);
215     [webView paste:nil];
216
217     EXPECT_WK_STREQ("Files", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
218     EXPECT_WK_STREQ("(FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
219     EXPECT_WK_STREQ("('image.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
220     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
221     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
222     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
223 }
224
225 TEST(PasteMixedContent, ImageDataAndPlainTextAndURLAndHTML)
226 {
227     auto webView = setUpWebView();
228     writeTypesAndDataToPasteboard(NSPasteboardTypeString, imagePath(), NSURLPboardType, imagePath(), NSPasteboardTypeHTML, markupString(), NSPasteboardTypePNG, [NSData dataWithContentsOfFile:imagePath()], nil);
229     [webView paste:nil];
230
231     EXPECT_WK_STREQ("Files, text/html", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
232     EXPECT_WK_STREQ("(STRING, text/html), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
233     EXPECT_WK_STREQ("('image.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
234     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
235     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
236     EXPECT_WK_STREQ("HELLO WORLD", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
237     EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"rawHTMLData.textContent"] containsString:@"script"]);
238 }
239
240 } // namespace TestWebKitAPI
241
242 #endif // PLATFORM(MAC) && WK_API_ENABLED