diff options
author | jschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-28 02:02:18 +0000 |
---|---|---|
committer | jschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-28 02:02:18 +0000 |
commit | 67ea507fbee5b2d1647f3b86a60c36e8ba40c797 (patch) | |
tree | 26384c8a65a9c333da260e433055bead8b0ef88d /ui | |
parent | 66eda3ee6b93c063f79ae9fc89e472e353b89585 (diff) | |
download | chromium_src-67ea507fbee5b2d1647f3b86a60c36e8ba40c797.zip chromium_src-67ea507fbee5b2d1647f3b86a60c36e8ba40c797.tar.gz chromium_src-67ea507fbee5b2d1647f3b86a60c36e8ba40c797.tar.bz2 |
Make SharedMemory track the size that was actually mapped
In the process I also had to fix several dependencies, and
some major issues in transport DIBs.
BUG=60819
Review URL: https://chromiumcodereview.appspot.com/12537014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191098 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/surface/surface.gyp | 1 | ||||
-rw-r--r-- | ui/surface/transport_dib.cc | 21 | ||||
-rw-r--r-- | ui/surface/transport_dib.h | 4 | ||||
-rw-r--r-- | ui/surface/transport_dib_android.cc | 11 | ||||
-rw-r--r-- | ui/surface/transport_dib_linux.cc | 2 | ||||
-rw-r--r-- | ui/surface/transport_dib_mac.cc | 2 | ||||
-rw-r--r-- | ui/surface/transport_dib_win.cc | 30 |
7 files changed, 48 insertions, 23 deletions
diff --git a/ui/surface/surface.gyp b/ui/surface/surface.gyp index 903ea49..cc4aa6b 100644 --- a/ui/surface/surface.gyp +++ b/ui/surface/surface.gyp @@ -80,6 +80,7 @@ 'surface_switches.h', 'surface_switches.cc', 'transport_dib.h', + 'transport_dib.cc', 'transport_dib_android.cc', 'transport_dib_linux.cc', 'transport_dib_mac.cc', diff --git a/ui/surface/transport_dib.cc b/ui/surface/transport_dib.cc new file mode 100644 index 0000000..ba72f91 --- /dev/null +++ b/ui/surface/transport_dib.cc @@ -0,0 +1,21 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/surface/transport_dib.h" + +#include "skia/ext/platform_canvas.h" + +// static +bool TransportDIB::VerifyCanvasSize(int w, int h) { + static const size_t kMaxSize = static_cast<size_t>(INT_MAX); + const size_t one_stride = skia::PlatformCanvasStrideForWidth(1); + const size_t stride = skia::PlatformCanvasStrideForWidth(w); + if (w <= 0 || h <= 0 || static_cast<size_t>(w) > (kMaxSize / one_stride) || + static_cast<size_t>(h) > (kMaxSize / stride)) { + return false; + } + + return (stride * h) <= size_; +} + diff --git a/ui/surface/transport_dib.h b/ui/surface/transport_dib.h index 5050a6a..233cd2e 100644 --- a/ui/surface/transport_dib.h +++ b/ui/surface/transport_dib.h @@ -205,6 +205,10 @@ class SURFACE_EXPORT TransportDIB { private: TransportDIB(); + + // Verifies that the dib can hold a canvas of the requested dimensions. + bool VerifyCanvasSize(int w, int h); + #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_ANDROID) explicit TransportDIB(base::SharedMemoryHandle dib); base::SharedMemory shared_memory_; diff --git a/ui/surface/transport_dib_android.cc b/ui/surface/transport_dib_android.cc index 25a7875..f734155 100644 --- a/ui/surface/transport_dib_android.cc +++ b/ui/surface/transport_dib_android.cc @@ -63,7 +63,7 @@ bool TransportDIB::is_valid_id(Id id) { } skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (!memory() && !Map()) + if ((!memory() && !Map()) || !VerifyCanvasSize(w, h)) return NULL; return skia::CreatePlatformCanvas(w, h, true, reinterpret_cast<uint8_t*>(memory()), @@ -71,15 +71,10 @@ skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { } bool TransportDIB::Map() { - if (!is_valid_handle(handle())) - return false; - // We will use ashmem_get_size_region() to figure out the size in Map(size). - if (!shared_memory_.Map(0)) + if (!is_valid_handle(handle()) || !shared_memory_.Map(0)) return false; - // TODO: Note that using created_size() below is a hack. See the comment in - // SharedMemory::Map(). - size_ = shared_memory_.created_size(); + size_ = shared_memory_.mapped_size(); return true; } diff --git a/ui/surface/transport_dib_linux.cc b/ui/surface/transport_dib_linux.cc index 3aaa798..1e8d8fa 100644 --- a/ui/surface/transport_dib_linux.cc +++ b/ui/surface/transport_dib_linux.cc @@ -92,7 +92,7 @@ bool TransportDIB::is_valid_id(Id id) { } skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (address_ == kInvalidAddress && !Map()) + if ((address_ == kInvalidAddress && !Map()) || !VerifyCanvasSize(w, h)) return NULL; return skia::CreatePlatformCanvas(w, h, true, reinterpret_cast<uint8_t*>(memory()), diff --git a/ui/surface/transport_dib_mac.cc b/ui/surface/transport_dib_mac.cc index 7abfbce..8481656 100644 --- a/ui/surface/transport_dib_mac.cc +++ b/ui/surface/transport_dib_mac.cc @@ -61,7 +61,7 @@ bool TransportDIB::is_valid_id(Id id) { } skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (!memory() && !Map()) + if ((!memory() && !Map()) || !VerifyCanvasSize(w, h)) return NULL; return skia::CreatePlatformCanvas(w, h, true, reinterpret_cast<uint8_t*>(memory()), diff --git a/ui/surface/transport_dib_win.cc b/ui/surface/transport_dib_win.cc index 55dd6a3..a664266 100644 --- a/ui/surface/transport_dib_win.cc +++ b/ui/surface/transport_dib_win.cc @@ -13,22 +13,20 @@ #include "base/sys_info.h" #include "skia/ext/platform_canvas.h" -TransportDIB::TransportDIB() { +TransportDIB::TransportDIB() + : size_(0) { } TransportDIB::~TransportDIB() { } TransportDIB::TransportDIB(HANDLE handle) - : shared_memory_(handle, false /* read write */) { + : shared_memory_(handle, false /* read write */), + size_(0) { } // static TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { - size_t allocation_granularity = base::SysInfo::VMAllocationGranularity(); - size = size / allocation_granularity + 1; - size = size * allocation_granularity; - TransportDIB* dib = new TransportDIB; if (!dib->shared_memory_.CreateAnonymous(size)) { @@ -70,8 +68,18 @@ skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { // will map it again. DCHECK(!memory()) << "Mapped file twice in the same process."; - return skia::CreatePlatformCanvas(w, h, true, handle(), - skia::RETURN_NULL_ON_FAILURE); + // We can't check the canvas size before mapping, but it's safe because + // Windows will fail to map the section if the dimensions of the canvas + // are too large. + skia::PlatformCanvas* canvas = + skia::CreatePlatformCanvas(w, h, true, handle(), + skia::RETURN_NULL_ON_FAILURE); + + // Calculate the size for the memory region backing the canvas. + if (canvas) + size_ = skia::PlatformCanvasStrideForWidth(w) * h; + + return canvas; } bool TransportDIB::Map() { @@ -87,11 +95,7 @@ bool TransportDIB::Map() { return false; } - // There doesn't seem to be any way to find the size of the shared memory - // region! GetFileSize indicates that the handle is invalid. Thus, we - // conservatively set the size to the maximum and hope that the renderer - // isn't about to ask us to read off the end of the array. - size_ = std::numeric_limits<size_t>::max(); + size_ = shared_memory_.mapped_size(); return true; } |