Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(570)

Unified Diff: ui/base/clipboard/clipboard.cc

Issue 740003003: Revert of Rewrite clipboard write IPC handling to be easier to understand. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/base/clipboard/clipboard.h ('k') | ui/base/clipboard/clipboard_test_template.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/clipboard/clipboard.cc
diff --git a/ui/base/clipboard/clipboard.cc b/ui/base/clipboard/clipboard.cc
index 953ebb4d7e6dcf909d515a65abb234fab827284f..0bd542d563a9a66cb3955b062ab7695380b63958 100644
--- a/ui/base/clipboard/clipboard.cc
+++ b/ui/base/clipboard/clipboard.cc
@@ -13,6 +13,27 @@
#include "ui/gfx/size.h"
namespace ui {
+
+namespace {
+
+// Valides a shared bitmap on the clipboard.
+// Returns true if the clipboard data makes sense and it's safe to access the
+// bitmap.
+bool ValidateAndMapSharedBitmap(size_t bitmap_bytes,
+ base::SharedMemory* bitmap_data) {
+ using base::SharedMemory;
+
+ if (!bitmap_data || !SharedMemory::IsHandleValid(bitmap_data->handle()))
+ return false;
+
+ if (!bitmap_data->Map(bitmap_bytes)) {
+ PLOG(ERROR) << "Failed to map bitmap memory";
+ return false;
+ }
+ return true;
+}
+
+} // namespace
base::LazyInstance<Clipboard::AllowedThreadsVector>
Clipboard::allowed_threads_ = LAZY_INSTANCE_INITIALIZER;
@@ -74,6 +95,13 @@
}
void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) {
+ // All types apart from CBF_WEBKIT need at least 1 non-empty param.
+ if (type != CBF_WEBKIT && (params.empty() || params[0].empty()))
+ return;
+ // Some other types need a non-empty 2nd param.
+ if ((type == CBF_BOOKMARK || type == CBF_SMBITMAP || type == CBF_DATA) &&
+ (params.size() != 2 || params[1].empty()))
+ return;
switch (type) {
case CBF_TEXT:
WriteText(&(params[0].front()), params[0].size());
@@ -104,13 +132,41 @@
break;
case CBF_SMBITMAP: {
- // Usually, the params are just UTF-8 strings. However, for images,
- // ScopedClipboardWriter actually sizes the buffer to sizeof(SkBitmap*),
- // aliases the contents of the vector to a SkBitmap**, and writes the
- // pointer to the actual SkBitmap in the clipboard object param.
- const char* packed_pointer_buffer = &params[0].front();
- WriteBitmap(
- **reinterpret_cast<SkBitmap* const*>(packed_pointer_buffer));
+ using base::SharedMemory;
+ using base::SharedMemoryHandle;
+
+ if (params[0].size() != sizeof(SharedMemory*) ||
+ params[1].size() != sizeof(gfx::Size)) {
+ return;
+ }
+
+ SkBitmap bitmap;
+ const gfx::Size* unvalidated_size =
+ reinterpret_cast<const gfx::Size*>(&params[1].front());
+ // Let Skia do some sanity checking for us (no negative widths/heights, no
+ // overflows while calculating bytes per row, etc).
+ if (!bitmap.setInfo(SkImageInfo::MakeN32Premul(
+ unvalidated_size->width(), unvalidated_size->height()))) {
+ return;
+ }
+ // Make sure the size is representable as a signed 32-bit int, so
+ // SkBitmap::getSize() won't be truncated.
+ if (!sk_64_isS32(bitmap.computeSize64()))
+ return;
+
+ // It's OK to cast away constness here since we map the handle as
+ // read-only.
+ const char* raw_bitmap_data_const =
+ reinterpret_cast<const char*>(&params[0].front());
+ char* raw_bitmap_data = const_cast<char*>(raw_bitmap_data_const);
+ scoped_ptr<SharedMemory> bitmap_data(
+ *reinterpret_cast<SharedMemory**>(raw_bitmap_data));
+
+ if (!ValidateAndMapSharedBitmap(bitmap.getSize(), bitmap_data.get()))
+ return;
+ bitmap.setPixels(bitmap_data->memory());
+
+ WriteBitmap(bitmap);
break;
}
@@ -127,4 +183,40 @@
}
}
+// static
+bool Clipboard::ReplaceSharedMemHandle(ObjectMap* objects,
+ base::SharedMemoryHandle bitmap_handle,
+ base::ProcessHandle process) {
+ using base::SharedMemory;
+ bool has_shared_bitmap = false;
+
+ for (ObjectMap::iterator iter = objects->begin(); iter != objects->end();
+ ++iter) {
+ if (iter->first == CBF_SMBITMAP) {
+ // The code currently only accepts sending a single bitmap over this way.
+ // Fail if we ever encounter more than one shmem bitmap structure to fill.
+ if (has_shared_bitmap)
+ return false;
+
+#if defined(OS_WIN)
+ SharedMemory* bitmap = new SharedMemory(bitmap_handle, true, process);
+#else
+ SharedMemory* bitmap = new SharedMemory(bitmap_handle, true);
+#endif
+
+ // There must always be two parameters associated with each shmem bitmap.
+ if (iter->second.size() != 2)
+ return false;
+
+ // We store the shared memory object pointer so it can be retrieved by the
+ // UI thread (see DispatchObject()).
+ iter->second[0].clear();
+ for (size_t i = 0; i < sizeof(SharedMemory*); ++i)
+ iter->second[0].push_back(reinterpret_cast<char*>(&bitmap)[i]);
+ has_shared_bitmap = true;
+ }
+ }
+ return true;
+}
+
} // namespace ui
« no previous file with comments | « ui/base/clipboard/clipboard.h ('k') | ui/base/clipboard/clipboard_test_template.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698