Skip to content

Commit

Permalink
Deal with cyclic structures, avoid stack overflow in Lottie model
Browse files Browse the repository at this point in the history
  • Loading branch information
mymedia2 committed Feb 26, 2022
1 parent 7446363 commit e3c6318
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/lottie/lottieitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ static renderer::Layer *createLayerItem(model::Layer *layerData,
{
switch (layerData->mLayerType) {
case model::Layer::Type::Precomp: {
model::Composition *comp = layerData->extra()->mCompRef;
if (comp && comp->mRootLayer->includes(layerData)) {
return nullptr;
}
return allocator->make<renderer::CompLayer>(layerData, allocator);
}
case model::Layer::Type::Solid: {
Expand Down
25 changes: 25 additions & 0 deletions src/lottie/lottiemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,27 @@
#include "lottiemodel.h"
#include <cassert>
#include <iterator>
#include <set>
#include <stack>
#include "vimageloader.h"
#include "vline.h"

using namespace rlottie::internal;

bool model::Group::includes(model::Group *pointer) {
if (this == pointer) {
return true;
}
for (Object *child : mChildren) {
if ((child->type() == Type::Group || child->type() == Type::Layer)
&& this != child
&& static_cast<Group *>(child)->includes(pointer)) {
return true;
}
}
return false;
}

/*
* We process the iterator objects in the children list
* by iterating from back to front. when we find a repeater object
Expand Down Expand Up @@ -79,6 +94,8 @@ class LottieRepeaterProcesser {

void visit(model::Object *obj)
{
if (!mVisited.insert(obj).second) return;

switch (obj->type()) {
case model::Object::Type::Group:
case model::Object::Type::Layer: {
Expand All @@ -89,6 +106,9 @@ class LottieRepeaterProcesser {
break;
}
}

private:
std::set<model::Object *> mVisited;
};

class LottieUpdateStatVisitor {
Expand Down Expand Up @@ -127,6 +147,8 @@ class LottieUpdateStatVisitor {
}
void visit(model::Object *obj)
{
if (!mVisited.insert(obj).second) return;

switch (obj->type()) {
case model::Object::Type::Layer: {
visitLayer(static_cast<model::Layer *>(obj));
Expand All @@ -144,6 +166,9 @@ class LottieUpdateStatVisitor {
break;
}
}

private:
std::set<model::Object *> mVisited;
};

void model::Composition::processRepeaterObjects()
Expand Down
1 change: 1 addition & 0 deletions src/lottie/lottiemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ class Group : public Object {
public:
Group() : Object(Object::Type::Group) {}
explicit Group(Object::Type type) : Object(type) {}
bool includes(Group *);

public:
std::vector<Object *> mChildren;
Expand Down

0 comments on commit e3c6318

Please sign in to comment.