Diff
Modified: trunk/Source/WebCore/ChangeLog (213987 => 213988)
--- trunk/Source/WebCore/ChangeLog 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebCore/ChangeLog 2017-03-15 17:59:08 UTC (rev 213988)
@@ -1,3 +1,23 @@
+2017-03-15 Alex Christensen <[email protected]>
+
+ Compiled content extensions should include the JSON source
+ https://bugs.webkit.org/show_bug.cgi?id=169643
+
+ Reviewed by Geoffrey Garen.
+
+ Serializing the JSON string from which a content extension was compiled
+ to disk with the compiled content extension will allow us to validate content
+ extensions and automatically migrate older content extensions to new versions.
+ It less than doubles the size of the compiled content extension on disk, and when
+ interpreting the bytecode that memory is never read, so it doesn't increase our
+ dirty memory usage.
+
+ Covered by new API tests.
+
+ * contentextensions/ContentExtensionCompiler.cpp:
+ (WebCore::ContentExtensions::compileRuleList):
+ * contentextensions/ContentExtensionCompiler.h:
+
2017-03-15 Antoine Quint <[email protected]>
[Modern Media Controls] Captions do not default to Auto when language is changed
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp (213987 => 213988)
--- trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp 2017-03-15 17:59:08 UTC (rev 213988)
@@ -306,6 +306,8 @@
#if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING
double patternPartitioningStart = monotonicallyIncreasingTime();
#endif
+
+ client.writeSource(ruleJSON);
Vector<SerializedActionByte> actions;
Vector<unsigned> actionLocations = serializeActions(parsedRuleList, actions);
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.h (213987 => 213988)
--- trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.h 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.h 2017-03-15 17:59:08 UTC (rev 213988)
@@ -40,6 +40,7 @@
virtual ~ContentExtensionCompilationClient() { }
// Functions should be called in this order. All except writeActions and finalize can be called multiple times, though.
+ virtual void writeSource(const String&) = 0;
virtual void writeActions(Vector<SerializedActionByte>&&, bool conditionsApplyOnlyToDomain) = 0;
virtual void writeFiltersWithoutConditionsBytecode(Vector<DFABytecode>&&) = 0;
virtual void writeFiltersWithConditionsBytecode(Vector<DFABytecode>&&) = 0;
Modified: trunk/Source/WebKit2/ChangeLog (213987 => 213988)
--- trunk/Source/WebKit2/ChangeLog 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/ChangeLog 2017-03-15 17:59:08 UTC (rev 213988)
@@ -1,3 +1,33 @@
+2017-03-15 Alex Christensen <[email protected]>
+
+ Compiled content extensions should include the JSON source
+ https://bugs.webkit.org/show_bug.cgi?id=169643
+
+ Reviewed by Geoffrey Garen.
+
+ * UIProcess/API/APIContentExtensionStore.cpp:
+ (API::ContentExtensionStore::ContentExtensionStore):
+ (API::ContentExtensionMetaData::fileSize):
+ (API::encodeContentExtensionMetaData):
+ (API::decodeContentExtensionMetaData):
+ (API::compiledToFile):
+ (API::createExtension):
+ (API::ContentExtensionStore::getContentExtensionSource):
+ * UIProcess/API/APIContentExtensionStore.h:
+ * UIProcess/API/Cocoa/WKContentExtensionStore.mm:
+ (toWKErrorCode):
+ (-[WKContentExtensionStore lookupContentExtensionForIdentifier:completionHandler:]):
+ (-[WKContentExtensionStore removeContentExtensionForIdentifier:completionHandler:]):
+ (-[WKContentExtensionStore _getContentExtensionSourceForIdentifier:completionHandler:]):
+ * UIProcess/API/Cocoa/WKContentExtensionStorePrivate.h:
+ * UIProcess/API/Cocoa/WKError.h:
+ * UIProcess/API/Cocoa/_WKUserContentExtensionStore.h:
+ * UIProcess/API/Cocoa/_WKUserContentExtensionStore.mm:
+ (toUserContentExtensionStoreError):
+ (-[_WKUserContentExtensionStore compileContentExtensionForIdentifier:encodedContentExtension:completionHandler:]):
+ (-[_WKUserContentExtensionStore lookupContentExtensionForIdentifier:completionHandler:]):
+ (-[_WKUserContentExtensionStore removeContentExtensionForIdentifier:completionHandler:]):
+
2017-03-15 Dean Jackson <[email protected]>
Sort Xcode project files
Modified: trunk/Source/WebKit2/UIProcess/API/APIContentExtensionStore.cpp (213987 => 213988)
--- trunk/Source/WebKit2/UIProcess/API/APIContentExtensionStore.cpp 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/UIProcess/API/APIContentExtensionStore.cpp 2017-03-15 17:59:08 UTC (rev 213988)
@@ -68,6 +68,7 @@
, m_readQueue(WorkQueue::create("ContentExtensionStore Read Queue"))
, m_removeQueue(WorkQueue::create("ContentExtensionStore Remove Queue"))
{
+ WebCore::makeAllDirectories(storePath);
}
ContentExtensionStore::~ContentExtensionStore()
@@ -81,11 +82,12 @@
// The size and offset of the densely packed bytes in the file, not sizeof and offsetof, which would
// represent the size and offset of the structure in memory, possibly with compiler-added padding.
-const size_t ContentExtensionFileHeaderSize = 2 * sizeof(uint32_t) + 4 * sizeof(uint64_t);
-const size_t ConditionsApplyOnlyToDomainOffset = sizeof(uint32_t) + 4 * sizeof(uint64_t);
+const size_t ContentExtensionFileHeaderSize = 2 * sizeof(uint32_t) + 5 * sizeof(uint64_t);
+const size_t ConditionsApplyOnlyToDomainOffset = sizeof(uint32_t) + 5 * sizeof(uint64_t);
struct ContentExtensionMetaData {
uint32_t version { ContentExtensionStore::CurrentContentExtensionFileVersion };
+ uint64_t sourceSize { 0 };
uint64_t actionsSize { 0 };
uint64_t filtersWithoutConditionsBytecodeSize { 0 };
uint64_t filtersWithConditionsBytecodeSize { 0 };
@@ -95,6 +97,7 @@
size_t fileSize() const
{
return ContentExtensionFileHeaderSize
+ + sourceSize
+ actionsSize
+ filtersWithoutConditionsBytecodeSize
+ filtersWithConditionsBytecodeSize
@@ -107,6 +110,7 @@
WTF::Persistence::Encoder encoder;
encoder << metaData.version;
+ encoder << metaData.sourceSize;
encoder << metaData.actionsSize;
encoder << metaData.filtersWithoutConditionsBytecodeSize;
encoder << metaData.filtersWithConditionsBytecodeSize;
@@ -129,6 +133,8 @@
WTF::Persistence::Decoder decoder(data, size);
if (!decoder.decode(metaData.version))
return false;
+ if (!decoder.decode(metaData.sourceSize))
+ return false;
if (!decoder.decode(metaData.actionsSize))
return false;
if (!decoder.decode(metaData.filtersWithoutConditionsBytecodeSize))
@@ -181,6 +187,7 @@
: m_fileHandle(fileHandle)
, m_metaData(metaData)
{
+ ASSERT(!metaData.sourceSize);
ASSERT(!metaData.actionsSize);
ASSERT(!metaData.filtersWithoutConditionsBytecodeSize);
ASSERT(!metaData.filtersWithConditionsBytecodeSize);
@@ -188,6 +195,25 @@
ASSERT(!metaData.conditionsApplyOnlyToDomain);
}
+ void writeSource(const String& sourceJSON) final {
+ ASSERT(!m_filtersWithoutConditionsBytecodeWritten);
+ ASSERT(!m_filtersWithConditionBytecodeWritten);
+ ASSERT(!m_conditionFiltersBytecodeWritten);
+ ASSERT(!m_actionsWritten);
+ ASSERT(!m_sourceWritten);
+ writeToFile(sourceJSON.is8Bit());
+ m_sourceWritten += sizeof(bool);
+ if (sourceJSON.is8Bit()) {
+ size_t serializedLength = sourceJSON.length() * sizeof(LChar);
+ writeToFile(Data(sourceJSON.characters8(), serializedLength));
+ m_sourceWritten += serializedLength;
+ } else {
+ size_t serializedLength = sourceJSON.length() * sizeof(UChar);
+ writeToFile(Data(reinterpret_cast<const uint8_t*>(sourceJSON.characters16()), serializedLength));
+ m_sourceWritten += serializedLength;
+ }
+ }
+
void writeFiltersWithoutConditionsBytecode(Vector<DFABytecode>&& bytecode) final
{
ASSERT(!m_filtersWithConditionBytecodeWritten);
@@ -222,6 +248,7 @@
void finalize() final
{
+ m_metaData.sourceSize = m_sourceWritten;
m_metaData.actionsSize = m_actionsWritten;
m_metaData.filtersWithoutConditionsBytecodeSize = m_filtersWithoutConditionsBytecodeWritten;
m_metaData.filtersWithConditionsBytecodeSize = m_filtersWithConditionBytecodeWritten;
@@ -239,6 +266,10 @@
bool hadErrorWhileWritingToFile() { return m_fileError; }
private:
+ void writeToFile(bool value)
+ {
+ writeToFile(Data(reinterpret_cast<const uint8_t*>(&value), sizeof(value)));
+ }
void writeToFile(const Data& data)
{
if (!m_fileError && !writeDataToFile(data, m_fileHandle)) {
@@ -253,6 +284,7 @@
size_t m_filtersWithConditionBytecodeWritten { 0 };
size_t m_conditionFiltersBytecodeWritten { 0 };
size_t m_actionsWritten { 0 };
+ size_t m_sourceWritten { 0 };
bool m_conditionsApplyOnlyToDomain { false };
bool m_fileError { false };
};
@@ -294,20 +326,21 @@
static RefPtr<API::ContentExtension> createExtension(const String& identifier, const ContentExtensionMetaData& metaData, const Data& fileData)
{
auto sharedMemory = WebKit::SharedMemory::create(const_cast<uint8_t*>(fileData.data()), fileData.size(), WebKit::SharedMemory::Protection::ReadOnly);
+ const size_t headerAndSourceSize = ContentExtensionFileHeaderSize + metaData.sourceSize;
auto compiledContentExtensionData = WebKit::WebCompiledContentExtensionData(
WTFMove(sharedMemory),
fileData,
ConditionsApplyOnlyToDomainOffset,
- ContentExtensionFileHeaderSize,
+ headerAndSourceSize,
metaData.actionsSize,
- ContentExtensionFileHeaderSize
+ headerAndSourceSize
+ metaData.actionsSize,
metaData.filtersWithoutConditionsBytecodeSize,
- ContentExtensionFileHeaderSize
+ headerAndSourceSize
+ metaData.actionsSize
+ metaData.filtersWithoutConditionsBytecodeSize,
metaData.filtersWithConditionsBytecodeSize,
- ContentExtensionFileHeaderSize
+ headerAndSourceSize
+ metaData.actionsSize
+ metaData.filtersWithoutConditionsBytecodeSize
+ metaData.filtersWithConditionsBytecodeSize,
@@ -401,7 +434,48 @@
ASSERT_UNUSED(bytesWritten, bytesWritten == sizeof(invalidHeader));
WebCore::closeFile(file);
}
-
+
+void ContentExtensionStore::getContentExtensionSource(const WTF::String& identifier, Function<void(WTF::String)> completionHandler)
+{
+ m_readQueue->dispatch([protectedThis = makeRef(*this), identifier = identifier.isolatedCopy(), storePath = m_storePath.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
+ auto path = constructedPath(storePath, identifier);
+
+ auto complete = [protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)](String source) mutable {
+ RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), source = source.isolatedCopy()] {
+ completionHandler(source);
+ });
+ };
+
+ ContentExtensionMetaData metaData;
+ Data fileData;
+ if (!openAndMapContentExtension(path, metaData, fileData)) {
+ complete({ });
+ return;
+ }
+
+ switch (metaData.version) {
+ case 9:
+ if (!metaData.sourceSize) {
+ complete({ });
+ return;
+ }
+ bool is8Bit = fileData.data()[ContentExtensionFileHeaderSize];
+ size_t start = ContentExtensionFileHeaderSize + sizeof(bool);
+ size_t length = metaData.sourceSize - sizeof(bool);
+ if (is8Bit)
+ complete(String(fileData.data() + start, length));
+ else {
+ ASSERT(!(length % sizeof(UChar)));
+ complete(String(reinterpret_cast<const UChar*>(fileData.data() + start), length / sizeof(UChar)));
+ }
+ return;
+ }
+
+ // Older versions cannot recover the original JSON source from disk.
+ complete({ });
+ });
+}
+
const std::error_category& contentExtensionStoreErrorCategory()
{
class ContentExtensionStoreErrorCategory : public std::error_category {
Modified: trunk/Source/WebKit2/UIProcess/API/APIContentExtensionStore.h (213987 => 213988)
--- trunk/Source/WebKit2/UIProcess/API/APIContentExtensionStore.h 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/UIProcess/API/APIContentExtensionStore.h 2017-03-15 17:59:08 UTC (rev 213988)
@@ -42,7 +42,7 @@
class ContentExtensionStore final : public ObjectImpl<Object::Type::ContentExtensionStore> {
public:
enum class Error {
- LookupFailed = 6, // Mirrors value of WKErrorContentExtensionStoreLookupFailed
+ LookupFailed = 1,
VersionMismatch,
CompileFailed,
RemoveFailed
@@ -50,7 +50,9 @@
// This should be incremented every time a functional change is made to the bytecode, file format, etc.
// to prevent crashing while loading old data.
- const static uint32_t CurrentContentExtensionFileVersion = 8;
+ // Also update ContentExtensionStore::getContentExtensionSource to be able to find the original JSON
+ // source from old versions.
+ const static uint32_t CurrentContentExtensionFileVersion = 9;
static ContentExtensionStore& defaultStore();
static Ref<ContentExtensionStore> storeWithPath(const WTF::String& storePath);
@@ -66,6 +68,7 @@
// For testing only.
void synchronousRemoveAllContentExtensions();
void invalidateContentExtensionVersion(const WTF::String& identifier);
+ void getContentExtensionSource(const WTF::String& identifier, Function<void(WTF::String)>);
private:
WTF::String defaultStorePath();
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKContentExtensionStore.mm (213987 => 213988)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKContentExtensionStore.mm 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKContentExtensionStore.mm 2017-03-15 17:59:08 UTC (rev 213988)
@@ -29,8 +29,26 @@
#if WK_API_ENABLED
+#import "APIContentExtensionStore.h"
#import "WKErrorInternal.h"
+static WKErrorCode toWKErrorCode(const std::error_code& error)
+{
+ ASSERT(error.category() == API::contentExtensionStoreErrorCategory());
+ switch (static_cast<API::ContentExtensionStore::Error>(error.value())) {
+ case API::ContentExtensionStore::Error::LookupFailed:
+ return WKErrorContentExtensionStoreLookupFailed;
+ case API::ContentExtensionStore::Error::VersionMismatch:
+ return WKErrorContentExtensionStoreVersionMismatch;
+ case API::ContentExtensionStore::Error::CompileFailed:
+ return WKErrorContentExtensionStoreCompileFailed;
+ case API::ContentExtensionStore::Error::RemoveFailed:
+ return WKErrorContentExtensionStoreRemoveFailed;
+ }
+ ASSERT_NOT_REACHED();
+ return WKErrorUnknown;
+}
+
@implementation WKContentExtensionStore
- (void)dealloc
@@ -92,8 +110,9 @@
auto rawHandler = (void (^)(WKContentExtension *, NSError *))handler.get();
auto userInfo = @{NSHelpAnchorErrorKey: [NSString stringWithFormat:@"Extension lookup failed: %s", error.message().c_str()]};
- ASSERT(error.value() == WKErrorContentExtensionStoreLookupFailed || error.value() == WKErrorContentExtensionStoreVersionMismatch);
- rawHandler(nil, [NSError errorWithDomain:WKErrorDomain code:error.value() userInfo:userInfo]);
+ auto wkError = toWKErrorCode(error);
+ ASSERT(wkError == WKErrorContentExtensionStoreLookupFailed || wkError == WKErrorContentExtensionStoreVersionMismatch);
+ rawHandler(nil, [NSError errorWithDomain:WKErrorDomain code:wkError userInfo:userInfo]);
return;
}
@@ -111,7 +130,7 @@
auto rawHandler = (void (^)(NSError *))handler.get();
auto userInfo = @{NSHelpAnchorErrorKey: [NSString stringWithFormat:@"Extension removal failed: %s", error.message().c_str()]};
- ASSERT(error.value() == WKErrorContentExtensionStoreRemoveFailed);
+ ASSERT(toWKErrorCode(error) == WKErrorContentExtensionStoreRemoveFailed);
rawHandler([NSError errorWithDomain:WKErrorDomain code:WKErrorContentExtensionStoreRemoveFailed userInfo:userInfo]);
return;
}
@@ -144,6 +163,18 @@
_contentExtensionStore->invalidateContentExtensionVersion(identifier);
}
+- (void)_getContentExtensionSourceForIdentifier:(NSString *)identifier completionHandler:(void (^)(NSString*))completionHandler
+{
+ auto handler = adoptNS([completionHandler copy]);
+ _contentExtensionStore->getContentExtensionSource(identifier, [handler](String source) {
+ auto rawHandler = (void (^)(NSString *))handler.get();
+ if (source.isNull())
+ rawHandler(nil);
+ else
+ rawHandler(source);
+ });
+}
+
// NS_RELEASES_ARGUMENT to keep peak memory usage low.
- (void)_compileContentExtensionForIdentifier:(NSString *)identifier encodedContentExtension:(NSString *)encodedContentExtension completionHandler:(void (^)(WKContentExtension *, NSError *))completionHandler
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKContentExtensionStorePrivate.h (213987 => 213988)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKContentExtensionStorePrivate.h 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKContentExtensionStorePrivate.h 2017-03-15 17:59:08 UTC (rev 213988)
@@ -32,6 +32,7 @@
// For testing only.
- (void)_removeAllContentExtensions;
- (void)_invalidateContentExtensionVersionForIdentifier:(NSString *)identifier;
+- (void)_getContentExtensionSourceForIdentifier:(NSString *)identifier completionHandler:(void (^)(NSString*))completionHandler;
// NS_RELEASES_ARGUMENT to keep peak memory usage low.
- (void)_compileContentExtensionForIdentifier:(NSString *)identifier encodedContentExtension:(NSString *) NS_RELEASES_ARGUMENT encodedContentExtension completionHandler:(void (^)(WKContentExtension *, NSError *))completionHandler;
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKError.h (213987 => 213988)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKError.h 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKError.h 2017-03-15 17:59:08 UTC (rev 213988)
@@ -42,7 +42,7 @@
@constant WKErrorJavaScriptExceptionOccurred Indicates that a _javascript_ exception occurred.
@constant WKErrorJavaScriptResultTypeIsUnsupported Indicates that the result of _javascript_ execution could not be returned.
@constant WKErrorContentExtensionStoreLookupFailed Indicates that looking up a WKUserContentExtension failed.
- @constant WKErrorContentExtensionStoreVersionMismatch Indicates that looking up a WKUserContentExtension found an extension with an incompatible binary version.
+ @constant WKErrorContentExtensionStoreVersionMismatch Indicates that the WKUserContentExtension version did not match the latest.
@constant WKErrorContentExtensionStoreCompileFailed Indicates that compiling a WKUserContentExtension failed.
@constant WKErrorContentExtensionStoreRemoveFailed Indicates that removing a WKUserContentExtension failed.
*/
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKUserContentExtensionStore.h (213987 => 213988)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKUserContentExtensionStore.h 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKUserContentExtensionStore.h 2017-03-15 17:59:08 UTC (rev 213988)
@@ -44,7 +44,7 @@
WK_EXTERN NSString * const _WKUserContentExtensionsDomain WK_API_AVAILABLE(macosx(10.12), ios(10.0));
typedef NS_ENUM(NSInteger, _WKUserContentExtensionStoreErrorCode) {
- _WKUserContentExtensionStoreErrorLookupFailed = 6, // Mirrors value of WKErrorContentExtensionStoreLookupFailed
+ _WKUserContentExtensionStoreErrorLookupFailed,
_WKUserContentExtensionStoreErrorVersionMismatch,
_WKUserContentExtensionStoreErrorCompileFailed,
_WKUserContentExtensionStoreErrorRemoveFailed,
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKUserContentExtensionStore.mm (213987 => 213988)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKUserContentExtensionStore.mm 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKUserContentExtensionStore.mm 2017-03-15 17:59:08 UTC (rev 213988)
@@ -38,6 +38,26 @@
NSString * const _WKUserContentExtensionsDomain = @"WKErrorDomain";
+static NSError *toUserContentExtensionStoreError(const NSError *error)
+{
+ if (!error)
+ return nil;
+
+ ASSERT(error.domain == WKErrorDomain);
+ switch (error.code) {
+ case WKErrorContentExtensionStoreLookupFailed:
+ return [NSError errorWithDomain:_WKUserContentExtensionsDomain code:_WKUserContentExtensionStoreErrorLookupFailed userInfo:error.userInfo];
+ case WKErrorContentExtensionStoreVersionMismatch:
+ return [NSError errorWithDomain:_WKUserContentExtensionsDomain code:_WKUserContentExtensionStoreErrorVersionMismatch userInfo:error.userInfo];
+ case WKErrorContentExtensionStoreCompileFailed:
+ return [NSError errorWithDomain:_WKUserContentExtensionsDomain code:_WKUserContentExtensionStoreErrorCompileFailed userInfo:error.userInfo];
+ case WKErrorContentExtensionStoreRemoveFailed:
+ return [NSError errorWithDomain:_WKUserContentExtensionsDomain code:_WKUserContentExtensionStoreErrorRemoveFailed userInfo:error.userInfo];
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+}
+
@implementation _WKUserContentExtensionStore
+ (instancetype)defaultStore
@@ -54,7 +74,7 @@
{
[_contentExtensionStore _compileContentExtensionForIdentifier:identifier encodedContentExtension:encodedContentExtension completionHandler:^(WKContentExtension *contentExtension, NSError *error) {
_WKUserContentFilter *contentFilter = contentExtension ? [[[_WKUserContentFilter alloc] _initWithWKContentExtension:contentExtension] autorelease] : nil;
- completionHandler(contentFilter, error);
+ completionHandler(contentFilter, toUserContentExtensionStoreError(error));
}];
}
@@ -62,13 +82,15 @@
{
[_contentExtensionStore lookupContentExtensionForIdentifier:identifier completionHandler:^(WKContentExtension *contentExtension, NSError *error) {
_WKUserContentFilter *contentFilter = contentExtension ? [[[_WKUserContentFilter alloc] _initWithWKContentExtension:contentExtension] autorelease] : nil;
- completionHandler(contentFilter, error);
+ completionHandler(contentFilter, toUserContentExtensionStoreError(error));
}];
}
- (void)removeContentExtensionForIdentifier:(NSString *)identifier completionHandler:(void (^)(NSError *))completionHandler
{
- [_contentExtensionStore removeContentExtensionForIdentifier:identifier completionHandler:completionHandler];
+ [_contentExtensionStore removeContentExtensionForIdentifier:identifier completionHandler:^(NSError *error) {
+ completionHandler(toUserContentExtensionStoreError(error));
+ }];
}
#pragma mark WKObject protocol implementation
Modified: trunk/Tools/ChangeLog (213987 => 213988)
--- trunk/Tools/ChangeLog 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Tools/ChangeLog 2017-03-15 17:59:08 UTC (rev 213988)
@@ -1,3 +1,14 @@
+2017-03-15 Alex Christensen <[email protected]>
+
+ Compiled content extensions should include the JSON source
+ https://bugs.webkit.org/show_bug.cgi?id=169643
+
+ Reviewed by Geoffrey Garen.
+
+ * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
+ * TestWebKitAPI/Tests/WebKit2Cocoa/WKUserContentExtensionStore.mm:
+ (TEST_F):
+
2017-03-15 Kocsen Chung <[email protected]>
Use git's -C flag when possible in VCSUtils.pm
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp (213987 => 213988)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp 2017-03-15 17:59:08 UTC (rev 213988)
@@ -100,6 +100,8 @@
EXPECT_EQ(data.topURLFilters.size(), 0ull);
}
+ void writeSource(const String&) final { }
+
void writeActions(Vector<ContentExtensions::SerializedActionByte>&& actions, bool conditionsApplyOnlyToDomain) final
{
EXPECT_FALSE(finalized);
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKUserContentExtensionStore.mm (213987 => 213988)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKUserContentExtensionStore.mm 2017-03-15 17:40:59 UTC (rev 213987)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKUserContentExtensionStore.mm 2017-03-15 17:59:08 UTC (rev 213988)
@@ -146,6 +146,13 @@
doneLookingUp = true;
}];
TestWebKitAPI::Util::run(&doneLookingUp);
+
+ __block bool doneGettingSource = false;
+ [[WKContentExtensionStore defaultStore] _getContentExtensionSourceForIdentifier:@"TestExtension" completionHandler:^(NSString* source) {
+ EXPECT_NULL(source);
+ doneGettingSource = true;
+ }];
+ TestWebKitAPI::Util::run(&doneGettingSource);
}
TEST_F(WKContentExtensionStoreTest, Removal)
@@ -183,4 +190,69 @@
TestWebKitAPI::Util::run(&doneRemoving);
}
+TEST_F(WKContentExtensionStoreTest, NonDefaultStore)
+{
+ NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"ContentExtensionTest"] isDirectory:YES];
+ WKContentExtensionStore *store = [WKContentExtensionStore storeWithURL:tempDir];
+ NSString *identifier = @"TestExtension";
+ NSString *fileName = @"ContentExtension-TestExtension";
+
+ __block bool doneCompiling = false;
+ [store compileContentExtensionForIdentifier:identifier encodedContentExtension:basicFilter completionHandler:^(WKContentExtension *filter, NSError *error) {
+ EXPECT_NOT_NULL(filter);
+ EXPECT_NULL(error);
+ doneCompiling = true;
+ }];
+ TestWebKitAPI::Util::run(&doneCompiling);
+
+ NSData *data = "" dataWithContentsOfURL:[tempDir URLByAppendingPathComponent:fileName]];
+ EXPECT_NOT_NULL(data);
+ EXPECT_EQ(data.length, 228u);
+
+ __block bool doneCheckingSource = false;
+ [store _getContentExtensionSourceForIdentifier:identifier completionHandler:^(NSString *source) {
+ EXPECT_NOT_NULL(source);
+ EXPECT_STREQ(basicFilter.UTF8String, source.UTF8String);
+ doneCheckingSource = true;
+ }];
+ TestWebKitAPI::Util::run(&doneCheckingSource);
+
+ __block bool doneRemoving = false;
+ [store removeContentExtensionForIdentifier:identifier completionHandler:^(NSError *error) {
+ EXPECT_NULL(error);
+ doneRemoving = true;
+ }];
+ TestWebKitAPI::Util::run(&doneRemoving);
+
+ NSData *dataAfterRemoving = [NSData dataWithContentsOfURL:[tempDir URLByAppendingPathComponent:fileName]];
+ EXPECT_NULL(dataAfterRemoving);
+}
+
+TEST_F(WKContentExtensionStoreTest, NonASCIISource)
+{
+ static NSString *nonASCIIFilter = @"[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*webkit.org\"}, \"unused\":\"💩\"}]";
+ NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"ContentExtensionTest"] isDirectory:YES];
+ WKContentExtensionStore *store = [WKContentExtensionStore storeWithURL:tempDir];
+ NSString *identifier = @"TestExtension";
+ NSString *fileName = @"ContentExtension-TestExtension";
+
+ __block bool done = false;
+ [store compileContentExtensionForIdentifier:identifier encodedContentExtension:nonASCIIFilter completionHandler:^(WKContentExtension *filter, NSError *error) {
+ EXPECT_NOT_NULL(filter);
+ EXPECT_NULL(error);
+
+ [store _getContentExtensionSourceForIdentifier:identifier completionHandler:^(NSString *source) {
+ EXPECT_NOT_NULL(source);
+ EXPECT_STREQ(nonASCIIFilter.UTF8String, source.UTF8String);
+
+ [store _removeAllContentExtensions];
+ NSData *dataAfterRemoving = [NSData dataWithContentsOfURL:[tempDir URLByAppendingPathComponent:fileName]];
+ EXPECT_NULL(dataAfterRemoving);
+
+ done = true;
+ }];
+ }];
+ TestWebKitAPI::Util::run(&done);
+}
+
#endif