Chromium Code Reviews| Index: components/mus/public/cpp/lib/property_type_converters.cc |
| diff --git a/components/mus/public/cpp/lib/property_type_converters.cc b/components/mus/public/cpp/lib/property_type_converters.cc |
| index 2e1ff65818c014d568d7f3f3fddcd1b4bea7b94a..a64b0f1da6ec52476b5bba910914b55c3a195be5 100644 |
| --- a/components/mus/public/cpp/lib/property_type_converters.cc |
| +++ b/components/mus/public/cpp/lib/property_type_converters.cc |
| @@ -7,9 +7,19 @@ |
| #include <stdint.h> |
| #include "base/strings/utf_string_conversions.h" |
| +#include "third_party/skia/include/core/SkBitmap.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/size.h" |
| +namespace { |
| + |
| +// Maximum allowed height or width of a bitmap, in pixels. This limit prevents |
| +// malformed bitmap headers from causing arbitrarily large memory allocations |
| +// for pixel data. |
| +const int kMaxBitmapSize = 4096; |
| + |
| +} // namespace |
| + |
| namespace mojo { |
| // static |
| @@ -73,7 +83,7 @@ gfx::Size TypeConverter<gfx::Size, const std::vector<uint8_t>>::Convert( |
| const std::vector<uint8_t> |
| TypeConverter<const std::vector<uint8_t>, int32_t>::Convert( |
| const int32_t& input) { |
| - std::vector<uint8_t> vec(8); |
| + std::vector<uint8_t> vec(4); |
| vec[0] = (input >> 24) & 0xFF; |
| vec[1] = (input >> 16) & 0xFF; |
| vec[2] = (input >> 8) & 0xFF; |
| @@ -118,5 +128,74 @@ TypeConverter<std::string, const std::vector<uint8_t>>::Convert( |
| return std::string(input.begin(), input.end()); |
| } |
| -} // namespace mojo |
| +// static |
| +const std::vector<uint8_t> |
| +TypeConverter<const std::vector<uint8_t>, SkBitmap>::Convert( |
| + const SkBitmap& input) { |
| + // Empty images are valid to serialize and are represented by an empty vector. |
| + if (input.isNull()) |
| + return std::vector<uint8_t>(); |
| + |
| + // Only RGBA 8888 bitmaps with premultiplied alpha are supported. |
| + if (input.colorType() != kBGRA_8888_SkColorType || |
| + input.alphaType() != kPremul_SkAlphaType) { |
| + NOTREACHED(); |
| + return std::vector<uint8_t>(); |
| + } |
| + |
| + // Sanity check the bitmap size. |
| + int width = input.width(); |
| + int height = input.height(); |
| + if (width < 0 || width > kMaxBitmapSize || height < 0 || |
| + height > kMaxBitmapSize) { |
| + NOTREACHED(); |
| + return std::vector<uint8_t>(); |
| + } |
| + |
| + // Serialize the bitmap. The size is restricted so only 2 bytes are required |
| + // per dimension. |
| + std::vector<uint8_t> vec(4 + input.getSize()); |
| + vec[0] = (width >> 8) & 0xFF; |
| + vec[1] = width & 0xFF; |
| + vec[2] = (height >> 8) & 0xFF; |
| + vec[3] = height & 0xFF; |
| + if (!input.copyPixelsTo(&vec[4], input.getSize())) |
| + return std::vector<uint8_t>(); |
| + return vec; |
| +} |
| +// static |
| +SkBitmap TypeConverter<SkBitmap, const std::vector<uint8_t>>::Convert( |
| + const std::vector<uint8_t>& input) { |
| + // Empty images are represented by empty vectors. |
| + if (input.empty()) |
| + return SkBitmap(); |
| + |
| + // Read and sanity check size. |
| + int width = input[0] << 8 | input[1]; |
| + int height = input[2] << 8 | input[3]; |
| + if (width < 0 || width > kMaxBitmapSize || height < 0 || |
| + height > kMaxBitmapSize) { |
| + NOTREACHED(); |
| + return SkBitmap(); |
| + } |
| + |
| + // Try to allocate a bitmap of the appropriate size. |
| + SkBitmap bitmap; |
| + if (!bitmap.tryAllocPixels(SkImageInfo::Make( |
| + width, height, kBGRA_8888_SkColorType, kPremul_SkAlphaType))) { |
| + return SkBitmap(); |
| + } |
| + |
| + // Ensure the vector contains the right amount of data. |
| + if (input.size() != bitmap.getSize() + 4) { |
| + NOTREACHED(); |
| + return SkBitmap(); |
| + } |
| + |
| + // Read the pixel data. |
| + memcpy(bitmap.getPixels(), &input[4], bitmap.getSize()); |
|
sky
2016/03/25 15:56:34
Do you need to lock and unlock the pixels here?
James Cook
2016/03/25 16:52:39
Done.
|
| + return bitmap; |
| +} |
| + |
| +} // namespace mojo |