Files from drag and file <input> should use getMIMETypeForExtension to determine...
authordcheng@chromium.org <dcheng@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jul 2012 18:17:44 +0000 (18:17 +0000)
committerdcheng@chromium.org <dcheng@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jul 2012 18:17:44 +0000 (18:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91702

Reviewed by Jian Li.

Awhile back, we changed File to only use getWellKnownMIMETypeForExtension to prevent web
pages from being able to detect what applications a user has installed indirectly through
the MIME types. However, some sites like YouTube's drag and drop uploader use MIME types
that aren't in WebKit's internal list, so we relax the restriction for Files that originate
from an user action.

* fileapi/File.cpp:
(WebCore::getContentTypeFromFileName):
(WebCore::createBlobDataForFile):
(WebCore::createBlobDataForFileWithName):
(WebCore::createBlobDataForFileWithMetadata):
(WebCore::File::createWithRelativePath):
(WebCore::File::File):
* fileapi/File.h:
(File):
(WebCore::File::create):
(WebCore::File::createWithName):
* html/FileInputType.cpp:
(WebCore::FileInputType::createFileList):
* platform/chromium/ChromiumDataObject.cpp:
(WebCore::ChromiumDataObject::addFilename):
* platform/gtk/ClipboardGtk.cpp:
(WebCore::ClipboardGtk::files):
* platform/mac/ClipboardMac.mm:
(WebCore::ClipboardMac::files):
* platform/qt/ClipboardQt.cpp:
(WebCore::ClipboardQt::files):
* platform/win/ClipboardWin.cpp:
(WebCore::ClipboardWin::files):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@123495 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/fileapi/File.cpp
Source/WebCore/fileapi/File.h
Source/WebCore/html/FileInputType.cpp
Source/WebCore/platform/chromium/ChromiumDataObject.cpp
Source/WebCore/platform/gtk/ClipboardGtk.cpp
Source/WebCore/platform/mac/ClipboardMac.mm
Source/WebCore/platform/qt/ClipboardQt.cpp
Source/WebCore/platform/win/ClipboardWin.cpp

index c0ed609..1435691 100644 (file)
@@ -1,3 +1,40 @@
+2012-07-24  Daniel Cheng  <dcheng@chromium.org>
+
+        Files from drag and file <input> should use getMIMETypeForExtension to determine content type.
+        https://bugs.webkit.org/show_bug.cgi?id=91702
+
+        Reviewed by Jian Li.
+
+        Awhile back, we changed File to only use getWellKnownMIMETypeForExtension to prevent web
+        pages from being able to detect what applications a user has installed indirectly through
+        the MIME types. However, some sites like YouTube's drag and drop uploader use MIME types
+        that aren't in WebKit's internal list, so we relax the restriction for Files that originate
+        from an user action.
+
+        * fileapi/File.cpp:
+        (WebCore::getContentTypeFromFileName):
+        (WebCore::createBlobDataForFile):
+        (WebCore::createBlobDataForFileWithName):
+        (WebCore::createBlobDataForFileWithMetadata):
+        (WebCore::File::createWithRelativePath):
+        (WebCore::File::File):
+        * fileapi/File.h:
+        (File):
+        (WebCore::File::create):
+        (WebCore::File::createWithName):
+        * html/FileInputType.cpp:
+        (WebCore::FileInputType::createFileList):
+        * platform/chromium/ChromiumDataObject.cpp:
+        (WebCore::ChromiumDataObject::addFilename):
+        * platform/gtk/ClipboardGtk.cpp:
+        (WebCore::ClipboardGtk::files):
+        * platform/mac/ClipboardMac.mm:
+        (WebCore::ClipboardMac::files):
+        * platform/qt/ClipboardQt.cpp:
+        (WebCore::ClipboardQt::files):
+        * platform/win/ClipboardWin.cpp:
+        (WebCore::ClipboardWin::files):
+
 2012-07-24  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Web Inspector: Snippets UI polish
index 5f8b93b..0878957 100644 (file)
 
 namespace WebCore {
 
-static String getContentTypeFromFileName(const String& name)
+static String getContentTypeFromFileName(const String& name, File::ContentTypeLookupPolicy policy)
 {
     String type;
     int index = name.reverseFind('.');
-    if (index != -1)
-        type = MIMETypeRegistry::getWellKnownMIMETypeForExtension(name.substring(index + 1));
+    if (index != -1) {
+        if (policy == File::WellKnownContentTypes)
+            type = MIMETypeRegistry::getWellKnownMIMETypeForExtension(name.substring(index + 1));
+        else {
+            ASSERT(policy == File::AllContentTypes);
+            type = MIMETypeRegistry::getMIMETypeForExtension(name.substring(index + 1));
+        }
+    }
     return type;
 }
 
@@ -51,21 +57,21 @@ static PassOwnPtr<BlobData> createBlobDataForFileWithType(const String& path, co
     return blobData.release();
 }
 
-static PassOwnPtr<BlobData> createBlobDataForFile(const String& path)
+static PassOwnPtr<BlobData> createBlobDataForFile(const String& path, File::ContentTypeLookupPolicy policy)
 {
-    return createBlobDataForFileWithType(path, getContentTypeFromFileName(path));
+    return createBlobDataForFileWithType(path, getContentTypeFromFileName(path, policy));
 }
 
-static PassOwnPtr<BlobData> createBlobDataForFileWithName(const String& path, const String& fileSystemName)
+static PassOwnPtr<BlobData> createBlobDataForFileWithName(const String& path, const String& fileSystemName, File::ContentTypeLookupPolicy policy)
 {
-    return createBlobDataForFileWithType(path, getContentTypeFromFileName(fileSystemName));
+    return createBlobDataForFileWithType(path, getContentTypeFromFileName(fileSystemName, policy));
 }
 
 #if ENABLE(FILE_SYSTEM)
 static PassOwnPtr<BlobData> createBlobDataForFileWithMetadata(const String& fileSystemName, const FileMetadata& metadata)
 {
     OwnPtr<BlobData> blobData = BlobData::create();
-    blobData->setContentType(getContentTypeFromFileName(fileSystemName));
+    blobData->setContentType(getContentTypeFromFileName(fileSystemName, File::WellKnownContentTypes));
     blobData->appendFile(metadata.platformPath, 0, metadata.length, metadata.modificationTime);
     return blobData.release();
 }
@@ -74,14 +80,14 @@ static PassOwnPtr<BlobData> createBlobDataForFileWithMetadata(const String& file
 #if ENABLE(DIRECTORY_UPLOAD)
 PassRefPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
 {
-    RefPtr<File> file = adoptRef(new File(path));
+    RefPtr<File> file = adoptRef(new File(path, AllContentTypes));
     file->m_relativePath = relativePath;
     return file.release();
 }
 #endif
 
-File::File(const String& path)
-    : Blob(createBlobDataForFile(path), -1)
+File::File(const String& path, ContentTypeLookupPolicy policy)
+    : Blob(createBlobDataForFile(path, policy), -1)
     , m_path(path)
     , m_name(pathGetFileName(path))
 #if ENABLE(FILE_SYSTEM)
@@ -105,8 +111,8 @@ File::File(const String& path, const KURL& url, const String& type)
     // See SerializedScriptValue.cpp for js and v8.
 }
 
-File::File(const String& path, const String& name)
-    : Blob(createBlobDataForFileWithName(path, name), -1)
+File::File(const String& path, const String& name, ContentTypeLookupPolicy policy)
+    : Blob(createBlobDataForFileWithName(path, name, policy), -1)
     , m_path(path)
     , m_name(name)
 #if ENABLE(FILE_SYSTEM)
index e3ca2a5..864c438 100644 (file)
@@ -38,9 +38,16 @@ class KURL;
 
 class File : public Blob {
 public:
-    static PassRefPtr<File> create(const String& path)
+    // AllContentTypes should only be used when the full path/name are trusted; otherwise, it could
+    // allow arbitrary pages to determine what applications an user has installed.
+    enum ContentTypeLookupPolicy {
+        WellKnownContentTypes,
+        AllContentTypes,
+    };
+
+    static PassRefPtr<File> create(const String& path, ContentTypeLookupPolicy policy = WellKnownContentTypes)
     {
-        return adoptRef(new File(path));
+        return adoptRef(new File(path, policy));
     }
 
     // For deserialization.
@@ -64,11 +71,11 @@ public:
 #endif
 
     // Create a file with a name exposed to the author (via File.name and associated DOM properties) that differs from the one provided in the path.
-    static PassRefPtr<File> createWithName(const String& path, const String& name)
+    static PassRefPtr<File> createWithName(const String& path, const String& name, ContentTypeLookupPolicy policy = WellKnownContentTypes)
     {
         if (name.isEmpty())
-            return adoptRef(new File(path));
-        return adoptRef(new File(path, name));
+            return adoptRef(new File(path, policy));
+        return adoptRef(new File(path, name, policy));
     }
 
     virtual unsigned long long size() const;
@@ -89,11 +96,11 @@ public:
     void captureSnapshot(long long& snapshotSize, double& snapshotModificationTime) const;
 
 private:
-    File(const String& path);
+    File(const String& path, ContentTypeLookupPolicy);
 
     // For deserialization.
     File(const String& path, const KURL& srcURL, const String& type);
-    File(const String& path, const String& name);
+    File(const String& path, const String& name, ContentTypeLookupPolicy);
 
 # if ENABLE(FILE_SYSTEM)
     File(const String& name, const FileMetadata&);
index 7a75e13..d08fe24 100644 (file)
@@ -284,7 +284,7 @@ PassRefPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileI
 #endif
 
     for (size_t i = 0; i < size; i++)
-        fileList->append(File::createWithName(files[i].path, files[i].displayName));
+        fileList->append(File::createWithName(files[i].path, files[i].displayName, File::AllContentTypes));
     return fileList;
 }
 
index 50383b6..ec7eebe 100644 (file)
@@ -209,7 +209,7 @@ Vector<String> ChromiumDataObject::filenames() const
 
 void ChromiumDataObject::addFilename(const String& filename, const String& displayName)
 {
-    internalAddFileItem(ChromiumDataObjectItem::createFromFile(File::createWithName(filename, displayName)));
+    internalAddFileItem(ChromiumDataObjectItem::createFromFile(File::createWithName(filename, displayName, File::AllContentTypes)));
 }
 
 void ChromiumDataObject::addSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
index b22adf4..891126d 100644 (file)
@@ -224,7 +224,7 @@ PassRefPtr<FileList> ClipboardGtk::files() const
     RefPtr<FileList> fileList = FileList::create();
     const Vector<String>& filenames = m_dataObject->filenames();
     for (size_t i = 0; i < filenames.size(); i++)
-        fileList->append(File::create(filenames[i]));
+        fileList->append(File::create(filenames[i], File::AllContentTypes));
     return fileList.release();
 }
 
index 20ec2fb..7004d23 100644 (file)
@@ -321,7 +321,7 @@ PassRefPtr<FileList> ClipboardMac::files() const
     for (size_t i = 0; i < absoluteURLs.size(); i++) {
         NSURL *absoluteURL = [NSURL URLWithString:absoluteURLs[i]];
         ASSERT([absoluteURL isFileURL]);
-        fileList->append(File::create([absoluteURL path]));
+        fileList->append(File::create([absoluteURL path], File::AllContentTypes));
     }
     return fileList.release(); // We will always return a FileList, sometimes empty
 }
index 8e4c580..8edbbe3 100644 (file)
@@ -208,7 +208,7 @@ PassRefPtr<FileList> ClipboardQt::files() const
         QUrl url = urls[i];
         if (url.scheme() != QLatin1String("file"))
             continue;
-        fileList->append(File::create(url.toLocalFile()));
+        fileList->append(File::create(url.toLocalFile(), File::AllContentTypes));
     }
 
     return fileList.release();
index 12cb8bf..d1c1386 100644 (file)
@@ -560,7 +560,7 @@ PassRefPtr<FileList> ClipboardWin::files() const
         for (UINT i = 0; i < fileCount; i++) {
             if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
                 continue;
-            files->append(File::create(reinterpret_cast<UChar*>(filename)));
+            files->append(File::create(reinterpret_cast<UChar*>(filename), File::AllContentTypes));
         }
 
         GlobalUnlock(medium.hGlobal);