diff options
-rw-r--r-- | src/mbgl/sprite/sprite_parser.cpp | 16 | ||||
-rw-r--r-- | test/sprite/sprite_parser.cpp | 43 |
2 files changed, 19 insertions, 40 deletions
diff --git a/src/mbgl/sprite/sprite_parser.cpp b/src/mbgl/sprite/sprite_parser.cpp index 9baf933177..9fbca51112 100644 --- a/src/mbgl/sprite/sprite_parser.cpp +++ b/src/mbgl/sprite/sprite_parser.cpp @@ -20,9 +20,10 @@ SpriteImagePtr createSpriteImage(const PremultipliedImage& image, const double ratio, const bool sdf) { // Disallow invalid parameter configurations. - if (width == 0 || height == 0 || ratio <= 0 || ratio > 10 || width > 1024 || - height > 1024) { - Log::Warning(Event::Sprite, "Can't create sprite with invalid metrics"); + if (width <= 0 || height <= 0 || width > 1024 || height > 1024 || + ratio <= 0 || ratio > 10 || + srcX + width > image.width || srcY + height > image.height) { + Log::Error(Event::Sprite, "Can't create sprite with invalid metrics"); return nullptr; } @@ -31,16 +32,11 @@ SpriteImagePtr createSpriteImage(const PremultipliedImage& image, auto srcData = reinterpret_cast<const uint32_t*>(image.data.get()); auto dstData = reinterpret_cast<uint32_t*>(dstImage.data.get()); - const int32_t maxX = std::min(uint32_t(image.width), uint32_t(width + srcX)) - srcX; - assert(maxX <= int32_t(image.width)); - const int32_t maxY = std::min(uint32_t(image.height), uint32_t(height + srcY)) - srcY; - assert(maxY <= int32_t(image.height)); - // Copy from the source image into our individual sprite image - for (uint16_t y = 0; y < maxY; ++y) { + for (uint16_t y = 0; y < height; ++y) { const auto dstRow = y * width; const auto srcRow = (y + srcY) * image.width + srcX; - for (uint16_t x = 0; x < maxX; ++x) { + for (uint16_t x = 0; x < width; ++x) { dstData[dstRow + x] = srcData[srcRow + x]; } } diff --git a/test/sprite/sprite_parser.cpp b/test/sprite/sprite_parser.cpp index 6ac155468a..318911674e 100644 --- a/test/sprite/sprite_parser.cpp +++ b/test/sprite/sprite_parser.cpp @@ -29,13 +29,20 @@ TEST(Sprite, SpriteImageCreationInvalid) { ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 0, 16, 1, false)); // width == 0 ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 0, 1, false)); // height == 0 + ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, -1, 16, 1, false)); // width < 0 + ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, -1, 1, false)); // height < 0 ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, 0, false)); // ratio == 0 + ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, -1, false)); // ratio < 0 ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, 23, false)); // ratio too large ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 2048, 16, 1, false)); // too wide ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 1025, 1, false)); // too tall + ASSERT_EQ(nullptr, createSpriteImage(image_1x, -1, 0, 16, 16, 1, false)); // srcX < 0 + ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, -1, 16, 16, 1, false)); // srcY < 0 + ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, image_1x.width + 1, 16, 1, false)); // right edge out of bounds + ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, image_1x.height + 1, 1, false)); // bottom edge out of bounds - EXPECT_EQ(6u, log.count({ - EventSeverity::Warning, + EXPECT_EQ(13u, log.count({ + EventSeverity::Error, Event::Sprite, int64_t(-1), "Can't create sprite with invalid metrics", @@ -59,30 +66,6 @@ TEST(Sprite, SpriteImageCreation1x) { EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1x-museum.png"), sprite->image); } - - { // outside image == blank - const auto sprite = createSpriteImage(image_1x, 200, 0, 16, 16, 1, false); - ASSERT_TRUE(sprite.get()); - EXPECT_EQ(16, sprite->getWidth()); - EXPECT_EQ(16, sprite->getHeight()); - EXPECT_EQ(16, sprite->image.width); - EXPECT_EQ(16, sprite->image.height); - EXPECT_EQ(1, sprite->pixelRatio); - EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1x-blank.png"), - sprite->image); - } - - { // outside image == blank - const auto sprite = createSpriteImage(image_1x, 0, 300, 16, 16, 1, false); - ASSERT_TRUE(sprite.get()); - EXPECT_EQ(16, sprite->getWidth()); - EXPECT_EQ(16, sprite->getHeight()); - EXPECT_EQ(16, sprite->image.width); - EXPECT_EQ(16, sprite->image.height); - EXPECT_EQ(1, sprite->pixelRatio); - EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1x-blank.png"), - sprite->image); - } } TEST(Sprite, SpriteImageCreation2x) { @@ -242,7 +225,7 @@ TEST(Sprite, SpriteParsingEmptyImage) { EXPECT_EQ(0u, images.size()); EXPECT_EQ(1u, log.count({ - EventSeverity::Warning, + EventSeverity::Error, Event::Sprite, int64_t(-1), "Can't create sprite with invalid metrics", @@ -275,7 +258,7 @@ TEST(Sprite, SpriteParsingWidthTooBig) { "Value of 'width' must be an integer between 0 and 65535", })); EXPECT_EQ(1u, log.count({ - EventSeverity::Warning, + EventSeverity::Error, Event::Sprite, int64_t(-1), "Can't create sprite with invalid metrics", @@ -298,7 +281,7 @@ TEST(Sprite, SpriteParsingNegativeWidth) { "Value of 'width' must be an integer between 0 and 65535", })); EXPECT_EQ(1u, log.count({ - EventSeverity::Warning, + EventSeverity::Error, Event::Sprite, int64_t(-1), "Can't create sprite with invalid metrics", @@ -315,7 +298,7 @@ TEST(Sprite, SpriteParsingNullRatio) { EXPECT_EQ(0u, images.size()); EXPECT_EQ(1u, log.count({ - EventSeverity::Warning, + EventSeverity::Error, Event::Sprite, int64_t(-1), "Can't create sprite with invalid metrics", |