Commit df19cc67 authored by David Quiroz Marin's avatar David Quiroz Marin Committed by Commit Bot

Fix float-cast-overflow in square root of pixels calculations.

Some of the canvas UMA histograms use the square root of total
pixels in an image or canvas in this CL uses CheckedNumeric to
avoid overflow.

Bug: 905314
Change-Id: I10a85c5c372406449a64f1e32153d58d560e901c
Reviewed-on: https://chromium-review.googlesource.com/c/1351519
Commit-Queue: David Quiroz Marin <davidqu@chromium.org>
Reviewed-by: default avatarFernando Serboncini <fserb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611916}
parent f4d9f4a9
...@@ -102,20 +102,27 @@ void RecordCompleteEncodingTimeHistogram(ImageEncodingMimeType mime_type, ...@@ -102,20 +102,27 @@ void RecordCompleteEncodingTimeHistogram(ImageEncodingMimeType mime_type,
void RecordScaledDurationHistogram(ImageEncodingMimeType mime_type, void RecordScaledDurationHistogram(ImageEncodingMimeType mime_type,
TimeDelta elapsed_time, TimeDelta elapsed_time,
int width, float width,
int height) { float height) {
float sqrt_pixels = std::sqrt(width * height); float sqrt_pixels = std::sqrt(width) * std::sqrt(height);
int scaled_time = float scaled_time_float =
elapsed_time.InMicrosecondsF() / (sqrt_pixels == 0 ? 1 : sqrt_pixels); elapsed_time.InMicrosecondsF() / (sqrt_pixels == 0 ? 1.0f : sqrt_pixels);
// If scaled_time_float overflows as integer, CheckedNumeric will store it
// as invalid, then ValueOrDefault will return the maximum int.
base::CheckedNumeric<int> checked_scaled_time = scaled_time_float;
int scaled_time_int =
checked_scaled_time.ValueOrDefault(std::numeric_limits<int>::max());
if (mime_type == kMimeTypePng) { if (mime_type == kMimeTypePng) {
UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToBlob.ScaledDuration.PNG", UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToBlob.ScaledDuration.PNG",
scaled_time); scaled_time_int);
} else if (mime_type == kMimeTypeJpeg) { } else if (mime_type == kMimeTypeJpeg) {
UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToBlob.ScaledDuration.JPEG", UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToBlob.ScaledDuration.JPEG",
scaled_time); scaled_time_int);
} else if (mime_type == kMimeTypeWebp) { } else if (mime_type == kMimeTypeWebp) {
UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToBlob.ScaledDuration.WEBP", UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToBlob.ScaledDuration.WEBP",
scaled_time); scaled_time_int);
} }
} }
......
...@@ -832,18 +832,25 @@ String HTMLCanvasElement::ToDataURLInternal( ...@@ -832,18 +832,25 @@ String HTMLCanvasElement::ToDataURLInternal(
String data_url = data_buffer->ToDataURL(encoding_mime_type, quality); String data_url = data_buffer->ToDataURL(encoding_mime_type, quality);
base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time; base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time;
float sqrt_pixels = float sqrt_pixels =
std::sqrt(image_bitmap->width() * image_bitmap->height()); std::sqrt(image_bitmap->width()) * std::sqrt(image_bitmap->height());
int scaled_time = float scaled_time_float = elapsed_time.InMicrosecondsF() /
elapsed_time.InMicrosecondsF() / (sqrt_pixels == 0 ? 1 : sqrt_pixels); (sqrt_pixels == 0 ? 1.0f : sqrt_pixels);
// If scaled_time_float overflows as integer, CheckedNumeric will store it
// as invalid, then ValueOrDefault will return the maximum int.
base::CheckedNumeric<int> checked_scaled_time = scaled_time_float;
int scaled_time_int =
checked_scaled_time.ValueOrDefault(std::numeric_limits<int>::max());
if (encoding_mime_type == kMimeTypePng) { if (encoding_mime_type == kMimeTypePng) {
UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToDataURLScaledDuration.PNG", UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToDataURLScaledDuration.PNG",
scaled_time); scaled_time_int);
} else if (encoding_mime_type == kMimeTypeJpeg) { } else if (encoding_mime_type == kMimeTypeJpeg) {
UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToDataURLScaledDuration.JPEG", UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToDataURLScaledDuration.JPEG",
scaled_time); scaled_time_int);
} else if (encoding_mime_type == kMimeTypeWebp) { } else if (encoding_mime_type == kMimeTypeWebp) {
UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToDataURLScaledDuration.WEBP", UMA_HISTOGRAM_COUNTS_100000("Blink.Canvas.ToDataURLScaledDuration.WEBP",
scaled_time); scaled_time_int);
} else { } else {
// Currently we only support three encoding types. // Currently we only support three encoding types.
NOTREACHED(); NOTREACHED();
......
...@@ -1310,12 +1310,18 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state, ...@@ -1310,12 +1310,18 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state,
duration_histogram_name.append(".CPU"); duration_histogram_name.append(".CPU");
} }
int sqrt_pixels = std::sqrt(dst_rect.Width() * dst_rect.Height());
base::TimeDelta elapsed = TimeTicks::Now() - start_time; base::TimeDelta elapsed = TimeTicks::Now() - start_time;
base::UmaHistogramMicrosecondsTimes(duration_histogram_name, elapsed); base::UmaHistogramMicrosecondsTimes(duration_histogram_name, elapsed);
base::UmaHistogramCustomCounts(size_histogram_name, sqrt_pixels, 1, 5000,
50); float sqrt_pixels_float =
std::sqrt(dst_rect.Width()) * std::sqrt(dst_rect.Height());
// If sqrt_pixels_float overflows as int CheckedNumeric will store it
// as invalid, then ValueOrDefault will return the maximum int.
base::CheckedNumeric<int> sqrt_pixels = sqrt_pixels_float;
base::UmaHistogramCustomCounts(
size_histogram_name,
sqrt_pixels.ValueOrDefault(std::numeric_limits<int>::max()), 1, 5000,
50);
} }
} }
...@@ -1678,13 +1684,18 @@ ImageData* BaseRenderingContext2D::getImageData( ...@@ -1678,13 +1684,18 @@ ImageData* BaseRenderingContext2D::getImageData(
return imageData; return imageData;
} }
int BaseRenderingContext2D::getScaledElapsedTime(int width, int BaseRenderingContext2D::getScaledElapsedTime(float width,
int height, float height,
base::TimeTicks start_time) { base::TimeTicks start_time) {
base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time; base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time;
float sqrt_pixels = std::sqrt(width * height); float sqrt_pixels = std::sqrt(width) * std::sqrt(height);
return elapsed_time.InMicrosecondsF() * 10.0f / float scaled_time_float = elapsed_time.InMicrosecondsF() * 10.0f /
(sqrt_pixels == 0 ? 1 : sqrt_pixels); (sqrt_pixels == 0 ? 1.0f : sqrt_pixels);
// If scaled_time_float overflows as integer, CheckedNumeric will store it
// as invalid, then ValueOrDefault will return the maximum int.
base::CheckedNumeric<int> checked_scaled_time = scaled_time_float;
return checked_scaled_time.ValueOrDefault(std::numeric_limits<int>::max());
} }
void BaseRenderingContext2D::putImageData(ImageData* data, void BaseRenderingContext2D::putImageData(ImageData* data,
......
...@@ -428,7 +428,9 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, ...@@ -428,7 +428,9 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
return false; return false;
} }
int getScaledElapsedTime(int width, int height, base::TimeTicks start_time); int getScaledElapsedTime(float width,
float height,
base::TimeTicks start_time);
bool origin_tainted_by_content_; bool origin_tainted_by_content_;
}; };
......
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