Auto merge of #15469 - stshine:no-integer-overflow, r=emilio

layout: Fix integer overflow when computing size of replace elements

<!-- Please describe your changes on the following line: -->

When calculating size of replaced element that has intrinsic aspect ratio, we need to multiply the ratio if one of the dimensions has definite size. And we can not precompute the ratio and store it as a float, because doing so may result one pixel difference in calculation for certain images, thus make some tests fail. So it may overflow when the dimension lengths are large, and this pull request convert them to `i64` before multiplication.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #15249 (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15469)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-02-09 06:21:29 -08:00 committed by GitHub
commit 384391da68

View file

@ -1051,7 +1051,8 @@ impl Fragment {
// Note: We can not precompute the ratio and store it as a float, because
// doing so may result one pixel difference in calculation for certain
// images, thus make some tests fail.
inline_size * intrinsic_block_size.0 / intrinsic_inline_size.0
Au((inline_size.0 as i64 * intrinsic_block_size.0 as i64 /
intrinsic_inline_size.0 as i64) as i32)
} else {
intrinsic_block_size
};
@ -1060,7 +1061,8 @@ impl Fragment {
(MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => {
let block_size = block_constraint.clamp(block_size);
let inline_size = if self.has_intrinsic_ratio() {
block_size * intrinsic_inline_size.0 / intrinsic_block_size.0
Au((block_size.0 as i64 * intrinsic_inline_size.0 as i64 /
intrinsic_block_size.0 as i64) as i32)
} else {
intrinsic_inline_size
};
@ -1075,10 +1077,11 @@ impl Fragment {
// First, create two rectangles that keep aspect ratio while may be clamped
// by the contraints;
let first_isize = inline_constraint.clamp(intrinsic_inline_size);
let first_bsize = first_isize * intrinsic_block_size.0 / intrinsic_inline_size.0;
let first_bsize = Au((first_isize.0 as i64 * intrinsic_block_size.0 as i64 /
intrinsic_inline_size.0 as i64) as i32);
let second_bsize = block_constraint.clamp(intrinsic_block_size);
let second_isize = second_bsize * intrinsic_inline_size.0 / intrinsic_block_size.0;
let second_isize = Au((second_bsize.0 as i64 * intrinsic_inline_size.0 as i64 /
intrinsic_block_size.0 as i64) as i32);
let (inline_size, block_size) = match (first_isize.cmp(&intrinsic_inline_size) ,
second_isize.cmp(&intrinsic_inline_size)) {
(Ordering::Equal, Ordering::Equal) =>