summaryrefslogtreecommitdiffstats
path: root/ui/surface
diff options
context:
space:
mode:
authorjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-28 02:02:18 +0000
committerjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-28 02:02:18 +0000
commit67ea507fbee5b2d1647f3b86a60c36e8ba40c797 (patch)
tree26384c8a65a9c333da260e433055bead8b0ef88d /ui/surface
parent66eda3ee6b93c063f79ae9fc89e472e353b89585 (diff)
downloadchromium_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/surface')
-rw-r--r--ui/surface/surface.gyp1
-rw-r--r--ui/surface/transport_dib.cc21
-rw-r--r--ui/surface/transport_dib.h4
-rw-r--r--ui/surface/transport_dib_android.cc11
-rw-r--r--ui/surface/transport_dib_linux.cc2
-rw-r--r--ui/surface/transport_dib_mac.cc2
-rw-r--r--ui/surface/transport_dib_win.cc30
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;
}