Changeset 242735 in webkit
- Timestamp:
- Mar 11, 2019, 1:21:39 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 23 edited
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/NetworkProcess/NetworkContentRuleListManager.cpp (modified) (2 diffs)
-
Source/WebKit/NetworkProcess/NetworkContentRuleListManager.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.cpp (modified) (1 diff)
-
Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.h (modified) (1 diff)
-
Source/WebKit/Shared/WebCompiledContentRuleList.cpp (modified) (4 diffs)
-
Source/WebKit/Shared/WebCompiledContentRuleList.h (modified) (1 diff)
-
Source/WebKit/Shared/WebCompiledContentRuleListData.cpp (modified) (2 diffs)
-
Source/WebKit/Shared/WebCompiledContentRuleListData.h (modified) (3 diffs)
-
Source/WebKit/UIProcess/API/APIContentRuleList.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/API/APIContentRuleList.h (modified) (1 diff)
-
Source/WebKit/UIProcess/API/APIContentRuleListStore.cpp (modified) (13 diffs)
-
Source/WebKit/UIProcess/API/APIContentRuleListStore.h (modified) (2 diffs)
-
Source/WebKit/UIProcess/API/Cocoa/APIContentRuleListStoreCocoa.mm (modified) (2 diffs)
-
Source/WebKit/UIProcess/API/Cocoa/WKContentRuleListStore.mm (modified) (2 diffs)
-
Source/WebKit/UIProcess/API/Cocoa/WKContentRuleListStorePrivate.h (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/_WKUserContentFilter.mm (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/_WKUserContentFilterPrivate.h (modified) (1 diff)
-
Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp (modified) (1 diff)
-
Source/WebKit/WebProcess/UserContent/WebUserContentController.h (modified) (1 diff)
-
Source/WebKit/WebProcess/WebPage/WebPage.cpp (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r242728 r242735 1 2019-03-11 Alex Christensen <achristensen@webkit.org> 2 3 Add a WKContentRuleList variant that uses copied memory instead of mmap'd shared memory for class A containerized apps 4 https://bugs.webkit.org/show_bug.cgi?id=195511 5 <rdar://problem/44873269> 6 7 Reviewed by Darin Adler. 8 9 * NetworkProcess/NetworkContentRuleListManager.cpp: 10 (WebKit::NetworkContentRuleListManager::addContentRuleLists): 11 * NetworkProcess/NetworkContentRuleListManager.h: 12 * NetworkProcess/cache/NetworkCacheFileSystem.cpp: 13 (WebKit::NetworkCache::pathRegisteredAsUnsafeToMemoryMapForTesting): 14 (WebKit::NetworkCache::registerPathAsUnsafeToMemoryMapForTesting): 15 (WebKit::NetworkCache::isSafeToUseMemoryMapForPath): 16 * NetworkProcess/cache/NetworkCacheFileSystem.h: 17 * Shared/WebCompiledContentRuleList.cpp: 18 (WebKit::WebCompiledContentRuleList::usesCopiedMemory const): 19 (WebKit::WebCompiledContentRuleList::conditionsApplyOnlyToDomain const): 20 (WebKit::WebCompiledContentRuleList::filtersWithoutConditionsBytecode const): 21 (WebKit::WebCompiledContentRuleList::filtersWithConditionsBytecode const): 22 (WebKit::WebCompiledContentRuleList::topURLFiltersBytecode const): 23 (WebKit::WebCompiledContentRuleList::actions const): 24 * Shared/WebCompiledContentRuleList.h: 25 * Shared/WebCompiledContentRuleListData.cpp: 26 (WebKit::WebCompiledContentRuleListData::size const): 27 (WebKit::WebCompiledContentRuleListData::dataPointer const): 28 (WebKit::WebCompiledContentRuleListData::encode const): 29 (WebKit::WebCompiledContentRuleListData::decode): 30 * Shared/WebCompiledContentRuleListData.h: 31 (WebKit::WebCompiledContentRuleListData::WebCompiledContentRuleListData): 32 * UIProcess/API/APIContentRuleList.cpp: 33 (API::ContentRuleList::usesCopiedMemory const): 34 * UIProcess/API/APIContentRuleList.h: 35 * UIProcess/API/APIContentRuleListStore.cpp: 36 (API::getData): 37 (API::decodeContentRuleListMetaData): 38 (API::ContentRuleListStore::readContentsOfFile): 39 (API::MappedOrCopiedData::dataPointer const): 40 (API::openAndMapOrCopyContentRuleList): 41 (API::compiledToFile): 42 (API::createExtension): 43 (API::ContentRuleListStore::lookupContentRuleList): 44 (API::ContentRuleListStore::compileContentRuleList): 45 (API::ContentRuleListStore::getContentRuleListSource): 46 (API::openAndMapContentRuleList): Deleted. 47 * UIProcess/API/APIContentRuleListStore.h: 48 * UIProcess/API/Cocoa/APIContentRuleListStoreCocoa.mm: 49 (API::ContentRuleListStore::readContentsOfFile): 50 * UIProcess/API/Cocoa/WKContentRuleListStore.mm: 51 (+[WKContentRuleListStore _registerPathAsUnsafeToMemoryMapForTesting:]): 52 * UIProcess/API/Cocoa/WKContentRuleListStorePrivate.h: 53 * UIProcess/API/Cocoa/_WKUserContentFilter.mm: 54 (-[_WKUserContentFilter usesCopiedMemory]): 55 * UIProcess/API/Cocoa/_WKUserContentFilterPrivate.h: 56 * WebProcess/UserContent/WebUserContentController.cpp: 57 (WebKit::WebUserContentController::addContentRuleLists): 58 * WebProcess/UserContent/WebUserContentController.h: 59 * WebProcess/WebPage/WebPage.cpp: 60 (WebKit::m_hostFileDescriptor): 61 1 62 2019-03-11 Chris Dumez <cdumez@apple.com> 2 63 -
trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.cpp
r242710 r242735 67 67 } 68 68 69 void NetworkContentRuleListManager::addContentRuleLists(UserContentControllerIdentifier identifier, const Vector<std::pair<String, WebCompiledContentRuleListData>>& contentRuleLists)69 void NetworkContentRuleListManager::addContentRuleLists(UserContentControllerIdentifier identifier, Vector<std::pair<String, WebCompiledContentRuleListData>>&& contentRuleLists) 70 70 { 71 71 auto& backend = *m_contentExtensionBackends.ensure(identifier, [] { … … 73 73 }).iterator->value; 74 74 75 for (const auto& contentRuleList : contentRuleLists) { 76 WebCompiledContentRuleListData contentRuleListData = contentRuleList.second; 77 auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleListData)); 75 for (auto&& contentRuleList : contentRuleLists) { 76 auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleList.second)); 78 77 backend.addContentExtension(contentRuleList.first, WTFMove(compiledContentRuleList), ContentExtensions::ContentExtension::ShouldCompileCSS::No); 79 78 } -
trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.h
r242710 r242735 52 52 53 53 private: 54 void addContentRuleLists(UserContentControllerIdentifier, const Vector<std::pair<String, WebCompiledContentRuleListData>>&);54 void addContentRuleLists(UserContentControllerIdentifier, Vector<std::pair<String, WebCompiledContentRuleListData>>&&); 55 55 void removeContentRuleList(UserContentControllerIdentifier, const String& name); 56 56 void removeAllContentRuleLists(UserContentControllerIdentifier); -
trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.cpp
r242710 r242735 146 146 } 147 147 148 static String& pathRegisteredAsUnsafeToMemoryMapForTesting() 149 { 150 static NeverDestroyed<String> path; 151 return path.get(); 152 } 153 154 void registerPathAsUnsafeToMemoryMapForTesting(const String& path) 155 { 156 pathRegisteredAsUnsafeToMemoryMapForTesting() = path; 157 } 158 159 148 160 bool isSafeToUseMemoryMapForPath(const String& path) 149 161 { 162 if (path == pathRegisteredAsUnsafeToMemoryMapForTesting()) 163 return false; 164 150 165 #if PLATFORM(IOS_FAMILY) && !PLATFORM(IOS_FAMILY_SIMULATOR) 151 166 struct { -
trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.h
r242710 r242735 44 44 45 45 bool isSafeToUseMemoryMapForPath(const String& path); 46 void registerPathAsUnsafeToMemoryMapForTesting(const String&); 46 47 47 48 } -
trunk/Source/WebKit/Shared/WebCompiledContentRuleList.cpp
r242710 r242735 45 45 } 46 46 47 bool WebCompiledContentRuleList::usesCopiedMemory() const 48 { 49 return WTF::holds_alternative<RefPtr<WebCore::SharedBuffer>>(m_data.data); 50 } 51 47 52 bool WebCompiledContentRuleList::conditionsApplyOnlyToDomain() const 48 53 { 49 return *reinterpret_cast< uint32_t*>(reinterpret_cast<uint8_t*>(m_data.data->data()) + m_data.conditionsApplyOnlyToDomainOffset);54 return *reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(m_data.dataPointer()) + m_data.conditionsApplyOnlyToDomainOffset); 50 55 } 51 56 52 57 const WebCore::ContentExtensions::DFABytecode* WebCompiledContentRuleList::filtersWithoutConditionsBytecode() const 53 58 { 54 return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.data ->data()) + m_data.filtersWithoutConditionsBytecodeOffset;59 return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.dataPointer()) + m_data.filtersWithoutConditionsBytecodeOffset; 55 60 } 56 61 … … 62 67 const WebCore::ContentExtensions::DFABytecode* WebCompiledContentRuleList::filtersWithConditionsBytecode() const 63 68 { 64 return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.data ->data()) + m_data.filtersWithConditionsBytecodeOffset;69 return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.dataPointer()) + m_data.filtersWithConditionsBytecodeOffset; 65 70 } 66 71 … … 72 77 const WebCore::ContentExtensions::DFABytecode* WebCompiledContentRuleList::topURLFiltersBytecode() const 73 78 { 74 return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.data ->data()) + m_data.topURLFiltersBytecodeOffset;79 return static_cast<const WebCore::ContentExtensions::DFABytecode*>(m_data.dataPointer()) + m_data.topURLFiltersBytecodeOffset; 75 80 } 76 81 … … 82 87 const WebCore::ContentExtensions::SerializedActionByte* WebCompiledContentRuleList::actions() const 83 88 { 84 return static_cast<const WebCore::ContentExtensions::SerializedActionByte*>(m_data.data ->data()) + m_data.actionsOffset;89 return static_cast<const WebCore::ContentExtensions::SerializedActionByte*>(m_data.dataPointer()) + m_data.actionsOffset; 85 90 } 86 91 -
trunk/Source/WebKit/Shared/WebCompiledContentRuleList.h
r242710 r242735 39 39 virtual ~WebCompiledContentRuleList(); 40 40 41 WebCompiledContentRuleListDatadata() const { return m_data; }41 const WebCompiledContentRuleListData& data() const { return m_data; } 42 42 43 bool usesCopiedMemory() const; 44 43 45 private: 44 46 WebCompiledContentRuleList(WebCompiledContentRuleListData&&); -
trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.cpp
r242710 r242735 30 30 31 31 #include "ArgumentCoders.h" 32 #include "SharedBufferDataReference.h" 32 33 33 34 namespace WebKit { 34 35 36 size_t WebCompiledContentRuleListData::size() const 37 { 38 return WTF::switchOn(data, [] (const auto& sharedMemoryOrBuffer) { 39 return sharedMemoryOrBuffer->size(); 40 }); 41 } 42 43 const void* WebCompiledContentRuleListData::dataPointer() const 44 { 45 return WTF::switchOn(data, [] (const auto& sharedMemoryOrBuffer) -> const void* { 46 return sharedMemoryOrBuffer->data(); 47 }); 48 } 49 35 50 void WebCompiledContentRuleListData::encode(IPC::Encoder& encoder) const 36 51 { 37 SharedMemory::Handle handle; 38 data->createHandle(handle, SharedMemory::Protection::ReadOnly); 39 encoder << handle; 52 if (auto sharedMemory = WTF::get_if<RefPtr<SharedMemory>>(data)) { 53 encoder << true; 54 SharedMemory::Handle handle; 55 sharedMemory->get()->createHandle(handle, SharedMemory::Protection::ReadOnly); 56 encoder << handle; 57 } else { 58 encoder << false; 59 encoder << IPC::SharedBufferDataReference { *WTF::get<RefPtr<WebCore::SharedBuffer>>(data) }; 60 } 61 62 // fileData needs to be kept in the UIProcess, but it does not need to be serialized. 63 // FIXME: Move it to API::ContentRuleList 40 64 41 65 encoder << conditionsApplyOnlyToDomainOffset; … … 53 77 { 54 78 WebCompiledContentRuleListData compiledContentRuleListData; 55 SharedMemory::Handle handle; 56 if (!decoder.decode(handle)) 79 80 Optional<bool> hasSharedMemory; 81 decoder >> hasSharedMemory; 82 if (!hasSharedMemory) 57 83 return WTF::nullopt; 58 compiledContentRuleListData.data = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly); 84 if (*hasSharedMemory) { 85 SharedMemory::Handle handle; 86 if (!decoder.decode(handle)) 87 return WTF::nullopt; 88 compiledContentRuleListData.data = { SharedMemory::map(handle, SharedMemory::Protection::ReadOnly) }; 89 } else { 90 IPC::DataReference dataReference; 91 if (!decoder.decode(dataReference)) 92 return WTF::nullopt; 93 compiledContentRuleListData.data = { RefPtr<WebCore::SharedBuffer>(WebCore::SharedBuffer::create(dataReference.data(), dataReference.size())) }; 94 } 59 95 60 96 if (!decoder.decode(compiledContentRuleListData.conditionsApplyOnlyToDomainOffset)) -
trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.h
r242710 r242735 30 30 #include "NetworkCacheData.h" 31 31 #include "SharedMemory.h" 32 #include <WebCore/SharedBuffer.h> 32 33 #include <wtf/RefPtr.h> 34 #include <wtf/Variant.h> 33 35 34 36 namespace IPC { … … 43 45 WebCompiledContentRuleListData() = default; 44 46 45 WebCompiledContentRuleListData( RefPtr<SharedMemory>&& data, NetworkCache::Data fileData, unsigned conditionsApplyOnlyToDomainOffset, unsigned actionsOffset, unsigned actionsSize, unsigned filtersWithoutConditionsBytecodeOffset, unsigned filtersWithoutConditionsBytecodeSize, unsigned filtersWithConditionsBytecodeOffset, unsigned filtersWithConditionsBytecodeSize, unsigned topURLFiltersBytecodeOffset, unsigned topURLFiltersBytecodeSize)47 WebCompiledContentRuleListData(Variant<RefPtr<SharedMemory>, RefPtr<WebCore::SharedBuffer>>&& data, NetworkCache::Data fileData, unsigned conditionsApplyOnlyToDomainOffset, unsigned actionsOffset, unsigned actionsSize, unsigned filtersWithoutConditionsBytecodeOffset, unsigned filtersWithoutConditionsBytecodeSize, unsigned filtersWithConditionsBytecodeOffset, unsigned filtersWithConditionsBytecodeSize, unsigned topURLFiltersBytecodeOffset, unsigned topURLFiltersBytecodeSize) 46 48 : data(WTFMove(data)) 47 49 , fileData(fileData) … … 61 63 static Optional<WebCompiledContentRuleListData> decode(IPC::Decoder&); 62 64 63 RefPtr<SharedMemory> data; 65 size_t size() const; 66 const void* dataPointer() const; 67 68 Variant<RefPtr<SharedMemory>, RefPtr<WebCore::SharedBuffer>> data; 64 69 NetworkCache::Data fileData; 65 70 unsigned conditionsApplyOnlyToDomainOffset { 0 }; -
trunk/Source/WebKit/UIProcess/API/APIContentRuleList.cpp
r242710 r242735 43 43 } 44 44 45 bool ContentRuleList::usesCopiedMemory() const 46 { 47 return m_compiledRuleList->usesCopiedMemory(); 48 } 49 45 50 } // namespace API 46 51 -
trunk/Source/WebKit/UIProcess/API/APIContentRuleList.h
r242710 r242735 49 49 const WebKit::WebCompiledContentRuleList& compiledRuleList() const { return m_compiledRuleList.get(); } 50 50 51 bool usesCopiedMemory() const; 52 51 53 private: 52 54 WTF::String m_name; -
trunk/Source/WebKit/UIProcess/API/APIContentRuleListStore.cpp
r242710 r242735 38 38 #include <WebCore/ContentExtensionParser.h> 39 39 #include <WebCore/QualifiedName.h> 40 #include <WebCore/SharedBuffer.h> 40 41 #include <string> 41 42 #include <wtf/CompletionHandler.h> … … 157 158 } 158 159 159 static bool decodeContentRuleListMetaData(ContentRuleListMetaData& metaData, const WebKit::NetworkCache::Data& fileData) 160 template<typename T> void getData(const T&, const Function<bool(const uint8_t*, size_t)>&); 161 template<> void getData(const WebKit::NetworkCache::Data& data, const Function<bool(const uint8_t*, size_t)>& function) 162 { 163 data.apply(function); 164 } 165 template<> void getData(const WebCore::SharedBuffer& data, const Function<bool(const uint8_t*, size_t)>& function) 166 { 167 function(reinterpret_cast<const uint8_t*>(data.data()), data.size()); 168 } 169 170 template<typename T> 171 static Optional<ContentRuleListMetaData> decodeContentRuleListMetaData(const T& fileData) 160 172 { 161 173 bool success = false; 162 fileData.apply([&metaData, &success, &fileData](const uint8_t* data, size_t size) { 174 ContentRuleListMetaData metaData; 175 getData(fileData, [&metaData, &success, &fileData](const uint8_t* data, size_t size) { 163 176 // The file data should be mapped into one continuous memory segment so the size 164 177 // passed to the applier should always equal the data size. … … 184 197 return false; 185 198 }); 186 return success; 187 } 188 189 static bool openAndMapContentRuleList(const WTF::String& path, ContentRuleListMetaData& metaData, WebKit::NetworkCache::Data& fileData) 190 { 191 fileData = mapFile(fileSystemRepresentation(path).data()); 199 if (!success) 200 return WTF::nullopt; 201 return WTFMove(metaData); 202 } 203 204 #if !PLATFORM(COCOA) 205 RefPtr<WebCore::SharedBuffer> ContentRuleListStore::readContentsOfFile(const WTF::String& filePath) 206 { 207 ASSERT_NOT_REACHED(); 208 return nullptr; 209 } 210 #endif 211 212 struct MappedOrCopiedData { 213 ContentRuleListMetaData metaData; 214 Variant<WebKit::NetworkCache::Data, RefPtr<WebCore::SharedBuffer>> data; 215 216 const uint8_t* dataPointer() const 217 { 218 return WTF::switchOn(data, [] (const WebKit::NetworkCache::Data& data) { 219 return data.data(); 220 }, [] (const RefPtr<WebCore::SharedBuffer>& sharedBuffer) { 221 return reinterpret_cast<const uint8_t*>(sharedBuffer->data()); 222 }); 223 } 224 }; 225 226 static Optional<MappedOrCopiedData> openAndMapOrCopyContentRuleList(const WTF::String& path) 227 { 228 if (!WebKit::NetworkCache::isSafeToUseMemoryMapForPath(path)) { 229 RefPtr<WebCore::SharedBuffer> buffer = ContentRuleListStore::readContentsOfFile(path); 230 if (!buffer) 231 return WTF::nullopt; 232 auto metaData = decodeContentRuleListMetaData(*buffer); 233 if (!metaData) 234 return WTF::nullopt; 235 return {{ WTFMove(*metaData), { buffer.releaseNonNull() }}}; 236 } 237 238 WebKit::NetworkCache::Data fileData = mapFile(fileSystemRepresentation(path).data()); 192 239 if (fileData.isNull()) 193 return false; 194 195 if (!decodeContentRuleListMetaData(metaData, fileData)) 196 return false; 197 198 return true; 240 return WTF::nullopt; 241 auto metaData = decodeContentRuleListMetaData(fileData); 242 if (!metaData) 243 return WTF::nullopt; 244 return {{ WTFMove(*metaData), { WTFMove(fileData) }}}; 199 245 } 200 246 … … 213 259 } 214 260 215 static std::error_code compiledToFile(WTF::String&& json, Vector<WebCore::ContentExtensions::ContentExtensionRule>&& parsedRules, const WTF::String& finalFilePath, ContentRuleListMetaData& metaData, WebKit::NetworkCache::Data& mappedData)261 static Expected<MappedOrCopiedData, std::error_code> compiledToFile(WTF::String&& json, Vector<WebCore::ContentExtensions::ContentExtensionRule>&& parsedRules, const WTF::String& finalFilePath) 216 262 { 217 263 using namespace WebCore::ContentExtensions; … … 330 376 if (temporaryFileHandle == invalidPlatformFileHandle) { 331 377 WTFLogAlways("Content Rule List compiling failed: Opening temporary file failed."); 332 return ContentRuleListStore::Error::CompileFailed;378 return makeUnexpected(ContentRuleListStore::Error::CompileFailed); 333 379 } 334 380 … … 339 385 WTFLogAlways("Content Rule List compiling failed: Writing header to file failed."); 340 386 closeFile(temporaryFileHandle); 341 return ContentRuleListStore::Error::CompileFailed; 342 } 343 387 return makeUnexpected(ContentRuleListStore::Error::CompileFailed); 388 } 389 390 ContentRuleListMetaData metaData; 344 391 CompilationClient compilationClient(temporaryFileHandle, metaData); 345 392 … … 347 394 WTFLogAlways("Content Rule List compiling failed: Compiling failed."); 348 395 closeFile(temporaryFileHandle); 349 return compilerError;396 return makeUnexpected(compilerError); 350 397 } 351 398 if (compilationClient.hadErrorWhileWritingToFile()) { 352 399 WTFLogAlways("Content Rule List compiling failed: Writing to file failed."); 353 400 closeFile(temporaryFileHandle); 354 return ContentRuleListStore::Error::CompileFailed;355 } 356 357 mappedData = adoptAndMapFile(temporaryFileHandle, 0, metaData.fileSize());401 return makeUnexpected(ContentRuleListStore::Error::CompileFailed); 402 } 403 404 auto mappedData = adoptAndMapFile(temporaryFileHandle, 0, metaData.fileSize()); 358 405 if (mappedData.isNull()) { 359 406 WTFLogAlways("Content Rule List compiling failed: Mapping file failed."); 360 return ContentRuleListStore::Error::CompileFailed;407 return makeUnexpected(ContentRuleListStore::Error::CompileFailed); 361 408 } 362 409 363 410 if (!moveFile(temporaryFilePath, finalFilePath)) { 364 411 WTFLogAlways("Content Rule List compiling failed: Moving file failed."); 365 return ContentRuleListStore::Error::CompileFailed; 366 } 367 368 return { }; 369 } 370 371 static Ref<API::ContentRuleList> createExtension(const WTF::String& identifier, const ContentRuleListMetaData& metaData, const WebKit::NetworkCache::Data& fileData) 372 { 373 // Content extensions are always compiled to files, and at this point the file 374 // has been already mapped, therefore tryCreateSharedMemory() cannot fail. 375 auto sharedMemory = fileData.tryCreateSharedMemory(); 376 ASSERT(sharedMemory); 377 378 const size_t headerAndSourceSize = ContentRuleListFileHeaderSize + metaData.sourceSize; 412 return makeUnexpected(ContentRuleListStore::Error::CompileFailed); 413 } 414 415 if (!isSafeToUseMemoryMapForPath(finalFilePath)) { 416 auto contents = ContentRuleListStore::readContentsOfFile(finalFilePath); 417 if (!contents) 418 return makeUnexpected(ContentRuleListStore::Error::CompileFailed); 419 return {{ WTFMove(metaData), WTFMove(contents) }}; 420 } 421 422 return {{ WTFMove(metaData), WTFMove(mappedData) }}; 423 } 424 425 static Ref<API::ContentRuleList> createExtension(const WTF::String& identifier, MappedOrCopiedData&& data) 426 { 427 RefPtr<WebKit::SharedMemory> sharedMemory; 428 if (auto mappedFileData = WTF::get_if<WebKit::NetworkCache::Data>(data.data)) { 429 sharedMemory = mappedFileData->tryCreateSharedMemory(); 430 431 // Content extensions are always compiled to files, and at this point the file 432 // has been already mapped, therefore tryCreateSharedMemory() cannot fail. 433 ASSERT(sharedMemory); 434 } 435 auto mappedOrCopiedFileData = sharedMemory ? 436 Variant<RefPtr<WebKit::SharedMemory>, RefPtr<WebCore::SharedBuffer>> { sharedMemory } 437 : Variant<RefPtr<WebKit::SharedMemory>, RefPtr<WebCore::SharedBuffer>> { WTFMove(WTF::get<RefPtr<WebCore::SharedBuffer>>(data.data)) }; 438 439 const size_t headerAndSourceSize = ContentRuleListFileHeaderSize + data.metaData.sourceSize; 379 440 auto compiledContentRuleListData = WebKit::WebCompiledContentRuleListData( 380 WTFMove( sharedMemory),381 fileData,441 WTFMove(mappedOrCopiedFileData), 442 WTF::holds_alternative<WebKit::NetworkCache::Data>(data.data) ? WTF::get<WebKit::NetworkCache::Data>(data.data) : WebKit::NetworkCache::Data { }, 382 443 ConditionsApplyOnlyToDomainOffset, 383 444 headerAndSourceSize, 384 metaData.actionsSize,445 data.metaData.actionsSize, 385 446 headerAndSourceSize 386 + metaData.actionsSize,387 metaData.filtersWithoutConditionsBytecodeSize,447 + data.metaData.actionsSize, 448 data.metaData.filtersWithoutConditionsBytecodeSize, 388 449 headerAndSourceSize 389 + metaData.actionsSize390 + metaData.filtersWithoutConditionsBytecodeSize,391 metaData.filtersWithConditionsBytecodeSize,450 + data.metaData.actionsSize 451 + data.metaData.filtersWithoutConditionsBytecodeSize, 452 data.metaData.filtersWithConditionsBytecodeSize, 392 453 headerAndSourceSize 393 + metaData.actionsSize394 + metaData.filtersWithoutConditionsBytecodeSize395 + metaData.filtersWithConditionsBytecodeSize,396 metaData.conditionedFiltersBytecodeSize454 + data.metaData.actionsSize 455 + data.metaData.filtersWithoutConditionsBytecodeSize 456 + data.metaData.filtersWithConditionsBytecodeSize, 457 data.metaData.conditionedFiltersBytecodeSize 397 458 ); 398 459 auto compiledContentRuleList = WebKit::WebCompiledContentRuleList::create(WTFMove(compiledContentRuleListData)); … … 405 466 auto path = constructedPath(storePath, identifier, legacyFilename); 406 467 407 ContentRuleListMetaData metaData; 408 WebKit::NetworkCache::Data fileData; 409 if (!openAndMapContentRuleList(path, metaData, fileData)) { 468 auto contentRuleList = openAndMapOrCopyContentRuleList(path); 469 if (!contentRuleList) { 410 470 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] () mutable { 411 471 completionHandler(nullptr, Error::LookupFailed); … … 414 474 } 415 475 416 if ( metaData.version != ContentRuleListStore::CurrentContentRuleListFileVersion) {476 if (contentRuleList->metaData.version != ContentRuleListStore::CurrentContentRuleListFileVersion) { 417 477 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] () mutable { 418 478 completionHandler(nullptr, Error::VersionMismatch); … … 421 481 } 422 482 423 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = identifier.isolatedCopy(), fileData = WTFMove(fileData), metaData = WTFMove(metaData), completionHandler = WTFMove(completionHandler)] () mutable {424 completionHandler(createExtension(identifier, metaData, fileData), { });483 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = identifier.isolatedCopy(), contentRuleList = WTFMove(*contentRuleList), completionHandler = WTFMove(completionHandler)] () mutable { 484 completionHandler(createExtension(identifier, WTFMove(contentRuleList)), { }); 425 485 }); 426 486 }); … … 456 516 auto path = constructedPath(storePath, identifier, legacyFilename); 457 517 458 ContentRuleListMetaData metaData; 459 WebKit::NetworkCache::Data fileData; 460 auto error = compiledToFile(WTFMove(json), WTFMove(parsedRules), path, metaData, fileData); 461 if (error) { 462 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), error = WTFMove(error), completionHandler = WTFMove(completionHandler)] () mutable { 518 auto result = compiledToFile(WTFMove(json), WTFMove(parsedRules), path); 519 if (!result.has_value()) { 520 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), error = WTFMove(result.error()), completionHandler = WTFMove(completionHandler)] () mutable { 463 521 completionHandler(nullptr, error); 464 522 }); … … 466 524 } 467 525 468 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = WTFMove(identifier), fileData = WTFMove(fileData), metaData = WTFMove(metaData), completionHandler = WTFMove(completionHandler)] () mutable {469 RefPtr<API::ContentRuleList> contentRuleList = createExtension(identifier, metaData, fileData);470 completionHandler(contentRuleList , { });526 RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = WTFMove(identifier), data = WTFMove(result.value()), completionHandler = WTFMove(completionHandler)] () mutable { 527 auto contentRuleList = createExtension(identifier, WTFMove(data)); 528 completionHandler(contentRuleList.ptr(), { }); 471 529 }); 472 530 }); … … 518 576 }); 519 577 }; 520 521 ContentRuleListMetaData metaData; 522 WebKit::NetworkCache::Data fileData; 523 if (!openAndMapContentRuleList(path, metaData, fileData)) { 578 579 auto contentRuleList = openAndMapOrCopyContentRuleList(path); 580 if (!contentRuleList) { 524 581 complete({ }); 525 582 return; 526 583 } 527 584 528 switch ( metaData.version) {585 switch (contentRuleList->metaData.version) { 529 586 case 9: 530 587 case 10: 531 if (! metaData.sourceSize) {588 if (!contentRuleList->metaData.sourceSize) { 532 589 complete({ }); 533 590 return; 534 591 } 535 bool is8Bit = fileData.data()[ContentRuleListFileHeaderSize];592 bool is8Bit = contentRuleList->dataPointer()[ContentRuleListFileHeaderSize]; 536 593 size_t start = ContentRuleListFileHeaderSize + sizeof(bool); 537 size_t length = metaData.sourceSize - sizeof(bool);594 size_t length = contentRuleList->metaData.sourceSize - sizeof(bool); 538 595 if (is8Bit) 539 complete(WTF::String( fileData.data() + start, length));596 complete(WTF::String(contentRuleList->dataPointer() + start, length)); 540 597 else { 541 598 ASSERT(!(length % sizeof(UChar))); 542 complete(WTF::String(reinterpret_cast<const UChar*>( fileData.data() + start), length / sizeof(UChar)));599 complete(WTF::String(reinterpret_cast<const UChar*>(contentRuleList->dataPointer() + start), length / sizeof(UChar))); 543 600 } 544 601 return; -
trunk/Source/WebKit/UIProcess/API/APIContentRuleListStore.h
r242710 r242735 31 31 #include <system_error> 32 32 #include <wtf/text/WTFString.h> 33 34 namespace WebCore { 35 class SharedBuffer; 36 } 33 37 34 38 namespace WTF { … … 73 77 void getContentRuleListSource(const WTF::String& identifier, CompletionHandler<void(WTF::String)>); 74 78 79 static RefPtr<WebCore::SharedBuffer> readContentsOfFile(const WTF::String& path); 80 75 81 private: 76 82 WTF::String defaultStorePath(bool legacyFilename); -
trunk/Source/WebKit/UIProcess/API/Cocoa/APIContentRuleListStoreCocoa.mm
r242710 r242735 30 30 31 31 #include "SandboxUtilities.h" 32 #include <WebCore/SharedBuffer.h> 32 33 33 34 namespace API { … … 64 65 } 65 66 67 RefPtr<WebCore::SharedBuffer> ContentRuleListStore::readContentsOfFile(const String& filePath) 68 { 69 ASSERT(!isMainThread()); 70 NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:filePath isDirectory:NO]]; 71 if (!data) 72 return nullptr; 73 return WebCore::SharedBuffer::create(data); 74 } 75 66 76 } // namespace API 67 77 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKContentRuleListStore.mm
r242710 r242735 29 29 30 30 #import "APIContentRuleListStore.h" 31 #import "NetworkCacheFilesystem.h" 31 32 #import "WKErrorInternal.h" 32 33 #import <wtf/BlockPtr.h> … … 126 127 // For testing only. 127 128 129 + (void)_registerPathAsUnsafeToMemoryMapForTesting:(NSString *)filename 130 { 131 WebKit::NetworkCache::registerPathAsUnsafeToMemoryMapForTesting(filename); 132 } 133 128 134 - (void)_removeAllContentRuleLists 129 135 { -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKContentRuleListStorePrivate.h
r242710 r242735 32 32 - (void)_invalidateContentRuleListVersionForIdentifier:(NSString *)identifier; 33 33 - (void)_getContentRuleListSourceForIdentifier:(NSString *)identifier completionHandler:(void (^)(NSString*))completionHandler; 34 + (void)_registerPathAsUnsafeToMemoryMapForTesting:(NSString *)filename; 34 35 35 36 // NS_RELEASES_ARGUMENT to keep peak memory usage low. -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKUserContentFilter.mm
r242710 r242735 57 57 } 58 58 59 - (BOOL)usesCopiedMemory 60 { 61 return _contentRuleList->_contentRuleList->usesCopiedMemory(); 62 } 63 59 64 @end -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKUserContentFilterPrivate.h
r242710 r242735 31 31 32 32 - (id)_initWithWKContentRuleList:(WKContentRuleList*)contentRuleList WK_API_AVAILABLE(macosx(10.13), ios(11.0)); 33 @property (nonatomic, readonly) BOOL usesCopiedMemory; 33 34 34 35 @end -
trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp
r242710 r242735 349 349 350 350 #if ENABLE(CONTENT_EXTENSIONS) 351 void WebUserContentController::addContentRuleLists(const Vector<std::pair<String, WebCompiledContentRuleListData>>& contentRuleLists) 352 { 353 for (const auto& contentRuleList : contentRuleLists) { 354 WebCompiledContentRuleListData contentRuleListData = contentRuleList.second; 355 auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleListData)); 351 void WebUserContentController::addContentRuleLists(Vector<std::pair<String, WebCompiledContentRuleListData>>&& contentRuleLists) 352 { 353 for (auto&& contentRuleList : contentRuleLists) { 354 auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleList.second)); 356 355 357 356 m_contentExtensionBackend.addContentExtension(contentRuleList.first, WTFMove(compiledContentRuleList)); -
trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h
r242710 r242735 70 70 void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>&); 71 71 #if ENABLE(CONTENT_EXTENSIONS) 72 void addContentRuleLists( const Vector<std::pair<String, WebCompiledContentRuleListData>>&);72 void addContentRuleLists(Vector<std::pair<String, WebCompiledContentRuleListData>>&&); 73 73 #endif 74 74 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r242714 r242735 638 638 m_userContentController->addUserScriptMessageHandlers(parameters.messageHandlers); 639 639 #if ENABLE(CONTENT_EXTENSIONS) 640 m_userContentController->addContentRuleLists( parameters.contentRuleLists);640 m_userContentController->addContentRuleLists(WTFMove(parameters.contentRuleLists)); 641 641 #endif 642 642 -
trunk/Tools/ChangeLog
r242733 r242735 1 2019-03-11 Alex Christensen <achristensen@webkit.org> 2 3 Add a WKContentRuleList variant that uses copied memory instead of mmap'd shared memory for class A containerized apps 4 https://bugs.webkit.org/show_bug.cgi?id=195511 5 <rdar://problem/44873269> 6 7 Reviewed by Darin Adler. 8 9 * TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm: 10 (-[TestSchemeHandlerSubresourceShouldBeBlocked webView:startURLSchemeTask:]): 11 (-[TestSchemeHandlerSubresourceShouldBeBlocked webView:stopURLSchemeTask:]): 12 (TEST_F): 13 1 14 2019-03-11 Chris Dumez <cdumez@apple.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm
r242710 r242735 29 29 #import "PlatformUtilities.h" 30 30 #import "Test.h" 31 #import "TestWKWebView.h" 31 32 #import <WebKit/WKContentRuleList.h> 32 33 #import <WebKit/WKContentRuleListStorePrivate.h> 34 #import <WebKit/_WKUserContentFilterPrivate.h> 33 35 #import <wtf/RetainPtr.h> 36 #import <wtf/text/StringBuilder.h> 37 #import <wtf/text/StringConcatenate.h> 38 #import <wtf/text/StringConcatenateNumbers.h> 34 39 35 40 class WKContentRuleListStoreTest : public testing::Test { … … 378 383 TestWebKitAPI::Util::run(&receivedAlert); 379 384 } 385 386 @interface TestSchemeHandlerSubresourceShouldBeBlocked : NSObject <WKURLSchemeHandler> 387 @end 388 @implementation TestSchemeHandlerSubresourceShouldBeBlocked 389 - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task 390 { 391 EXPECT_TRUE([task.request.URL.path isEqualToString:@"/shouldload"]); 392 [task didReceiveResponse:[[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil] autorelease]]; 393 [task didFinish]; 394 } 395 - (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task 396 { 397 EXPECT_TRUE(false); 398 } 399 @end 400 401 TEST_F(WKContentRuleListStoreTest, UnsafeMMap) 402 { 403 RetainPtr<NSString> tempDir = [NSTemporaryDirectory() stringByAppendingPathComponent:@"UnsafeMMapTest"]; 404 RetainPtr<WKContentRuleListStore> store = [WKContentRuleListStore storeWithURL:[NSURL fileURLWithPath:tempDir.get() isDirectory:YES]]; 405 static NSString *identifier = @"TestRuleList"; 406 static NSString *fileName = @"ContentRuleList-TestRuleList"; 407 static NSString *ruleListSourceString = @"[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"blockedsubresource\"}}]"; 408 RetainPtr<NSString> filePath = [tempDir stringByAppendingPathComponent:fileName]; 409 410 auto runTest = [&] (bool shouldUseCopiedMemory) { 411 EXPECT_FALSE([[NSFileManager defaultManager] fileExistsAtPath:filePath.get()]); 412 413 __block bool doneCompiling = false; 414 __block RetainPtr<WKContentRuleList> ruleList; 415 [store compileContentRuleListForIdentifier:identifier encodedContentRuleList:ruleListSourceString completionHandler:^(WKContentRuleList *filter, NSError *error) { 416 EXPECT_NOT_NULL(filter); 417 EXPECT_NULL(error); 418 doneCompiling = true; 419 ruleList = filter; 420 EXPECT_TRUE([[[[_WKUserContentFilter alloc] _initWithWKContentRuleList:filter] autorelease] usesCopiedMemory] == shouldUseCopiedMemory); 421 }]; 422 TestWebKitAPI::Util::run(&doneCompiling); 423 424 EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:filePath.get()]); 425 426 auto handler = adoptNS([TestSchemeHandlerSubresourceShouldBeBlocked new]); 427 auto configuration = adoptNS([WKWebViewConfiguration new]); 428 [configuration setURLSchemeHandler:handler.get() forURLScheme:@"testmmap"]; 429 [[configuration userContentController] addContentRuleList:ruleList.get()]; 430 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 431 [webView synchronouslyLoadHTMLString:@"<html>main resource content</html>" baseURL:[NSURL URLWithString:@"testmmap://webkit.org/mainresource"]]; 432 433 auto loadingShouldSucceed = [&] (NSString *resourcePath, NSString *shouldSucceed) { 434 __block bool doneEvaluating = false; 435 [webView evaluateJavaScript:[NSString stringWithFormat:@"var caught = false; var xhr = new XMLHttpRequest(); xhr.open('GET', '%@', false); try{ xhr.send() } catch(e) { caught = true; }; caught != %@ ? 'success' : 'failure'", resourcePath, shouldSucceed] completionHandler:^(id result, NSError *error) { 436 EXPECT_NULL(error); 437 EXPECT_TRUE([@"success" isEqualToString:result]); 438 doneEvaluating = true; 439 }]; 440 TestWebKitAPI::Util::run(&doneEvaluating); 441 }; 442 loadingShouldSucceed(@"/shouldload", @"true"); 443 loadingShouldSucceed(@"/blockedsubresource", @"false"); 444 445 [[configuration userContentController] removeContentRuleList:ruleList.get()]; 446 447 __block bool doneLookingUp = false; 448 [store lookUpContentRuleListForIdentifier:identifier completionHandler:^(WKContentRuleList *filter, NSError *error) { 449 EXPECT_NOT_NULL(filter); 450 EXPECT_NULL(error); 451 452 doneLookingUp = true; 453 454 EXPECT_TRUE([[[[_WKUserContentFilter alloc] _initWithWKContentRuleList:filter] autorelease] usesCopiedMemory] == shouldUseCopiedMemory); 455 ruleList = filter; 456 }]; 457 TestWebKitAPI::Util::run(&doneLookingUp); 458 459 [[configuration userContentController] addContentRuleList:ruleList.get()]; 460 loadingShouldSucceed(@"/shouldload", @"true"); 461 loadingShouldSucceed(@"/blockedsubresource", @"false"); 462 463 __block bool doneCheckingSource = false; 464 [store _getContentRuleListSourceForIdentifier:identifier completionHandler:^(NSString *source) { 465 EXPECT_TRUE([source isEqualToString:ruleListSourceString]); 466 doneCheckingSource = true; 467 }]; 468 TestWebKitAPI::Util::run(&doneCheckingSource); 469 470 __block bool doneRemoving = false; 471 [store removeContentRuleListForIdentifier:identifier completionHandler:^(NSError *error) { 472 EXPECT_NULL(error); 473 doneRemoving = true; 474 }]; 475 TestWebKitAPI::Util::run(&doneRemoving); 476 477 EXPECT_FALSE([[NSFileManager defaultManager] fileExistsAtPath:filePath.get()]); 478 }; 479 480 runTest(false); 481 [WKContentRuleListStore _registerPathAsUnsafeToMemoryMapForTesting:filePath.get()]; 482 runTest(true); 483 }
Note:
See TracChangeset
for help on using the changeset viewer.