Fail early with bad blend modes. Diffs= 5ad13845d Fail early with bad blend modes. (#7302) Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index 1563e51..8e96435 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -973ff2276f928634e964fafb2d74f11a1cb9d29c +5ad13845d3ca1a130b61fb16e6c3627356e31f79
diff --git a/include/rive/drawable.hpp b/include/rive/drawable.hpp index 547d6b5..ca5e996 100644 --- a/include/rive/drawable.hpp +++ b/include/rive/drawable.hpp
@@ -46,6 +46,8 @@ return (static_cast<DrawableFlag>(drawableFlags()) & DrawableFlag::Opaque) == DrawableFlag::Opaque; } + + StatusCode onAddedDirty(CoreContext* context) override; }; } // namespace rive
diff --git a/include/rive/importers/import_stack.hpp b/include/rive/importers/import_stack.hpp index c80986b..ae03495 100644 --- a/include/rive/importers/import_stack.hpp +++ b/include/rive/importers/import_stack.hpp
@@ -72,18 +72,29 @@ StatusCode resolve() { + StatusCode returnCode = StatusCode::Ok; + + // Reverse iterate the last added import stack objects and resolve them. + // If any don't resolve, capture the return code and stop resolving. for (auto itr = m_LastAdded.rbegin(); itr != m_LastAdded.rend(); itr++) { StatusCode code = (*itr)->resolve(); - delete *itr; if (code != StatusCode::Ok) { - return code; + returnCode = code; + break; } } + + // Clean the import stack before returning the resolve code. + for (ImportStackObject* stackObject : m_LastAdded) + { + delete stackObject; + } m_Latests.clear(); m_LastAdded.clear(); - return StatusCode::Ok; + + return returnCode; } ~ImportStack()
diff --git a/src/drawable.cpp b/src/drawable.cpp index 5f41d68..2f01c79 100644 --- a/src/drawable.cpp +++ b/src/drawable.cpp
@@ -7,6 +7,37 @@ using namespace rive; +StatusCode Drawable::onAddedDirty(CoreContext* context) +{ + auto code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + auto blendMode = static_cast<rive::BlendMode>(blendModeValue()); + switch (blendMode) + { + case rive::BlendMode::srcOver: + case rive::BlendMode::screen: + case rive::BlendMode::overlay: + case rive::BlendMode::darken: + case rive::BlendMode::lighten: + case rive::BlendMode::colorDodge: + case rive::BlendMode::colorBurn: + case rive::BlendMode::hardLight: + case rive::BlendMode::softLight: + case rive::BlendMode::difference: + case rive::BlendMode::exclusion: + case rive::BlendMode::multiply: + case rive::BlendMode::hue: + case rive::BlendMode::saturation: + case rive::BlendMode::color: + case rive::BlendMode::luminosity: + return StatusCode::Ok; + } + return StatusCode::InvalidObject; +} + void Drawable::addClippingShape(ClippingShape* shape) { m_ClippingShapes.push_back(shape); } ClipResult Drawable::clip(Renderer* renderer) const
diff --git a/src/file.cpp b/src/file.cpp index 183aa50..83edfc6 100644 --- a/src/file.cpp +++ b/src/file.cpp
@@ -174,14 +174,14 @@ auto file = std::unique_ptr<File>(new File(factory, assetLoader)); auto readResult = file->read(reader, header); + if (result) + { + *result = readResult; + } if (readResult != ImportResult::success) { file.reset(nullptr); } - if (result) - { - *result = ImportResult::success; - } return file; }
diff --git a/test/assets/solar-system.riv b/test/assets/solar-system.riv new file mode 100644 index 0000000..acb0b98 --- /dev/null +++ b/test/assets/solar-system.riv Binary files differ
diff --git a/test/file_test.cpp b/test/file_test.cpp index 504014c..03ca35c 100644 --- a/test/file_test.cpp +++ b/test/file_test.cpp
@@ -38,6 +38,15 @@ REQUIRE(file->artboard("One") != nullptr); } +TEST_CASE("file with bad blend mode fails to load", "[file]") +{ + std::vector<uint8_t> bytes = ReadFile("../../test/assets/solar-system.riv"); + + rive::ImportResult result; + auto file = rive::File::import(bytes, &gNoOpFactory, &result, nullptr); + CHECK(result == rive::ImportResult::malformed); +} + TEST_CASE("file with animation can be read", "[file]") { auto file = ReadRiveFile("../../test/assets/juice.riv");