lottie/parser: revise logic to handle exceptional cases more gracefully

- prioritize valid (positive) cases first
- continue parsing even when encountering parsing errors

Co-Authored-By: Mira Grudzinska <mira@lottiefiles.com>
This commit is contained in:
Hermet Park 2025-05-07 13:46:31 +09:00 committed by Mira Grudzinska
parent ae84708f9b
commit 57adfbd499
2 changed files with 41 additions and 50 deletions

View file

@ -46,13 +46,6 @@
#include "tvgLottieParserHandler.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
static const int PARSE_FLAGS = kParseDefaultFlags | kParseInsituFlag;
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
@ -60,12 +53,12 @@ static const int PARSE_FLAGS = kParseDefaultFlags | kParseInsituFlag;
bool LookaheadParserHandler::enterArray()
{
if (state != kEnteringArray) {
Error();
return false;
if (state == kEnteringArray) {
parseNext();
return true;
}
parseNext();
return true;
Error();
return false;
}
@ -87,37 +80,37 @@ bool LookaheadParserHandler::nextArrayValue()
int LookaheadParserHandler::getInt()
{
if (state != kHasNumber) {
Error();
return 0;
if (state == kHasNumber) {
auto result = val.GetInt();
parseNext();
return result;
}
auto result = val.GetInt();
parseNext();
return result;
Error();
return 0;
}
float LookaheadParserHandler::getFloat()
{
if (state != kHasNumber) {
Error();
return 0;
if (state == kHasNumber) {
auto result = val.GetFloat();
parseNext();
return result;
}
auto result = val.GetFloat();
parseNext();
return result;
Error();
return 0;
}
const char* LookaheadParserHandler::getString()
{
if (state != kHasString) {
Error();
return nullptr;
if (state == kHasString) {
auto result = val.GetString();
parseNext();
return result;
}
auto result = val.GetString();
parseNext();
return result;
Error();
return nullptr;
}
@ -131,33 +124,29 @@ char* LookaheadParserHandler::getStringCopy()
bool LookaheadParserHandler::getBool()
{
if (state != kHasBool) {
Error();
return false;
if (state == kHasBool) {
auto result = val.GetBool();
parseNext();
return result;
}
auto result = val.GetBool();
parseNext();
return result;
Error();
return false;
}
void LookaheadParserHandler::getNull()
{
if (state != kHasNull) {
Error();
if (state == kHasNull) {
parseNext();
return;
}
parseNext();
Error();
}
bool LookaheadParserHandler::parseNext()
{
if (reader.HasParseError()) {
Error();
return false;
}
if (!reader.IterativeParseNext<PARSE_FLAGS>(iss, *this)) {
if (reader.HasParseError() || !reader.IterativeParseNext<PARSE_FLAGS>(iss, *this)) {
Error();
return false;
}
@ -167,12 +156,12 @@ bool LookaheadParserHandler::parseNext()
bool LookaheadParserHandler::enterObject()
{
if (state != kEnteringObject) {
Error();
return false;
if (state == kEnteringObject) {
parseNext();
return true;
}
parseNext();
return true;
Error();
return false;
}

View file

@ -51,6 +51,7 @@
using namespace rapidjson;
#define PARSE_FLAGS (kParseDefaultFlags | kParseInsituFlag)
struct LookaheadParserHandler
{
@ -172,8 +173,9 @@ struct LookaheadParserHandler
void Error()
{
TVGERR("LOTTIE", "Parsing Error!");
TVGERR("LOTTIE", "Invalid JSON: unexpected or misaligned data fields.");
state = kError;
reader.IterativeParseNext<PARSE_FLAGS>(iss, *this); //something wrong but try advancement.
}
bool Invalid()