From 6f8504d3b9558c84f4fa3da85a2b1fd304a059af Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 9 Aug 2023 12:09:54 +0900 Subject: [PATCH] loader/lottie: ++safety - add an execeptional hanlding at parsing the assets. - The precomp layer failed to prepare its instance in the parsing stage. This corrects the mistake. --- src/lib/tvgAnimation.cpp | 3 +-- src/loaders/lottie/tvgLottieBuilder.cpp | 4 ++-- src/loaders/lottie/tvgLottieModel.h | 11 ++--------- src/loaders/lottie/tvgLottieParser.cpp | 20 ++++++++++---------- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/lib/tvgAnimation.cpp b/src/lib/tvgAnimation.cpp index f671daa7..f43cfe6c 100644 --- a/src/lib/tvgAnimation.cpp +++ b/src/lib/tvgAnimation.cpp @@ -31,7 +31,6 @@ struct Animation::Impl { - //TODO: Memory Safety Picture picture; }; @@ -41,7 +40,7 @@ struct Animation::Impl Animation::~Animation() { - + //FIXME: free pImpl } diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index d0eecf62..9887ad9b 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -370,15 +370,15 @@ static void _buildReference(LottieComposition* comp, LottieLayer* layer) { for (auto asset = comp->assets.data; asset < comp->assets.end(); ++asset) { if (strcmp(layer->refId, (*asset)->name)) continue; - auto assetLayer = static_cast(*asset); if (layer->type == LottieLayer::Precomp) { + auto assetLayer = static_cast(*asset); if (_buildPrecomp(comp, assetLayer)) { layer->children = assetLayer->children; } } else if (layer->type == LottieLayer::Image) { layer->children.push(*asset); } - layer->statical &= assetLayer->statical; + layer->statical &= (*asset)->statical; break; } } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index dff1e532..5028523c 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -349,12 +349,6 @@ struct LottieLayer : LottieGroup { enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text}; - LottieLayer() - { - autoOrient = false; - mask = false; - } - ~LottieLayer() { if (refId) { @@ -418,9 +412,8 @@ struct LottieLayer : LottieGroup } cache; Type type = Null; - - bool autoOrient : 1; - bool mask : 1; + bool autoOrient = false; + bool mask = false; }; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index c1e6035f..5481b7b1 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -806,9 +806,6 @@ void LottieParser::parseObject(LottieGroup* parent) LottieImage* LottieParser::parseImage(const char* key) { - auto image = new LottieImage; - if (!image) return nullptr; - //Used for Image Asset const char* data = nullptr; const char* subPath = nullptr; @@ -821,15 +818,14 @@ LottieImage* LottieParser::parseImage(const char* key) data = getString(); } else if (!strcmp(key, "e")) { embedded = getInt(); -#if 0 - } else if (!strcmp(key, "w")) { - auto w = getInt(); - } else if (!strcmp(key, "h")) { - auto h = getInt(); -#endif } else skip(key); } while ((key = nextObjectKey())); + if (!data) return nullptr; + + auto image = new LottieImage; + if (!image) return nullptr; + //embeded image resource. should start with "data:" //header look like "data:image/png;base64," so need to skip till ','. if (embedded && !strncmp(data, "data:", 5)) { @@ -877,13 +873,15 @@ LottieObject* LottieParser::parseAsset() //Precomposition asset } else if (!strcmp(key, "layers")) { obj = parseLayers(); + } else if (!strcmp(key, "w") || !strcmp(key, "h") || !strcmp(key, "nm") || !strcmp(key, "fr")) { + skip(key); //Image asset } else { obj = parseImage(key); break; } } - obj->name = id; + if (obj) obj->name = id; return obj; } @@ -1007,6 +1005,8 @@ LottieLayer* LottieParser::parseLayers() root->children.push(layer); } } + + root->prepare(); return root; }