diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-10 00:12:04 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-10 00:12:04 +0000 |
commit | 2776363abfdfd7f08a626b151e06776569c41ccb (patch) | |
tree | 685503fce788066875284134663b45710d2e937c /content | |
parent | 2240256fd2e66ffb592788f027178a03c571b75b (diff) | |
download | chromium_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.cc | 24 |
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()) { |