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

Side by Side Diff: ui/gfx/geometry/rect_unittest.cc

Issue 2354783004: Fix overflow/underflow in gfx geometry once and for all (Closed)
Patch Set: Add additional inset test 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits> 5 #include <limits>
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 1.1f, 1.0f))); 900 0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 1.1f, 1.0f)));
901 EXPECT_FLOAT_EQ( 901 EXPECT_FLOAT_EQ(
902 0.1f + kEpsilon, 902 0.1f + kEpsilon,
903 f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.4f, 1.0f))); 903 f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.4f, 1.0f)));
904 EXPECT_FLOAT_EQ( 904 EXPECT_FLOAT_EQ(
905 kEpsilon, 905 kEpsilon,
906 f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.5f, 1.0f))); 906 f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.5f, 1.0f)));
907 } 907 }
908 908
909 TEST(RectTest, IntegerOverflow) { 909 TEST(RectTest, IntegerOverflow) {
910 int limit = std::numeric_limits<int>::max();
911 int min_limit = std::numeric_limits<int>::min();
910 int expected = 10; 912 int expected = 10;
911 int large_number = std::numeric_limits<int>::max() - expected; 913 int large_number = limit - expected;
912 914
913 Rect height_overflow(0, large_number, 100, 100); 915 Rect height_overflow(0, large_number, 100, 100);
914 EXPECT_EQ(large_number, height_overflow.y()); 916 EXPECT_EQ(large_number, height_overflow.y());
915 EXPECT_EQ(expected, height_overflow.height()); 917 EXPECT_EQ(expected, height_overflow.height());
916 918
917 Rect width_overflow(large_number, 0, 100, 100); 919 Rect width_overflow(large_number, 0, 100, 100);
918 EXPECT_EQ(large_number, width_overflow.x()); 920 EXPECT_EQ(large_number, width_overflow.x());
919 EXPECT_EQ(expected, width_overflow.width()); 921 EXPECT_EQ(expected, width_overflow.width());
920 922
921 Rect size_height_overflow(Point(0, large_number), Size(100, 100)); 923 Rect size_height_overflow(Point(0, large_number), Size(100, 100));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 EXPECT_EQ(Size(5, 5), set_size_overflow.size()); 962 EXPECT_EQ(Size(5, 5), set_size_overflow.size());
961 set_size_overflow.set_size(size); 963 set_size_overflow.set_size(size);
962 EXPECT_EQ(large_offset, set_size_overflow.origin()); 964 EXPECT_EQ(large_offset, set_size_overflow.origin());
963 EXPECT_EQ(expected_size, set_size_overflow.size()); 965 EXPECT_EQ(expected_size, set_size_overflow.size());
964 966
965 Rect set_rect_overflow; 967 Rect set_rect_overflow;
966 set_rect_overflow.SetRect(large_number, large_number, 100, 100); 968 set_rect_overflow.SetRect(large_number, large_number, 100, 100);
967 EXPECT_EQ(large_offset, set_rect_overflow.origin()); 969 EXPECT_EQ(large_offset, set_rect_overflow.origin());
968 EXPECT_EQ(expected_size, set_rect_overflow.size()); 970 EXPECT_EQ(expected_size, set_rect_overflow.size());
969 971
972 // Insetting an empty rect, but the total inset (left + right) could overflow.
970 Rect inset_overflow; 973 Rect inset_overflow;
971 inset_overflow.Inset(large_number, large_number, 100, 100); 974 inset_overflow.Inset(large_number, large_number, 100, 100);
972 EXPECT_EQ(large_offset, inset_overflow.origin()); 975 EXPECT_EQ(large_offset, inset_overflow.origin());
973 EXPECT_EQ(expected_size, inset_overflow.size()); 976 EXPECT_EQ(gfx::Size(), inset_overflow.size());
977
978 // Insetting where the total inset (width - left - right) could overflow.
979 // Also, this insetting by the min limit in all directions cannot
980 // represent width() without overflow, so that will also clamp.
981 Rect inset_overflow2;
982 inset_overflow2.Inset(min_limit, min_limit, min_limit, min_limit);
983 EXPECT_EQ(inset_overflow2, gfx::Rect(min_limit, min_limit, limit, limit));
984
985 // Insetting where the width shouldn't change, but if the insets operations
986 // clamped in the wrong order, e.g. ((width - left) - right) vs (width - (left
987 // + right)) then this will not work properly. This is the proper order,
988 // as if left + right overflows, the width cannot be decreased by more than
989 // max int anyway. Additionally, if left + right underflows, it cannot be
990 // increased by more then max int.
991 Rect inset_overflow3(0, 0, limit, limit);
992 inset_overflow3.Inset(-100, -100, 100, 100);
993 EXPECT_EQ(inset_overflow3, gfx::Rect(-100, -100, limit, limit));
994
995 Rect inset_overflow4(-1000, -1000, limit, limit);
996 inset_overflow4.Inset(100, 100, -100, -100);
997 EXPECT_EQ(inset_overflow4, gfx::Rect(-900, -900, limit, limit));
974 998
975 Rect offset_overflow(0, 0, 100, 100); 999 Rect offset_overflow(0, 0, 100, 100);
976 offset_overflow.Offset(large_number, large_number); 1000 offset_overflow.Offset(large_number, large_number);
977 EXPECT_EQ(large_offset, offset_overflow.origin()); 1001 EXPECT_EQ(large_offset, offset_overflow.origin());
978 EXPECT_EQ(expected_size, offset_overflow.size()); 1002 EXPECT_EQ(expected_size, offset_overflow.size());
979 1003
980 Rect operator_overflow(0, 0, 100, 100); 1004 Rect operator_overflow(0, 0, 100, 100);
981 operator_overflow += Vector2d(large_number, large_number); 1005 operator_overflow += Vector2d(large_number, large_number);
982 EXPECT_EQ(large_offset, operator_overflow.origin()); 1006 EXPECT_EQ(large_offset, operator_overflow.origin());
983 EXPECT_EQ(expected_size, operator_overflow.size()); 1007 EXPECT_EQ(expected_size, operator_overflow.size());
1008
1009 Rect origin_maxint(limit, limit, limit, limit);
1010 EXPECT_EQ(origin_maxint, Rect(gfx::Point(limit, limit), gfx::Size()));
1011
1012 // Expect a rect at the origin and a rect whose right/bottom is maxint
1013 // create a rect that extends from 0..maxint in both extents.
1014 {
1015 Rect origin_small(0, 0, 100, 100);
1016 Rect big_clamped(50, 50, limit, limit);
1017 EXPECT_EQ(big_clamped.right(), limit);
1018
1019 Rect unioned = UnionRects(origin_small, big_clamped);
1020 Rect rect_limit(0, 0, limit, limit);
1021 EXPECT_EQ(unioned, rect_limit);
1022 }
1023
1024 // Expect a rect that would overflow width (but not right) to be clamped
1025 // and to have maxint extents after unioning.
1026 {
1027 Rect small(-500, -400, 100, 100);
1028 Rect big(-400, -500, limit, limit);
1029 // Technically, this should be limit + 100 width, but will clamp to maxint.
1030 EXPECT_EQ(UnionRects(small, big), Rect(-500, -500, limit, limit));
1031 }
1032
1033 // Expect a rect that would overflow right *and* width to be clamped.
1034 {
1035 Rect clamped(500, 500, limit, limit);
1036 Rect positive_origin(100, 100, 500, 500);
1037
1038 // Ideally, this should be (100, 100, limit + 400, limit + 400).
1039 // However, width overflows and would be clamped to limit, but right
1040 // overflows too and so will be clamped to limit - 100.
1041 Rect expected(100, 100, limit - 100, limit - 100);
1042 EXPECT_EQ(UnionRects(clamped, positive_origin), expected);
1043 }
1044
1045 // Unioning a left=minint rect with a right=maxint rect.
1046 // Width is always clamped before adjusting position, so this
1047 // should taking the min left/top and then finding the max width.
1048 {
1049 Rect left_minint(min_limit, min_limit, 1, 1);
1050 Rect right_maxint(limit - 1, limit - 1, limit, limit);
1051 Rect expected(min_limit, min_limit, limit, limit);
1052 EXPECT_EQ(UnionRects(left_minint, right_maxint), expected);
1053 }
984 } 1054 }
985 1055
986 } // namespace gfx 1056 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698