Index: cc/resources/resource.h |
diff --git a/cc/resources/resource.h b/cc/resources/resource.h |
index 0e3c3df688387b9ee927f150737bc8dd37a7a6b7..676ca6dd0f46df6de58681b654f87e5d02a3dd59 100644 |
--- a/cc/resources/resource.h |
+++ b/cc/resources/resource.h |
@@ -5,6 +5,7 @@ |
#ifndef CC_RESOURCES_RESOURCE_H_ |
#define CC_RESOURCES_RESOURCE_H_ |
+#include "base/numerics/safe_math.h" |
#include "cc/base/cc_export.h" |
#include "cc/resources/resource_provider.h" |
#include "ui/gfx/geometry/size.h" |
@@ -22,14 +23,46 @@ class CC_EXPORT Resource { |
ResourceId id() const { return id_; } |
gfx::Size size() const { return size_; } |
ResourceFormat format() const { return format_; } |
- size_t bytes() const; |
- inline static size_t MemorySizeBytes(const gfx::Size& size, |
+ // Return true if the call to UncheckedMemorySizeBytes would return a value |
+ // that fits in a size_t. |
+ static bool VerifySizeInBytes(const gfx::Size& size, |
+ ResourceFormat format, |
+ size_t* bytes) { |
+ if (size.IsEmpty()) { |
+ if (bytes) |
+ *bytes = 0; |
+ return true; |
+ } |
+ |
+ base::CheckedNumeric<size_t> checked_value = BitsPerPixel(format); |
+ checked_value *= size.width(); |
+ checked_value *= size.height(); |
+ if (!checked_value.IsValid()) |
+ return false; |
+ size_t value = checked_value.ValueOrDie(); |
+ if ((value % 8) != 0) |
+ return false; |
+ if (bytes) |
+ *bytes = value / 8; |
danakj
2015/06/04 22:43:49
Eh, you're adding this optional pointer thing just
vmpstr
2015/06/04 23:17:30
Done.
|
+ return true; |
+ } |
+ |
+ static size_t CheckedMemorySizeBytes(const gfx::Size& size, |
ResourceFormat format) { |
- DCHECK_EQ(0, (BitsPerPixel(format) * size.width() * size.height()) % 8); |
- // TODO(vmpstr): Make this function overflow safe. crbug.com/495867 |
- return static_cast<size_t>( |
- (BitsPerPixel(format) * size.width() * size.height()) / 8); |
+ size_t bytes = 0; |
+ bool is_valid = VerifySizeInBytes(size, format, &bytes); |
+ CHECK(is_valid); |
+ return bytes; |
+ } |
+ |
+ inline static size_t UncheckedMemorySizeBytes(const gfx::Size& size, |
+ ResourceFormat format) { |
+ if (size.IsEmpty()) |
+ return 0; |
+ DCHECK(VerifySizeInBytes(size, format, nullptr)); |
+ return static_cast<size_t>(BitsPerPixel(format)) * size.width() * |
+ size.height() / 8; |
} |
protected: |