Title: [222699] trunk/Source/WebCore
Revision
222699
Author
[email protected]
Date
2017-10-02 00:03:45 -0700 (Mon, 02 Oct 2017)

Log Message

Merge readFilenames() and read(PasteboardFileReader)
https://bugs.webkit.org/show_bug.cgi?id=177728
<rdar://problem/34761725>

Reviewed by Sam Weinig.

Generalized PasteboardFileReader to return multiple files instead of just one file, and replaced the use
of Pasteboard::readFilenames() with it. Because eliminates the need for finding the list of types to read
as files in addition to file names, this patch also removes Pasteboard::typesTreatedAsFiles().

Note that Pasteboard::readFilenames() continues to exist in macOS and iOS as it's internally used by
Pasteboard::read(PasteboardFileReader) in PasteboardCocoa.mm.

No new tests since there should be no behavioral change.

* dom/DataTransfer.cpp:
(WebCore::DataTransfer::files const): Now makes a single call to Pasteboard::read(PasteboardFileReader)
instead of reading filenames and then falling back to it. Also got rid of if-def for drag drop checks
since forDrag() and forFileDrag() are always defined since r222688.
(WebCore::PasteboardFileTypeReader): Added. Gets the list of all file types.
(WebCore::PasteboardFileTypeReader::readFilename): Added. Gets the list of all file types.
(WebCore::PasteboardFileTypeReader::readBuffer): Added. Gets the list of all file types.
(WebCore::DataTransfer::hasFileOfType): Reimplemented using PasteboardFileTypeReader.
* editing/WebCorePasteboardFileReader.cpp:
(WebCore::WebCorePasteboardFileReader::readFilename): Added.
(WebCore::WebCorePasteboardFileReader::readBuffer): Renamed from read.
* editing/WebCorePasteboardFileReader.h:
* platform/Pasteboard.h:
(WebCore::PasteboardFileReader): Removed the constructor since we no longer specify a specific type to
read off of pasteboard, and renamed the existing read function to readBuffer, and added a new variant
which takes a filename.
* platform/StaticPasteboard.h:
* platform/cocoa/PasteboardCocoa.mm:
(WebCore::imageTypeToFakeFilename): Return "image/png" for ImageType::TIFF (to do TIFF-to-PNG conversion;
see r222656 for why this is needed) now that this function is used to convert directly from image type
converted from cocoa type instead of the one reverse-converted from MIME type.
(WebCore::mimeTypeToImageType): Deleted.
(WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
(WebCore::Pasteboard::typesForLegacyUnsafeBindings): Use newly added readTypesWithSecurityCheck.
(WebCore::convertTIFFToPNG): Extracted out of read(PasteboardFileReader).
(WebCore::Pasteboard::read): Generalized to add filenames as well as image buffers as files. Because now
we're concerting Cocoa types to ImageType, we no longer have to detect when TIFF-as-PNG conversion is
happening here. We just treat ImageType::TIFF as PNG and do the conversion.
(WebCore::Pasteboard::readStringInCustomData): Use newly added readBufferForTypeWithSecurityCheck.
(WebCore::Pasteboard::readTypesWithSecurityCheck): Added.
(WebCore::Pasteboard::readBufferForTypeWithSecurityCheck): Added.
* platform/gtk/PasteboardGtk.cpp:
(WebCore::Pasteboard::read): Implemented.
(WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
(WebCore::Pasteboard::containsFiles): Implemented without calling readFilenames, which has been deleted.
(WebCore::Pasteboard::readFilenames): Deleted.
* platform/win/PasteboardWin.cpp:
(WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
(WebCore::PasteboardFileCounter): Added. Used to counts the number of files in the pasteboard.
(WebCore::PasteboardFileCounter::readFilename):
(WebCore::PasteboardFileCounter::readBuffer):
(WebCore::Pasteboard::containsFiles):
(WebCore::Pasteboard::read): Moved the code to extract filenames out of readFilenames.
(WebCore::Pasteboard::readFilenames): Deleted.
* platform/wpe/PasteboardWPE.cpp:
(WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
(WebCore::Pasteboard::readFilenames): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (222698 => 222699)


--- trunk/Source/WebCore/ChangeLog	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/ChangeLog	2017-10-02 07:03:45 UTC (rev 222699)
@@ -1,3 +1,68 @@
+2017-10-02  Ryosuke Niwa  <[email protected]>
+
+        Merge readFilenames() and read(PasteboardFileReader)
+        https://bugs.webkit.org/show_bug.cgi?id=177728
+        <rdar://problem/34761725>
+
+        Reviewed by Sam Weinig.
+
+        Generalized PasteboardFileReader to return multiple files instead of just one file, and replaced the use
+        of Pasteboard::readFilenames() with it. Because eliminates the need for finding the list of types to read
+        as files in addition to file names, this patch also removes Pasteboard::typesTreatedAsFiles().
+
+        Note that Pasteboard::readFilenames() continues to exist in macOS and iOS as it's internally used by
+        Pasteboard::read(PasteboardFileReader) in PasteboardCocoa.mm.
+
+        No new tests since there should be no behavioral change.
+
+        * dom/DataTransfer.cpp:
+        (WebCore::DataTransfer::files const): Now makes a single call to Pasteboard::read(PasteboardFileReader)
+        instead of reading filenames and then falling back to it. Also got rid of if-def for drag drop checks
+        since forDrag() and forFileDrag() are always defined since r222688.
+        (WebCore::PasteboardFileTypeReader): Added. Gets the list of all file types.
+        (WebCore::PasteboardFileTypeReader::readFilename): Added. Gets the list of all file types.
+        (WebCore::PasteboardFileTypeReader::readBuffer): Added. Gets the list of all file types.
+        (WebCore::DataTransfer::hasFileOfType): Reimplemented using PasteboardFileTypeReader.
+        * editing/WebCorePasteboardFileReader.cpp:
+        (WebCore::WebCorePasteboardFileReader::readFilename): Added.
+        (WebCore::WebCorePasteboardFileReader::readBuffer): Renamed from read.
+        * editing/WebCorePasteboardFileReader.h:
+        * platform/Pasteboard.h:
+        (WebCore::PasteboardFileReader): Removed the constructor since we no longer specify a specific type to
+        read off of pasteboard, and renamed the existing read function to readBuffer, and added a new variant
+        which takes a filename.
+        * platform/StaticPasteboard.h:
+        * platform/cocoa/PasteboardCocoa.mm:
+        (WebCore::imageTypeToFakeFilename): Return "image/png" for ImageType::TIFF (to do TIFF-to-PNG conversion;
+        see r222656 for why this is needed) now that this function is used to convert directly from image type
+        converted from cocoa type instead of the one reverse-converted from MIME type.
+        (WebCore::mimeTypeToImageType): Deleted.
+        (WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
+        (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Use newly added readTypesWithSecurityCheck.
+        (WebCore::convertTIFFToPNG): Extracted out of read(PasteboardFileReader).
+        (WebCore::Pasteboard::read): Generalized to add filenames as well as image buffers as files. Because now
+        we're concerting Cocoa types to ImageType, we no longer have to detect when TIFF-as-PNG conversion is
+        happening here. We just treat ImageType::TIFF as PNG and do the conversion.
+        (WebCore::Pasteboard::readStringInCustomData): Use newly added readBufferForTypeWithSecurityCheck.
+        (WebCore::Pasteboard::readTypesWithSecurityCheck): Added.
+        (WebCore::Pasteboard::readBufferForTypeWithSecurityCheck): Added.
+        * platform/gtk/PasteboardGtk.cpp:
+        (WebCore::Pasteboard::read): Implemented.
+        (WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
+        (WebCore::Pasteboard::containsFiles): Implemented without calling readFilenames, which has been deleted.
+        (WebCore::Pasteboard::readFilenames): Deleted.
+        * platform/win/PasteboardWin.cpp:
+        (WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
+        (WebCore::PasteboardFileCounter): Added. Used to counts the number of files in the pasteboard.
+        (WebCore::PasteboardFileCounter::readFilename):
+        (WebCore::PasteboardFileCounter::readBuffer):
+        (WebCore::Pasteboard::containsFiles):
+        (WebCore::Pasteboard::read): Moved the code to extract filenames out of readFilenames.
+        (WebCore::Pasteboard::readFilenames): Deleted.
+        * platform/wpe/PasteboardWPE.cpp:
+        (WebCore::Pasteboard::typesTreatedAsFiles): Deleted.
+        (WebCore::Pasteboard::readFilenames): Deleted.
+
 2017-10-01  Sam Weinig  <[email protected]>
 
         [Settings] Move remaining simple settings to Settings.in

Modified: trunk/Source/WebCore/dom/DataTransfer.cpp (222698 => 222699)


--- trunk/Source/WebCore/dom/DataTransfer.cpp	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/dom/DataTransfer.cpp	2017-10-02 07:03:45 UTC (rev 222699)
@@ -182,47 +182,50 @@
 
 FileList& DataTransfer::files() const
 {
-    bool newlyCreatedFileList = !m_fileList;
-    if (!m_fileList)
-        m_fileList = FileList::create();
-
     if (!canReadData()) {
-        m_fileList->clear();
+        if (m_fileList)
+            m_fileList->clear();
+        else
+            m_fileList = FileList::create();
         return *m_fileList;
     }
 
-#if ENABLE(DRAG_SUPPORT)
     if (forDrag() && !forFileDrag()) {
-        ASSERT(m_fileList->isEmpty());
+        if (m_fileList)
+            ASSERT(m_fileList->isEmpty());
+        else
+            m_fileList = FileList::create();
         return *m_fileList;
     }
-#endif
 
-    if (newlyCreatedFileList) {
-        for (auto& filename : m_pasteboard->readFilenames())
-            m_fileList->append(File::create(filename));
-        if (m_fileList->isEmpty()) {
-            for (auto& type : m_pasteboard->typesTreatedAsFiles()) {
-                WebCorePasteboardFileReader reader(type);
-                m_pasteboard->read(reader);
-                if (reader.file)
-                    m_fileList->append(reader.file.releaseNonNull());
-            }
-        }
+    if (!m_fileList) {
+        WebCorePasteboardFileReader reader;
+        m_pasteboard->read(reader);
+        m_fileList = FileList::create(WTFMove(reader.files));
     }
     return *m_fileList;
 }
 
+struct PasteboardFileTypeReader final : PasteboardFileReader {
+    void readFilename(const String& filename)
+    {
+        types.add(File::contentTypeForFile(filename));
+    }
+
+    void readBuffer(const String&, const String& type, Ref<SharedBuffer>&&)
+    {
+        types.add(type);
+    }
+
+    HashSet<String, ASCIICaseInsensitiveHash> types;
+};
+
 bool DataTransfer::hasFileOfType(const String& type)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(canReadTypes());
-
-    for (auto& path : m_pasteboard->readFilenames()) {
-        if (equalIgnoringASCIICase(File::contentTypeForFile(path), type))
-            return true;
-    }
-
-    return false;
+    PasteboardFileTypeReader reader;
+    m_pasteboard->read(reader);
+    return reader.types.contains(type);
 }
 
 bool DataTransfer::hasStringOfType(const String& type)

Modified: trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp (222698 => 222699)


--- trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp	2017-10-02 07:03:45 UTC (rev 222699)
@@ -33,11 +33,16 @@
 
 WebCorePasteboardFileReader::~WebCorePasteboardFileReader() = default;
 
-void WebCorePasteboardFileReader::read(const String& filename, Ref<SharedBuffer>&& buffer)
+void WebCorePasteboardFileReader::readFilename(const String& filename)
 {
+    files.append(File::create(filename));
+}
+
+void WebCorePasteboardFileReader::readBuffer(const String& filename, const String& type, Ref<SharedBuffer>&& buffer)
+{
     Vector<uint8_t> data;
     data.append(buffer->data(), buffer->size());
-    file = File::create(Blob::create(WTFMove(data), type), filename);
+    files.append(File::create(Blob::create(WTFMove(data), type), filename));
 }
 
 }

Modified: trunk/Source/WebCore/editing/WebCorePasteboardFileReader.h (222698 => 222699)


--- trunk/Source/WebCore/editing/WebCorePasteboardFileReader.h	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/editing/WebCorePasteboardFileReader.h	2017-10-02 07:03:45 UTC (rev 222699)
@@ -32,15 +32,12 @@
 class File;
 
 struct WebCorePasteboardFileReader final : PasteboardFileReader {
-    WebCorePasteboardFileReader(const String& type)
-        : PasteboardFileReader(type)
-    { }
-
     ~WebCorePasteboardFileReader();
 
-    void read(const String&, Ref<SharedBuffer>&&) final;
+    void readFilename(const String&) final;
+    void readBuffer(const String& filename, const String& type, Ref<SharedBuffer>&&) final;
 
-    RefPtr<File> file;
+    Vector<Ref<File>> files;
 };
 
 }

Modified: trunk/Source/WebCore/platform/Pasteboard.h (222698 => 222699)


--- trunk/Source/WebCore/platform/Pasteboard.h	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/platform/Pasteboard.h	2017-10-02 07:03:45 UTC (rev 222699)
@@ -58,6 +58,7 @@
 class DragData;
 class Element;
 class Frame;
+class PasteboardStrategy;
 class Range;
 class SelectionData;
 class SharedBuffer;
@@ -148,14 +149,9 @@
 };
 
 struct PasteboardFileReader {
-    PasteboardFileReader(const String& type)
-        : type(type)
-    { }
     virtual ~PasteboardFileReader() = default;
-
-    virtual void read(const String&, Ref<SharedBuffer>&&) = 0;
-
-    const String type;
+    virtual void readFilename(const String&) = 0;
+    virtual void readBuffer(const String& filename, const String& type, Ref<SharedBuffer>&&) = 0;
 };
 
 // FIXME: We need to ensure that the contents of sameOriginCustomData are not accessible across different origins.
@@ -198,7 +194,6 @@
     virtual bool hasData();
     virtual Vector<String> typesSafeForBindings();
     virtual Vector<String> typesForLegacyUnsafeBindings();
-    virtual Vector<String> typesTreatedAsFiles();
     virtual String readString(const String& type);
     virtual String readStringInCustomData(const String& type);
 
@@ -216,7 +211,6 @@
     virtual void write(const PasteboardWebContent&);
 
     virtual bool containsFiles();
-    virtual Vector<String> readFilenames();
     virtual bool canSmartReplace();
 
     virtual void writeMarkup(const String& markup);
@@ -282,9 +276,12 @@
 #endif
 
 #if PLATFORM(COCOA)
+    Vector<String> readFilenames();
     String readPlatformValueAsString(const String& domType, long changeCount, const String& pasteboardName);
     static void addHTMLClipboardTypesForCocoaType(ListHashSet<String>& resultTypes, const String& cocoaType, const String& pasteboardName);
     String readStringForPlatformType(const String&);
+    Vector<String> readTypesWithSecurityCheck();
+    RefPtr<SharedBuffer> readBufferForTypeWithSecurityCheck(const String&);
 #endif
 
 #if PLATFORM(GTK)

Modified: trunk/Source/WebCore/platform/StaticPasteboard.h (222698 => 222699)


--- trunk/Source/WebCore/platform/StaticPasteboard.h	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/platform/StaticPasteboard.h	2017-10-02 07:03:45 UTC (rev 222699)
@@ -43,7 +43,6 @@
     bool hasData() final;
     Vector<String> typesSafeForBindings() final { return m_types; }
     Vector<String> typesForLegacyUnsafeBindings() final { return m_types; }
-    Vector<String> typesTreatedAsFiles() final { return { }; }
     String readString(const String& type) final;
     String readStringInCustomData(const String& type) final;
 
@@ -59,7 +58,6 @@
     void write(const PasteboardWebContent&) final { }
 
     bool containsFiles() final { return false; }
-    Vector<String> readFilenames() final { return { }; }
     bool canSmartReplace() final { return false; }
 
     void writeMarkup(const String&) final { }

Modified: trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm (222698 => 222699)


--- trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm	2017-10-02 07:03:45 UTC (rev 222699)
@@ -72,6 +72,8 @@
     return ImageType::Invalid;
 }
 
+// String literals returned by this function must be defined exactly once
+// since read(PasteboardFileReader&) uses HashMap<const char*> to check uniqueness.
 static const char* imageTypeToMIMEType(ImageType type)
 {
     switch (type) {
@@ -81,7 +83,7 @@
 #if PLATFORM(MAC)
         return "image/png"; // For Web compatibility, we pretend to have PNG instead.
 #else
-        return nullptr; // Don't support TIFF on iOS for now.
+        return nullptr; // Don't support pasting TIFF on iOS for now.
 #endif
     case ImageType::PNG:
         return "image/png";
@@ -99,8 +101,12 @@
         ASSERT_NOT_REACHED();
         return nullptr;
     case ImageType::TIFF:
+#if PLATFORM(MAC)
+        return "image/png"; // For Web compatibility, we pretend to have PNG instead.
+#else
         ASSERT_NOT_REACHED();
         return nullptr;
+#endif
     case ImageType::PNG:
         return "image.png";
     case ImageType::JPEG:
@@ -110,47 +116,11 @@
     }
 }
 
-static ImageType mimeTypeToImageType(const String& mimeType)
-{
-#if PLATFORM(MAC)
-    if (mimeType == "image/tiff")
-        return ImageType::TIFF;
-#endif
-    if (mimeType == "image/png")
-        return ImageType::PNG;
-    if (mimeType == "image/jpeg")
-        return ImageType::JPEG;
-    if (mimeType == "image/gif")
-        return ImageType::GIF;
-    return ImageType::Invalid;
-}
-
 bool Pasteboard::shouldTreatCocoaTypeAsFile(const String& cocoaType)
 {
     return cocoaTypeToImageType(cocoaType) != ImageType::Invalid;
 }
 
-Vector<String> Pasteboard::typesTreatedAsFiles()
-{
-    Vector<String> cocoaTypes;
-    platformStrategies()->pasteboardStrategy()->getTypes(cocoaTypes, m_pasteboardName);
-
-    // Enforce changeCount ourselves for security. We check after reading instead of before to be
-    // sure it doesn't change between our testing the change count and accessing the data.
-    if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
-        return { };
-
-    ListHashSet<String> result;
-    for (auto& cocoaType : cocoaTypes) {
-        if (auto* mimeType = imageTypeToMIMEType(cocoaTypeToImageType(cocoaType)))
-            result.add(mimeType);
-    }
-
-    Vector<String> types;
-    copyToVector(result, types);
-    return types;
-}
-
 bool Pasteboard::containsFiles()
 {
     if (!platformStrategies()->pasteboardStrategy()->getNumberOfFiles(m_pasteboardName)) {
@@ -182,63 +152,55 @@
 
 Vector<String> Pasteboard::typesForLegacyUnsafeBindings()
 {
-    Vector<String> types;
-    platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
+    auto cocoaTypes = readTypesWithSecurityCheck();
+    if (cocoaTypes.isEmpty())
+        return cocoaTypes;
 
-    // Enforce changeCount ourselves for security. We check after reading instead of before to be
-    // sure it doesn't change between our testing the change count and accessing the data.
-    if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
-        return { };
-
     ListHashSet<String> result;
-    for (auto& cocoaType : types)
+    for (auto& cocoaType : cocoaTypes)
         addHTMLClipboardTypesForCocoaType(result, cocoaType, m_pasteboardName);
 
+    Vector<String> types;
     copyToVector(result, types);
     return types;
 }
 
+#if PLATFORM(MAC)
+static Ref<SharedBuffer> convertTIFFToPNG(SharedBuffer& tiffBuffer)
+{
+    auto image = adoptNS([[NSBitmapImageRep alloc] initWithData: tiffBuffer.createNSData().get()]);
+    NSData *pngData = [image representationUsingType:NSPNGFileType properties:@{ }];
+    return SharedBuffer::create(pngData);
+}
+#endif
+
 void Pasteboard::read(PasteboardFileReader& reader)
 {
-    auto imageType = mimeTypeToImageType(reader.type);
-    if (imageType == ImageType::Invalid)
+    auto filenames = readFilenames();
+    if (!filenames.isEmpty()) {
+        for (auto& filename : filenames)
+            reader.readFilename(filename);
         return;
+    }
 
-    String cocoaTypeToRead;
-    String tiffCocoaTypeInPasteboard;
-    Vector<String> cocoaTypes;
-    platformStrategies()->pasteboardStrategy()->getTypes(cocoaTypes, m_pasteboardName);
+    auto cocoaTypes = readTypesWithSecurityCheck();
+    HashSet<const char*> existingMIMEs;
     for (auto& cocoaType : cocoaTypes) {
-        auto imageTypeInPasteboard = cocoaTypeToImageType(cocoaType);
-        if (imageTypeInPasteboard == imageType) {
-            cocoaTypeToRead = cocoaType;
-            break;
-        }
-        if (tiffCocoaTypeInPasteboard.isNull() && imageTypeInPasteboard == ImageType::TIFF)
-            tiffCocoaTypeInPasteboard = cocoaType;
-    }
-
-    bool tiffWasTreatedAsPNGForWebCompatibility = imageType == ImageType::PNG && cocoaTypeToRead.isNull() && !tiffCocoaTypeInPasteboard.isNull();
-    if (tiffWasTreatedAsPNGForWebCompatibility)
-        cocoaTypeToRead = tiffCocoaTypeInPasteboard;
-
-    RefPtr<SharedBuffer> buffer = platformStrategies()->pasteboardStrategy()->bufferForType(cocoaTypeToRead, m_pasteboardName);
-
-    // Enforce changeCount ourselves for security. We check after reading instead of before to be
-    // sure it doesn't change between our testing the change count and accessing the data.
-    if (!buffer || m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
-        return;
-
+        auto imageType = cocoaTypeToImageType(cocoaType);
+        const char* mimeType = imageTypeToMIMEType(imageType);
+        if (!mimeType)
+            continue;
+        if (!existingMIMEs.add(mimeType).isNewEntry)
+            continue;
+        auto buffer = readBufferForTypeWithSecurityCheck(cocoaType);
 #if PLATFORM(MAC)
-    if (tiffWasTreatedAsPNGForWebCompatibility) {
-        auto tiffData = buffer->createNSData();
-        auto image = adoptNS([[NSBitmapImageRep alloc] initWithData: tiffData.get()]);
-        NSData *pngData = [image representationUsingType:NSPNGFileType properties:@{ }];
-        reader.read(imageTypeToFakeFilename(imageType), SharedBuffer::create(pngData));
-        return;
+        if (buffer && imageType == ImageType::TIFF)
+            buffer = convertTIFFToPNG(buffer.releaseNonNull());
+#endif
+        if (!buffer)
+            continue;
+        reader.readBuffer(imageTypeToFakeFilename(imageType), mimeType, buffer.releaseNonNull());
     }
-#endif
-    reader.read(imageTypeToFakeFilename(imageType), buffer.releaseNonNull());
 }
 
 String Pasteboard::readString(const String& type)
@@ -248,14 +210,16 @@
 
 String Pasteboard::readStringInCustomData(const String& type)
 {
-    auto buffer = platformStrategies()->pasteboardStrategy()->bufferForType(customWebKitPasteboardDataType, m_pasteboardName);
+    auto buffer = readBufferForTypeWithSecurityCheck(customWebKitPasteboardDataType);
     if (!buffer)
         return { };
 
-    NSString *customDataValue = customDataFromSharedBuffer(*buffer).sameOriginCustomData.get(type);
-    if (!customDataValue.length)
+    // Enforce changeCount ourselves for security. We check after reading instead of before to be
+    // sure it doesn't change between our testing the change count and accessing the data.
+    if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
         return { };
-    return customDataValue;
+
+    return customDataFromSharedBuffer(*buffer).sameOriginCustomData.get(type);
 }
 
 void Pasteboard::writeCustomData(const PasteboardCustomData& data)
@@ -268,5 +232,29 @@
     return platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName);
 }
 
+Vector<String> Pasteboard::readTypesWithSecurityCheck()
+{
+    Vector<String> cocoaTypes;
+    platformStrategies()->pasteboardStrategy()->getTypes(cocoaTypes, m_pasteboardName);
+
+    // Enforce changeCount ourselves for security. We check after reading instead of before to be
+    // sure it doesn't change between our testing the change count and accessing the data.
+    if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
+        return { };
+
+    return cocoaTypes;
 }
 
+RefPtr<SharedBuffer> Pasteboard::readBufferForTypeWithSecurityCheck(const String& type)
+{
+    auto buffer = platformStrategies()->pasteboardStrategy()->bufferForType(type, m_pasteboardName);
+
+    // Enforce changeCount ourselves for security. We check after reading instead of before to be
+    // sure it doesn't change between our testing the change count and accessing the data.
+    if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
+        return nullptr;
+
+    return buffer;
+}
+
+}

Modified: trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp (222698 => 222699)


--- trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp	2017-10-02 07:03:45 UTC (rev 222699)
@@ -242,8 +242,11 @@
 {
 }
 
-void Pasteboard::read(PasteboardFileReader&)
+void Pasteboard::read(PasteboardFileReader& reader)
 {
+    readFromClipboard();
+    for (auto& filename : m_selectionData->filenames())
+        reader.readFilename(filename);
 }
 
 bool Pasteboard::hasData()
@@ -286,11 +289,6 @@
     return types;
 }
 
-Vector<String> Pasteboard::typesTreatedAsFiles()
-{
-    return { };
-}
-
 String Pasteboard::readString(const String& type)
 {
     readFromClipboard();
@@ -321,13 +319,8 @@
 
 bool Pasteboard::containsFiles()
 {
-    return readFilenames().size();
-}
-
-Vector<String> Pasteboard::readFilenames()
-{
     readFromClipboard();
-    return m_selectionData->filenames();
+    return !m_selectionData->filenames().isEmpty();
 }
 
 void Pasteboard::writeMarkup(const String&)

Modified: trunk/Source/WebCore/platform/win/PasteboardWin.cpp (222698 => 222699)


--- trunk/Source/WebCore/platform/win/PasteboardWin.cpp	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/platform/win/PasteboardWin.cpp	2017-10-02 07:03:45 UTC (rev 222699)
@@ -283,11 +283,6 @@
     return vector;
 }
 
-Vector<String> Pasteboard::typesTreatedAsFiles()
-{
-    return { };
-}
-
 String Pasteboard::readString(const String& type)
 {
     if (!m_dataObject && m_dragDataMap.isEmpty())
@@ -314,24 +309,32 @@
     return { };
 }
 
+struct PasteboardFileCounter final : PasteboardFileReader {
+    void readFilename(const String&) final { ++count; }
+    void readBuffer(const String&, const String&, Ref<SharedBuffer>&&) final { ++count; }
+
+    unsigned count { 0 };
+};
+
 bool Pasteboard::containsFiles()
 {
-    return readFilenames().size(); // FIXME: Make this code more efficient.
+    // FIXME: This implementation can be slightly more efficient by avoiding calls to DragQueryFileW.
+    PasteboardFileCounter reader;
+    read(reader);
+    return reader.count;
 }
 
-Vector<String> Pasteboard::readFilenames()
+void Pasteboard::read(PasteboardFileReader& reader)
 {
-    Vector<String> fileNames;
-
 #if USE(CF)
     if (m_dataObject) {
         STGMEDIUM medium;
         if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium)))
-            return fileNames;
+            return;
 
         HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
         if (!hdrop)
-            return fileNames;
+            return;
 
         WCHAR filename[MAX_PATH];
         UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
@@ -338,19 +341,22 @@
         for (UINT i = 0; i < fileCount; i++) {
             if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
                 continue;
-            fileNames.append(filename);
+            reader.readFilename(filename);
         }
 
         GlobalUnlock(medium.hGlobal);
         ReleaseStgMedium(&medium);
-        return fileNames;
+        return;
     }
-    if (!m_dragDataMap.contains(cfHDropFormat()->cfFormat))
-        return fileNames;
-    return m_dragDataMap.get(cfHDropFormat()->cfFormat);
+    auto list = m_dragDataMap.find(cfHDropFormat()->cfFormat);
+    if (list == m_dragDataMap.end())
+        return;
+
+    for (auto& filename : list->value)
+        reader.readFilename(filename);
 #else
     notImplemented();
-    return fileNames;
+    return { };
 #endif
 }
 
@@ -1072,10 +1078,6 @@
 {
 }
 
-void Pasteboard::read(PasteboardFileReader&)
-{
-}
-
 void Pasteboard::write(const PasteboardImage&)
 {
 }

Modified: trunk/Source/WebCore/platform/wpe/PasteboardWPE.cpp (222698 => 222699)


--- trunk/Source/WebCore/platform/wpe/PasteboardWPE.cpp	2017-10-02 06:02:52 UTC (rev 222698)
+++ trunk/Source/WebCore/platform/wpe/PasteboardWPE.cpp	2017-10-02 07:03:45 UTC (rev 222699)
@@ -62,11 +62,6 @@
     return types;
 }
 
-Vector<String> Pasteboard::typesTreatedAsFiles()
-{
-    return { };
-}
-
 String Pasteboard::readString(const String& type)
 {
     return platformStrategies()->pasteboardStrategy()->readStringFromPasteboard(0, type);
@@ -130,12 +125,6 @@
     return false;
 }
 
-Vector<String> Pasteboard::readFilenames()
-{
-    notImplemented();
-    return Vector<String>();
-}
-
 bool Pasteboard::canSmartReplace()
 {
     return false;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to