Commit af790e56 authored by Anupam Snigdha's avatar Anupam Snigdha Committed by Commit Bot

Converted DomRect to IntRect while reporting layout bounds.

A clusterfuzz bug showed that the conversion from double to int could
lead to overflow while fetching the layout bounds in DomRect type and
converting it to WebRect. This patch follows a similar approach in
reporting the control bounds of the active element's bounding rect that
selection bounds does when it tries to update the selection bounds in
RenderWidget::UpdateSelectionBounds. We convert DOMRect to DoubleRect
and then use the enclosing IntRect to fetch the layout bounds using the
EnclosingIntRect API.

Bug: 1078429

Change-Id: Iac11e8f4ef1259214f100819f0d5df2f9b6d5356
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2183202
Commit-Queue: Anupam Snigdha <snianu@microsoft.com>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatardanakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#766477}
parent 0f93d88e
......@@ -18,6 +18,7 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/gmock_callback_support.h"
#include "base/threading/thread_task_runner_handle.h"
......@@ -1532,9 +1533,16 @@ TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsAndInputPanelPolicy) {
// panel policy to auto.
ExecuteJavaScriptForTests(
"const editContext = new EditContext(); "
"editContext.focus();editContext.inputPanelPolicy=\"auto\";editContext."
"updateLayout(new DOMRect(10, 20, 30, 40), new DOMRect(10,20, 1, 5));");
base::RunLoop().RunUntilIdle();
"editContext.focus();editContext.inputPanelPolicy=\"auto\"; "
"const control_bound = new DOMRect(10, 20, 30, 40); "
"const selection_bound = new DOMRect(10, 20, 1, 5); "
"editContext.updateLayout(control_bound, selection_bound);");
// This RunLoop is waiting for EditContext to be created and layout bounds
// to be updated in the EditContext.
base::RunLoop run_loop;
base::PostTask(FROM_HERE, run_loop.QuitClosure());
run_loop.Run();
// Update the IME status and verify if our IME backend sends an IPC message
// to notify layout bounds of the EditContext.
main_widget()->UpdateTextInputState();
......@@ -1555,6 +1563,49 @@ TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsAndInputPanelPolicy) {
actual_active_element_selection_bounds);
}
TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsWithFloatingValues) {
// Load an HTML page.
LoadHTML(
"<html>"
"<head>"
"</head>"
"<body>"
"</body>"
"</html>");
render_thread_->sink().ClearMessages();
// Create an EditContext with control and selection bounds and set input
// panel policy to auto.
ExecuteJavaScriptForTests(
"const editContext = new EditContext(); "
"editContext.focus();editContext.inputPanelPolicy=\"auto\"; "
"const control_bound = new DOMRect(10.14, 20.25, 30.15, 40.50); "
"const selection_bound = new DOMRect(10, 20, 1, 5); "
"editContext.updateLayout(control_bound, selection_bound);");
// This RunLoop is waiting for EditContext to be created and layout bounds
// to be updated in the EditContext.
base::RunLoop run_loop;
base::PostTask(FROM_HERE, run_loop.QuitClosure());
run_loop.Run();
// Update the IME status and verify if our IME backend sends an IPC message
// to notify layout bounds of the EditContext.
main_widget()->UpdateTextInputState();
auto params = ProcessAndReadIPC<WidgetHostMsg_TextInputStateChanged>();
EXPECT_EQ(true, std::get<0>(params).show_ime_if_needed);
blink::WebRect edit_context_control_bounds_expected(10, 20, 31, 41);
blink::WebRect edit_context_selection_bounds_expected(10, 20, 1, 5);
main_widget()->ConvertViewportToWindow(&edit_context_control_bounds_expected);
main_widget()->ConvertViewportToWindow(
&edit_context_selection_bounds_expected);
blink::WebRect actual_active_element_control_bounds(
std::get<0>(params).edit_context_control_bounds.value());
blink::WebRect actual_active_element_selection_bounds(
std::get<0>(params).edit_context_selection_bounds.value());
EXPECT_EQ(edit_context_control_bounds_expected,
actual_active_element_control_bounds);
EXPECT_EQ(edit_context_selection_bounds_expected,
actual_active_element_selection_bounds);
}
TEST_F(RenderViewImplTest, ActiveElementGetLayoutBounds) {
// Load an HTML page consisting of one input fields.
LoadHTML(
......@@ -1569,7 +1620,10 @@ TEST_F(RenderViewImplTest, ActiveElementGetLayoutBounds) {
// Create an EditContext with control and selection bounds and set input
// panel policy to auto.
ExecuteJavaScriptForTests("document.getElementById('test').focus();");
base::RunLoop().RunUntilIdle();
// This RunLoop is waiting for focus to be processed for the active element.
base::RunLoop run_loop;
base::PostTask(FROM_HERE, run_loop.QuitClosure());
run_loop.Run();
// Update the IME status and verify if our IME backend sends an IPC message
// to notify layout bounds of the EditContext.
main_widget()->UpdateTextInputState();
......
......@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/platform/geometry/double_rect.h"
#include "third_party/blink/renderer/platform/wtf/decimal.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
......@@ -198,14 +199,15 @@ void EditContext::updateSelection(uint32_t start,
void EditContext::updateLayout(DOMRect* control_bounds,
DOMRect* selection_bounds) {
control_bounds_.x = control_bounds->x();
control_bounds_.y = control_bounds->y();
control_bounds_.width = control_bounds->width();
control_bounds_.height = control_bounds->height();
selection_bounds_.x = selection_bounds->x();
selection_bounds_.y = selection_bounds->y();
selection_bounds_.width = selection_bounds->width();
selection_bounds_.height = selection_bounds->height();
// Return the IntRect containing the given DOMRect.
const DoubleRect control_bounds_double_rect(
control_bounds->x(), control_bounds->y(), control_bounds->width(),
control_bounds->height());
control_bounds_ = EnclosingIntRect(control_bounds_double_rect);
const DoubleRect selection_bounds_double_rect(
selection_bounds->x(), selection_bounds->y(), selection_bounds->width(),
selection_bounds->height());
selection_bounds_ = EnclosingIntRect(selection_bounds_double_rect);
}
void EditContext::updateText(uint32_t start,
......
......@@ -62,6 +62,7 @@
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/geometry/double_rect.h"
namespace blink {
......@@ -1375,11 +1376,12 @@ void InputMethodController::GetLayoutBounds(WebRect* control_bounds,
// Selection bounds are currently populated only for EditContext.
// For editable elements we use GetCompositionCharacterBounds to fetch the
// selection bounds.
DOMRect* editable_rect = element->getBoundingClientRect();
control_bounds->x = editable_rect->x();
control_bounds->y = editable_rect->y();
control_bounds->width = editable_rect->width();
control_bounds->height = editable_rect->height();
const DOMRect* editable_rect = element->getBoundingClientRect();
const DoubleRect editable_rect_double(editable_rect->x(), editable_rect->y(),
editable_rect->width(),
editable_rect->height());
// Return the IntRect containing the given DOMRect.
*control_bounds = EnclosingIntRect(editable_rect_double);
}
WebTextInputInfo InputMethodController::TextInputInfo() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment