diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 4c6af859..d385718c 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -849,10 +849,12 @@ LottieOffsetPath* LottieParser::parseOffsetPath() } -LottieObject* LottieParser::parseObject() +LottieObject* LottieParser::parseObject(const char* type) { - auto type = getString(); - if (!type) return nullptr; + if (!type) { + type = getString(); + if (!type) return nullptr; + } if (!strcmp(type, "gr")) return parseGroup(); else if (!strcmp(type, "rc")) return parseRect(); @@ -879,6 +881,24 @@ LottieObject* LottieParser::parseObject() void LottieParser::parseObject(Array& parent) { enterObject(); + + + //object type key is not listed as the first one + auto value = peekValue(); + if (value && strcmp(value->GetString(), "ty")) { + if (auto type = findObjectType()) { + if (auto child = parseObject(type)) { + if (child->hidden) delete (child); + else parent.push(child); + } else { + //skip unsupported type + while (nextObjectKey()) skip(); + } + free(type); + return; + } + } + //object type key either listed as the first one or never - skip the entire object while (auto key = nextObjectKey()) { if (KEY_AS("ty")) { if (auto child = parseObject()) { @@ -1081,20 +1101,7 @@ void LottieParser::parseTimeRemap(LottieLayer* layer) void LottieParser::parseShapes(Array& parent) { enterArray(); - while (nextArrayValue()) { - enterObject(); - while (auto key = nextObjectKey()) { - if (KEY_AS("it")) { - enterArray(); - while (nextArrayValue()) parseObject(parent); - } else if (KEY_AS("ty")) { - if (auto child = parseObject()) { - if (child->hidden) delete(child); - else parent.push(child); - } - } else skip(); - } - } + while (nextArrayValue()) parseObject(parent); } diff --git a/src/loaders/lottie/tvgLottieParser.h b/src/loaders/lottie/tvgLottieParser.h index aa1e85d5..9666fd2d 100644 --- a/src/loaders/lottie/tvgLottieParser.h +++ b/src/loaders/lottie/tvgLottieParser.h @@ -75,7 +75,7 @@ private: template void parseProperty(T& prop, LottieObject* obj = nullptr); template void parseSlotProperty(T& prop); - LottieObject* parseObject(); + LottieObject* parseObject(const char* type = nullptr); LottieObject* parseAsset(); void parseImage(LottieImage* image, const char* data, const char* subPath, bool embedded, float width, float height); LottieLayer* parseLayer(LottieLayer* precomp); diff --git a/src/loaders/lottie/tvgLottieParserHandler.cpp b/src/loaders/lottie/tvgLottieParserHandler.cpp index e5506f99..de454cf7 100644 --- a/src/loaders/lottie/tvgLottieParserHandler.cpp +++ b/src/loaders/lottie/tvgLottieParserHandler.cpp @@ -1,4 +1,4 @@ -/* + /* * Copyright (c) 2023 - 2025 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -43,6 +43,7 @@ */ #include "tvgLottieParserHandler.h" +#include "tvgStr.h" /************************************************************************/ @@ -184,6 +185,14 @@ int LookaheadParserHandler::peekType() } +Value* LookaheadParserHandler::peekValue() { + if (state >= kHasNull && state <= kHasKey) { + return &val; + } + return nullptr; +} + + void LookaheadParserHandler::skipOut(int depth) { do { @@ -233,6 +242,31 @@ void LookaheadParserHandler::skip() } +char* LookaheadParserHandler::findObjectType() +{ + auto level = 0; + for (auto p = iss.src_; *p != '\0'; ++p) { + if (*p == '{') level++; + else if (*p == '}') { + if (--level < 0) break; + } else if (level == 0) { + if (!strncmp(p, "\"ty\"", 4)) { + p += 4; + while (*p != '\0' && (isspace(*p) || *p == '\n')) ++p; + if (*p++ != ':') return nullptr; + while (*p != '\0' && (isspace(*p) || *p == '\n')) ++p; + if (*p++ != '\"') return nullptr; + const char* start = p; + while (*p != '\0' && *p != '\"') ++p; + if (*p == '\"') return strDuplicate(start, p - start); + return nullptr; + } + } + } + return nullptr; +} + + char* LookaheadParserHandler::getPos() { return iss.src_; diff --git a/src/loaders/lottie/tvgLottieParserHandler.h b/src/loaders/lottie/tvgLottieParserHandler.h index 6c595022..7e18d493 100644 --- a/src/loaders/lottie/tvgLottieParserHandler.h +++ b/src/loaders/lottie/tvgLottieParserHandler.h @@ -195,6 +195,8 @@ struct LookaheadParserHandler void skip(); void skipOut(int depth); int peekType(); + Value* peekValue(); + char* findObjectType(); char* getPos(); };