summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-10 00:12:04 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-10 00:12:04 +0000
commit2776363abfdfd7f08a626b151e06776569c41ccb (patch)
tree685503fce788066875284134663b45710d2e937c /content
parent2240256fd2e66ffb592788f027178a03c571b75b (diff)
downloadchromium_src-2776363abfdfd7f08a626b151e06776569c41ccb.zip
chromium_src-2776363abfdfd7f08a626b151e06776569c41ccb.tar.gz
chromium_src-2776363abfdfd7f08a626b151e06776569c41ccb.tar.bz2
Merge 120916 - Avoid overread in RenderWidgetHostViewWin::OnPaint
GetRegionData may return 0 to indicate error. This call is used both to calculate the required buffer size and to fill the buffer with region data. In the first case, if not checked, a zero-length buffer may be allocated. In the second case, the buffer content is undefined. In either case, we should not depend on the buffer content. BUG=110176 TEST=Long tail crasher in gfx::Rect::Rect, called from RenderWidgetHostViewWin::OnPaint. Review URL: http://codereview.chromium.org/9316056 TBR=davidbarr@chromium.org Review URL: https://chromiumcodereview.appspot.com/9371031 git-svn-id: svn://svn.chromium.org/chrome/branches/1025/src@121346 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc24
1 files changed, 20 insertions, 4 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
index 90d2f76..501c610 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -1052,11 +1052,27 @@ void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) {
// Blit only the damaged regions from the backing store.
DWORD data_size = GetRegionData(damage_region, 0, NULL);
- scoped_array<char> region_data_buf(new char[data_size]);
- RGNDATA* region_data = reinterpret_cast<RGNDATA*>(region_data_buf.get());
- GetRegionData(damage_region, data_size, region_data);
+ scoped_array<char> region_data_buf;
+ RGNDATA* region_data = NULL;
+ RECT* region_rects = NULL;
+
+ if (data_size) {
+ region_data_buf.reset(new char[data_size]);
+ region_data = reinterpret_cast<RGNDATA*>(region_data_buf.get());
+ region_rects = reinterpret_cast<RECT*>(region_data->Buffer);
+ data_size = GetRegionData(damage_region, data_size, region_data);
+ }
+
+ if (!data_size) {
+ // Grabbing the damaged regions failed, fake with the whole rect.
+ data_size = sizeof(RGNDATAHEADER) + sizeof(RECT);
+ region_data_buf.reset(new char[data_size]);
+ region_data = reinterpret_cast<RGNDATA*>(region_data_buf.get());
+ region_rects = reinterpret_cast<RECT*>(region_data->Buffer);
+ region_data->rdh.nCount = 1;
+ region_rects[0] = damaged_rect.ToRECT();
+ }
- RECT* region_rects = reinterpret_cast<RECT*>(region_data->Buffer);
for (DWORD i = 0; i < region_data->rdh.nCount; ++i) {
gfx::Rect paint_rect = bitmap_rect.Intersect(gfx::Rect(region_rects[i]));
if (!paint_rect.IsEmpty()) {