Chromium Code Reviews| 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: |