Chromium Code Reviews

Side by Side Diff: ui/base/dragdrop/os_exchange_data_provider_win.cc

Issue 7778008: Truncate file name longer than MAX_PATH(260) on D2D (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Handle too long file extension Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" 5 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
6 6
7 #include <algorithm>
8 #include <vector>
9
7 #include "base/file_path.h" 10 #include "base/file_path.h"
8 #include "base/i18n/file_util_icu.h" 11 #include "base/i18n/file_util_icu.h"
9 #include "base/logging.h" 12 #include "base/logging.h"
10 #include "base/memory/scoped_handle.h" 13 #include "base/memory/scoped_handle.h"
11 #include "base/pickle.h" 14 #include "base/pickle.h"
12 #include "base/stl_util.h" 15 #include "base/stl_util.h"
13 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
14 #include "base/win/scoped_hglobal.h" 17 #include "base/win/scoped_hglobal.h"
15 #include "googleurl/src/gurl.h" 18 #include "googleurl/src/gurl.h"
16 #include "grit/ui_strings.h" 19 #include "grit/ui_strings.h"
(...skipping 100 matching lines...)
117 } 120 }
118 121
119 FormatEtcEnumerator::~FormatEtcEnumerator() { 122 FormatEtcEnumerator::~FormatEtcEnumerator() {
120 STLDeleteContainerPointers(contents_.begin(), contents_.end()); 123 STLDeleteContainerPointers(contents_.begin(), contents_.end());
121 } 124 }
122 125
123 STDMETHODIMP FormatEtcEnumerator::Next( 126 STDMETHODIMP FormatEtcEnumerator::Next(
124 ULONG count, FORMATETC* elements_array, ULONG* elements_fetched) { 127 ULONG count, FORMATETC* elements_array, ULONG* elements_fetched) {
125 // MSDN says |elements_fetched| is allowed to be NULL if count is 1. 128 // MSDN says |elements_fetched| is allowed to be NULL if count is 1.
126 if (!elements_fetched) 129 if (!elements_fetched)
127 DCHECK(count == 1); 130 DCHECK_EQ(count, 1ul);
128 131
129 // This method copies count elements into |elements_array|. 132 // This method copies count elements into |elements_array|.
130 ULONG index = 0; 133 ULONG index = 0;
131 while (cursor_ < contents_.size() && index < count) { 134 while (cursor_ < contents_.size() && index < count) {
132 CloneFormatEtc(contents_[cursor_], &elements_array[index]); 135 CloneFormatEtc(contents_[cursor_], &elements_array[index]);
133 ++cursor_; 136 ++cursor_;
134 ++index; 137 ++index;
135 } 138 }
136 // The out param is for how many we actually copied. 139 // The out param is for how many we actually copied.
137 if (elements_fetched) 140 if (elements_fetched)
(...skipping 258 matching lines...)
396 bool OSExchangeDataProviderWin::GetPickledData(CLIPFORMAT format, 399 bool OSExchangeDataProviderWin::GetPickledData(CLIPFORMAT format,
397 Pickle* data) const { 400 Pickle* data) const {
398 DCHECK(data); 401 DCHECK(data);
399 FORMATETC format_etc = 402 FORMATETC format_etc =
400 { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 403 { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
401 bool success = false; 404 bool success = false;
402 STGMEDIUM medium; 405 STGMEDIUM medium;
403 if (SUCCEEDED(source_object_->GetData(&format_etc, &medium))) { 406 if (SUCCEEDED(source_object_->GetData(&format_etc, &medium))) {
404 if (medium.tymed & TYMED_HGLOBAL) { 407 if (medium.tymed & TYMED_HGLOBAL) {
405 base::win::ScopedHGlobal<char> c_data(medium.hGlobal); 408 base::win::ScopedHGlobal<char> c_data(medium.hGlobal);
406 DCHECK(c_data.Size() > 0); 409 DCHECK_GT(c_data.Size(), static_cast<size_t>(0));
sky 2011/09/08 17:25:46 0u
yosin_UTC9 2011/09/09 04:25:41 Done.
407 // Need to subtract 1 as SetPickledData adds an extra byte to the end. 410 // Need to subtract 1 as SetPickledData adds an extra byte to the end.
408 *data = Pickle(c_data.get(), static_cast<int>(c_data.Size() - 1)); 411 *data = Pickle(c_data.get(), static_cast<int>(c_data.Size() - 1));
409 success = true; 412 success = true;
410 } 413 }
411 ReleaseStgMedium(&medium); 414 ReleaseStgMedium(&medium);
412 } 415 }
413 return success; 416 return success;
414 } 417 }
415 418
416 bool OSExchangeDataProviderWin::GetFileContents( 419 bool OSExchangeDataProviderWin::GetFileContents(
(...skipping 465 matching lines...)
882 static const size_t max_length = MAX_PATH - arraysize(extension); 885 static const size_t max_length = MAX_PATH - arraysize(extension);
883 if (validated->size() > max_length) 886 if (validated->size() > max_length)
884 validated->erase(max_length); 887 validated->erase(max_length);
885 *validated += extension; 888 *validated += extension;
886 } 889 }
887 890
888 static STGMEDIUM* GetStorageForFileName(const FilePath& path) { 891 static STGMEDIUM* GetStorageForFileName(const FilePath& path) {
889 const size_t kDropSize = sizeof(DROPFILES); 892 const size_t kDropSize = sizeof(DROPFILES);
890 const size_t kTotalBytes = 893 const size_t kTotalBytes =
891 kDropSize + (path.value().length() + 2) * sizeof(wchar_t); 894 kDropSize + (path.value().length() + 2) * sizeof(wchar_t);
892 HANDLE hdata = GlobalAlloc(GMEM_MOVEABLE, kTotalBytes); 895 HANDLE hdata = GlobalAlloc(GMEM_MOVEABLE, kTotalBytes);
sky 2011/09/08 17:25:46 Shouldn't we check the return value?
yosin_UTC9 2011/09/09 04:25:41 Yes, we should check. Although, I would like to do
893 896
894 base::win::ScopedHGlobal<DROPFILES> locked_mem(hdata); 897 base::win::ScopedHGlobal<DROPFILES> locked_mem(hdata);
895 DROPFILES* drop_files = locked_mem.get(); 898 DROPFILES* drop_files = locked_mem.get();
896 drop_files->pFiles = sizeof(DROPFILES); 899 drop_files->pFiles = sizeof(DROPFILES);
897 drop_files->fWide = TRUE; 900 drop_files->fWide = TRUE;
898 wchar_t* data = reinterpret_cast<wchar_t*>( 901 wchar_t* data = reinterpret_cast<wchar_t*>(
899 reinterpret_cast<BYTE*>(drop_files) + kDropSize); 902 reinterpret_cast<BYTE*>(drop_files) + kDropSize);
900 const size_t copy_size = (path.value().length() + 1) * sizeof(wchar_t); 903 const size_t copy_size = (path.value().length() + 1) * sizeof(wchar_t);
901 memcpy(data, path.value().c_str(), copy_size); 904 memcpy(data, path.value().c_str(), copy_size);
902 data[path.value().length() + 1] = L'\0'; // Double NULL 905 data[path.value().length() + 1] = L'\0'; // Double NULL
903 906
904 STGMEDIUM* storage = new STGMEDIUM; 907 STGMEDIUM* storage = new STGMEDIUM;
905 storage->tymed = TYMED_HGLOBAL; 908 storage->tymed = TYMED_HGLOBAL;
906 storage->hGlobal = drop_files; 909 storage->hGlobal = hdata;
907 storage->pUnkForRelease = NULL; 910 storage->pUnkForRelease = NULL;
908 return storage; 911 return storage;
909 } 912 }
910 913
911 static STGMEDIUM* GetStorageForFileDescriptor( 914 static STGMEDIUM* GetStorageForFileDescriptor(
912 const FilePath& path) { 915 const FilePath& path) {
913 string16 valid_file_name = path.value(); 916 string16 file_name = path.value();
914 DCHECK(!valid_file_name.empty() && valid_file_name.size() + 1 <= MAX_PATH); 917 DCHECK(!file_name.empty());
915 HANDLE handle = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR)); 918 HANDLE hdata = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
sky 2011/09/08 17:25:46 Same thing about checking return value here.
yosin_UTC9 2011/09/09 04:25:41 I'll do another CR.
916 FILEGROUPDESCRIPTOR* descriptor = 919 base::win::ScopedHGlobal<FILEGROUPDESCRIPTOR> locked_mem(hdata);
917 reinterpret_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(handle));
918 920
921 FILEGROUPDESCRIPTOR* descriptor = locked_mem.get();
919 descriptor->cItems = 1; 922 descriptor->cItems = 1;
920 wcscpy_s(descriptor->fgd[0].cFileName,
921 valid_file_name.size() + 1,
922 valid_file_name.c_str());
923 descriptor->fgd[0].dwFlags = FD_LINKUI; 923 descriptor->fgd[0].dwFlags = FD_LINKUI;
924 924 int file_name_len = file_name.size();
925 GlobalUnlock(handle); 925 if (file_name_len + 1 < MAX_PATH) {
926 wcscpy_s(descriptor->fgd[0].cFileName,
927 MAX_PATH,
928 file_name.c_str());
929 } else {
930 string16 extension = path.Extension();
sky 2011/09/08 17:25:46 Shouldn't we make sure we maintain the path compon
yosin_UTC9 2011/09/09 04:25:41 Callers should take care of it. Actually, this fun
931 int extension_len = extension.size();
932 int max_name_len = MAX_PATH - extension_len - 1;
933 if (max_name_len >= 1) {
934 // We take at least one character from name.
935 int orig_name_len = file_name_len - extension_len;
936 int name_len = std::min(orig_name_len, max_name_len);
937 memcpy(descriptor->fgd[0].cFileName,
938 file_name.c_str(),
939 sizeof(wchar_t) * name_len);
940 wcscpy_s(descriptor->fgd[0].cFileName + name_len,
941 MAX_PATH - extension_len,
942 extension.c_str());
943 } else {
944 // We take MAX_PATH-1 characters from file_name.
945 wcsncpy_s(descriptor->fgd[0].cFileName,
946 MAX_PATH,
947 file_name.c_str(),
948 MAX_PATH - 1);
949 }
950 }
926 951
927 STGMEDIUM* storage = new STGMEDIUM; 952 STGMEDIUM* storage = new STGMEDIUM;
928 storage->hGlobal = handle; 953 storage->hGlobal = hdata;
929 storage->tymed = TYMED_HGLOBAL; 954 storage->tymed = TYMED_HGLOBAL;
930 storage->pUnkForRelease = NULL; 955 storage->pUnkForRelease = NULL;
931 return storage; 956 return storage;
932 } 957 }
933 958
934
935 /////////////////////////////////////////////////////////////////////////////// 959 ///////////////////////////////////////////////////////////////////////////////
936 // OSExchangeData, public: 960 // OSExchangeData, public:
937 961
938 // static 962 // static
939 OSExchangeData::Provider* OSExchangeData::CreateProvider() { 963 OSExchangeData::Provider* OSExchangeData::CreateProvider() {
940 return new OSExchangeDataProviderWin(); 964 return new OSExchangeDataProviderWin();
941 } 965 }
942 966
943 // static 967 // static
944 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat( 968 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat(
945 const std::string& type) { 969 const std::string& type) {
946 return RegisterClipboardFormat(ASCIIToUTF16(type).c_str()); 970 return RegisterClipboardFormat(ASCIIToUTF16(type).c_str());
947 } 971 }
948 972
949 } // namespace ui 973 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine