[core] make sprite metrics checking stricter
- check that sprite metrics are within the bounds of the sprite. fix #714 - make sprite metrics problems Errors instead of Warnings - check for negative image width, height
This commit is contained in:
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user