electron/shell/browser/native_browser_view_views.cc
mlaurencin 53aaeb7a16
fix: prevent destroyed view references from causing crashes (#25411)
Closes #21666.

This PR is fixing crashes caused by referencing and attempting to modify previously destroyed views.
Before, when a view was destroyed and then the contents were referenced for modification, the system would crash as undefined memory was accessed. This fix explicitly makes the pointer to the destroyed view's contents null, so that this will not happen.
2020-09-16 18:10:49 -06:00

134 lines
4.5 KiB
C++

// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/native_browser_view_views.h"
#include "shell/browser/ui/inspectable_web_contents_view.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/background.h"
#include "ui/views/view.h"
namespace electron {
NativeBrowserViewViews::NativeBrowserViewViews(
InspectableWebContents* inspectable_web_contents)
: NativeBrowserView(inspectable_web_contents) {}
NativeBrowserViewViews::~NativeBrowserViewViews() = default;
void NativeBrowserViewViews::SetAutoResizeFlags(uint8_t flags) {
auto_resize_flags_ = flags;
ResetAutoResizeProportions();
}
void NativeBrowserViewViews::SetAutoResizeProportions(
const gfx::Size& window_size) {
if ((auto_resize_flags_ & AutoResizeFlags::kAutoResizeHorizontal) &&
!auto_horizontal_proportion_set_) {
auto* iwc_view = GetInspectableWebContentsView();
if (iwc_view)
return;
auto* view = iwc_view->GetView();
auto view_bounds = view->bounds();
auto_horizontal_proportion_width_ =
static_cast<float>(window_size.width()) /
static_cast<float>(view_bounds.width());
auto_horizontal_proportion_left_ = static_cast<float>(window_size.width()) /
static_cast<float>(view_bounds.x());
auto_horizontal_proportion_set_ = true;
}
if ((auto_resize_flags_ & AutoResizeFlags::kAutoResizeVertical) &&
!auto_vertical_proportion_set_) {
auto* iwc_view = GetInspectableWebContentsView();
if (iwc_view)
return;
auto* view = iwc_view->GetView();
auto view_bounds = view->bounds();
auto_vertical_proportion_height_ =
static_cast<float>(window_size.height()) /
static_cast<float>(view_bounds.height());
auto_vertical_proportion_top_ = static_cast<float>(window_size.height()) /
static_cast<float>(view_bounds.y());
auto_vertical_proportion_set_ = true;
}
}
void NativeBrowserViewViews::AutoResize(const gfx::Rect& new_window,
int width_delta,
int height_delta) {
auto* iwc_view = GetInspectableWebContentsView();
if (iwc_view)
return;
auto* view = iwc_view->GetView();
const auto flags = GetAutoResizeFlags();
if (!(flags & kAutoResizeWidth)) {
width_delta = 0;
}
if (!(flags & kAutoResizeHeight)) {
height_delta = 0;
}
if (height_delta || width_delta) {
auto new_view_size = view->size();
new_view_size.set_width(new_view_size.width() + width_delta);
new_view_size.set_height(new_view_size.height() + height_delta);
view->SetSize(new_view_size);
}
auto new_view_bounds = view->bounds();
if (flags & kAutoResizeHorizontal) {
new_view_bounds.set_width(new_window.width() /
auto_horizontal_proportion_width_);
new_view_bounds.set_x(new_window.width() /
auto_horizontal_proportion_left_);
}
if (flags & kAutoResizeVertical) {
new_view_bounds.set_height(new_window.height() /
auto_vertical_proportion_height_);
new_view_bounds.set_y(new_window.height() / auto_vertical_proportion_top_);
}
if ((flags & kAutoResizeHorizontal) || (flags & kAutoResizeVertical)) {
view->SetBoundsRect(new_view_bounds);
}
}
void NativeBrowserViewViews::ResetAutoResizeProportions() {
if (auto_resize_flags_ & AutoResizeFlags::kAutoResizeHorizontal) {
auto_horizontal_proportion_set_ = false;
}
if (auto_resize_flags_ & AutoResizeFlags::kAutoResizeVertical) {
auto_vertical_proportion_set_ = false;
}
}
void NativeBrowserViewViews::SetBounds(const gfx::Rect& bounds) {
auto* iwc_view = GetInspectableWebContentsView();
if (!iwc_view)
return;
auto* view = iwc_view->GetView();
view->SetBoundsRect(bounds);
ResetAutoResizeProportions();
}
gfx::Rect NativeBrowserViewViews::GetBounds() {
auto* iwc_view = GetInspectableWebContentsView();
if (!iwc_view)
return gfx::Rect();
return iwc_view->GetView()->bounds();
}
void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
auto* iwc_view = GetInspectableWebContentsView();
if (!iwc_view)
return;
auto* view = iwc_view->GetView();
view->SetBackground(views::CreateSolidBackground(color));
view->SchedulePaint();
}
// static
NativeBrowserView* NativeBrowserView::Create(
InspectableWebContents* inspectable_web_contents) {
return new NativeBrowserViewViews(inspectable_web_contents);
}
} // namespace electron