Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Unified Diff: ui/gfx/geometry/rect_unittest.cc

Issue 2354783004: Fix overflow/underflow in gfx geometry once and for all (Closed)
Patch Set: Remove accessibility test changes Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/geometry/rect.cc ('k') | ui/gfx/geometry/safe_integer_conversions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/geometry/rect_unittest.cc
diff --git a/ui/gfx/geometry/rect_unittest.cc b/ui/gfx/geometry/rect_unittest.cc
index 179e3f5828703b9a0e92d1e13df61b2284f61d5c..29d6f2c8ce53f1c2752b29c18d757b532f414ac0 100644
--- a/ui/gfx/geometry/rect_unittest.cc
+++ b/ui/gfx/geometry/rect_unittest.cc
@@ -910,8 +910,10 @@ TEST(RectTest, ManhattanInternalDistance) {
}
TEST(RectTest, IntegerOverflow) {
+ int limit = std::numeric_limits<int>::max();
+ int min_limit = std::numeric_limits<int>::min();
int expected = 10;
- int large_number = std::numeric_limits<int>::max() - expected;
+ int large_number = limit - expected;
Rect height_overflow(0, large_number, 100, 100);
EXPECT_EQ(large_number, height_overflow.y());
@@ -970,10 +972,32 @@ TEST(RectTest, IntegerOverflow) {
EXPECT_EQ(large_offset, set_rect_overflow.origin());
EXPECT_EQ(expected_size, set_rect_overflow.size());
+ // Insetting an empty rect, but the total inset (left + right) could overflow.
Rect inset_overflow;
inset_overflow.Inset(large_number, large_number, 100, 100);
EXPECT_EQ(large_offset, inset_overflow.origin());
- EXPECT_EQ(expected_size, inset_overflow.size());
+ EXPECT_EQ(gfx::Size(), inset_overflow.size());
+
+ // Insetting where the total inset (width - left - right) could overflow.
+ // Also, this insetting by the min limit in all directions cannot
+ // represent width() without overflow, so that will also clamp.
+ Rect inset_overflow2;
+ inset_overflow2.Inset(min_limit, min_limit, min_limit, min_limit);
+ EXPECT_EQ(inset_overflow2, gfx::Rect(min_limit, min_limit, limit, limit));
+
+ // Insetting where the width shouldn't change, but if the insets operations
+ // clamped in the wrong order, e.g. ((width - left) - right) vs (width - (left
+ // + right)) then this will not work properly. This is the proper order,
+ // as if left + right overflows, the width cannot be decreased by more than
+ // max int anyway. Additionally, if left + right underflows, it cannot be
+ // increased by more then max int.
+ Rect inset_overflow3(0, 0, limit, limit);
+ inset_overflow3.Inset(-100, -100, 100, 100);
+ EXPECT_EQ(inset_overflow3, gfx::Rect(-100, -100, limit, limit));
+
+ Rect inset_overflow4(-1000, -1000, limit, limit);
+ inset_overflow4.Inset(100, 100, -100, -100);
+ EXPECT_EQ(inset_overflow4, gfx::Rect(-900, -900, limit, limit));
Rect offset_overflow(0, 0, 100, 100);
offset_overflow.Offset(large_number, large_number);
@@ -984,6 +1008,52 @@ TEST(RectTest, IntegerOverflow) {
operator_overflow += Vector2d(large_number, large_number);
EXPECT_EQ(large_offset, operator_overflow.origin());
EXPECT_EQ(expected_size, operator_overflow.size());
+
+ Rect origin_maxint(limit, limit, limit, limit);
+ EXPECT_EQ(origin_maxint, Rect(gfx::Point(limit, limit), gfx::Size()));
+
+ // Expect a rect at the origin and a rect whose right/bottom is maxint
+ // create a rect that extends from 0..maxint in both extents.
+ {
+ Rect origin_small(0, 0, 100, 100);
+ Rect big_clamped(50, 50, limit, limit);
+ EXPECT_EQ(big_clamped.right(), limit);
+
+ Rect unioned = UnionRects(origin_small, big_clamped);
+ Rect rect_limit(0, 0, limit, limit);
+ EXPECT_EQ(unioned, rect_limit);
+ }
+
+ // Expect a rect that would overflow width (but not right) to be clamped
+ // and to have maxint extents after unioning.
+ {
+ Rect small(-500, -400, 100, 100);
+ Rect big(-400, -500, limit, limit);
+ // Technically, this should be limit + 100 width, but will clamp to maxint.
+ EXPECT_EQ(UnionRects(small, big), Rect(-500, -500, limit, limit));
+ }
+
+ // Expect a rect that would overflow right *and* width to be clamped.
+ {
+ Rect clamped(500, 500, limit, limit);
+ Rect positive_origin(100, 100, 500, 500);
+
+ // Ideally, this should be (100, 100, limit + 400, limit + 400).
+ // However, width overflows and would be clamped to limit, but right
+ // overflows too and so will be clamped to limit - 100.
+ Rect expected(100, 100, limit - 100, limit - 100);
+ EXPECT_EQ(UnionRects(clamped, positive_origin), expected);
+ }
+
+ // Unioning a left=minint rect with a right=maxint rect.
+ // Width is always clamped before adjusting position, so this
+ // should taking the min left/top and then finding the max width.
+ {
+ Rect left_minint(min_limit, min_limit, 1, 1);
+ Rect right_maxint(limit - 1, limit - 1, limit, limit);
+ Rect expected(min_limit, min_limit, limit, limit);
+ EXPECT_EQ(UnionRects(left_minint, right_maxint), expected);
+ }
}
TEST(RectTest, ScaleToEnclosingRectSafe) {
« no previous file with comments | « ui/gfx/geometry/rect.cc ('k') | ui/gfx/geometry/safe_integer_conversions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698