Fix expression UAF

remo
This commit is contained in:
Jinny You 2025-02-20 23:25:58 +08:00
parent acdec3d294
commit 08609129e8
3 changed files with 13 additions and 10 deletions

View file

@ -937,6 +937,7 @@ struct LottieSlot
// used for expression // used for expression
LottieLayer* layer = nullptr; LottieLayer* layer = nullptr;
LottieObject* parent = nullptr;
}; };

View file

@ -26,7 +26,6 @@
#include "tvgLottieParser.h" #include "tvgLottieParser.h"
#include "tvgLottieExpressions.h" #include "tvgLottieExpressions.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
/************************************************************************/ /************************************************************************/
@ -469,6 +468,7 @@ void LottieParser::registerSlot(LottieObject* obj, const char* sid)
auto slot = new LottieSlot(strdup(sid), obj, type); auto slot = new LottieSlot(strdup(sid), obj, type);
slot->layer = context.layer; slot->layer = context.layer;
slot->parent = context.parent;
comp->slots.push(slot); comp->slots.push(slot);
} }
@ -1501,41 +1501,42 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
//OPTIMIZE: we can create the property directly, without object //OPTIMIZE: we can create the property directly, without object
LottieObject* obj = nullptr; //slot object LottieObject* obj = nullptr; //slot object
context.layer = slot->layer; context.layer = slot->layer;
context.parent = slot->parent;
switch (slot->type) { switch (slot->type) {
case LottieProperty::Type::Position: { case LottieProperty::Type::Position: {
obj = new LottieTransform; obj = new LottieTransform;
context.parent = obj; // context.parent = obj;
parseSlotProperty<LottieProperty::Type::Position>(static_cast<LottieTransform*>(obj)->position); parseSlotProperty<LottieProperty::Type::Position>(static_cast<LottieTransform*>(obj)->position);
break; break;
} }
case LottieProperty::Type::Point: { case LottieProperty::Type::Point: {
obj = new LottieTransform; obj = new LottieTransform;
context.parent = obj; // context.parent = obj;
parseSlotProperty<LottieProperty::Type::Point>(static_cast<LottieTransform*>(obj)->scale); parseSlotProperty<LottieProperty::Type::Point>(static_cast<LottieTransform*>(obj)->scale);
break; break;
} }
case LottieProperty::Type::Float: { case LottieProperty::Type::Float: {
obj = new LottieTransform; obj = new LottieTransform;
context.parent = obj; // context.parent = obj;
parseSlotProperty<LottieProperty::Type::Float>(static_cast<LottieTransform*>(obj)->rotation); parseSlotProperty<LottieProperty::Type::Float>(static_cast<LottieTransform*>(obj)->rotation);
break; break;
} }
case LottieProperty::Type::Opacity: { case LottieProperty::Type::Opacity: {
obj = new LottieSolid; obj = new LottieSolid;
context.parent = obj; // context.parent = obj;
parseSlotProperty<LottieProperty::Type::Opacity>(static_cast<LottieSolid*>(obj)->opacity); parseSlotProperty<LottieProperty::Type::Opacity>(static_cast<LottieSolid*>(obj)->opacity);
break; break;
} }
case LottieProperty::Type::Color: { case LottieProperty::Type::Color: {
obj = new LottieSolid; obj = new LottieSolid;
context.parent = obj; // context.parent = obj;
parseSlotProperty<LottieProperty::Type::Color>(static_cast<LottieSolid*>(obj)->color); parseSlotProperty<LottieProperty::Type::Color>(static_cast<LottieSolid*>(obj)->color);
break; break;
} }
case LottieProperty::Type::ColorStop: { case LottieProperty::Type::ColorStop: {
obj = new LottieGradient; obj = new LottieGradient;
context.parent = obj; // context.parent = obj;
while (auto key = nextObjectKey()) { while (auto key = nextObjectKey()) {
if (KEY_AS("p")) parseColorStop(static_cast<LottieGradient*>(obj)); if (KEY_AS("p")) parseColorStop(static_cast<LottieGradient*>(obj));
else skip(); else skip();
@ -1544,7 +1545,7 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
} }
case LottieProperty::Type::TextDoc: { case LottieProperty::Type::TextDoc: {
obj = new LottieText; obj = new LottieText;
context.parent = obj; // context.parent = obj;
parseSlotProperty<LottieProperty::Type::TextDoc>(static_cast<LottieText*>(obj)->doc); parseSlotProperty<LottieProperty::Type::TextDoc>(static_cast<LottieText*>(obj)->doc);
break; break;
} }
@ -1553,7 +1554,7 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
if (KEY_AS("p")) obj = parseAsset(); if (KEY_AS("p")) obj = parseAsset();
else skip(); else skip();
} }
context.parent = obj; // context.parent = obj;
break; break;
} }
default: break; default: break;
@ -1566,7 +1567,7 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
slot->assign(obj, byDefault); slot->assign(obj, byDefault);
// delete(obj); // 여기서 expression을 위한 property가 free 됨 (수정필요) delete(obj);
return true; return true;
} }

View file

@ -369,6 +369,7 @@ struct LottieGenericProperty : LottieProperty
// TODO: 슬롯 데이터 이전 로직에 expression에 대한 정보 추가 필요 // TODO: 슬롯 데이터 이전 로직에 expression에 대한 정보 추가 필요
if (rhs.exp) { if (rhs.exp) {
exp = rhs.exp; exp = rhs.exp;
exp->property = this; // Slot JSON obj의 프로퍼티를 바라보면 안되므로, exp를 덮어씌울 때는 반드시 원본 obj의 property를 지정해주어야함. otherwise heap UAF
const_cast<LottieGenericProperty<Frame, Value, Scalar>&>(rhs).exp = nullptr; const_cast<LottieGenericProperty<Frame, Value, Scalar>&>(rhs).exp = nullptr;
} }
} }