Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues revealed by fuzzing test #523

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
9 changes: 9 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 Expand Up @@ -1159,6 +1163,11 @@ void renderer::Polystar::updatePath(VPath &path, int frameNo)
path.reset();
VMatrix m;

if (!(points > 0)) {
vWarning << "The number of path points is below zero or NaN at all";
return;
}

if (mData->mPolyType == model::Polystar::PolyType::Star) {
path.addPolystar(points, innerRadius, outerRadius, innerRoundness,
outerRoundness, 0.0, 0.0, 0.0, mData->direction());
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
22 changes: 12 additions & 10 deletions src/lottie/lottiemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ struct PathData {

template <typename T, typename Tag = void>
struct Value {
T start_;
T end_;
T start_{};
T end_{};
T at(float t) const { return lerp(start_, end_, t); }
float angle(float) const { return 0; }
void cache() {}
Expand All @@ -168,10 +168,10 @@ struct Position;

template <typename T>
struct Value<T, Position> {
T start_;
T end_;
T inTangent_;
T outTangent_;
T start_{};
T end_{};
T inTangent_{};
T outTangent_{};
float length_{0};
bool hasTangent_{false};

Expand Down Expand Up @@ -340,6 +340,7 @@ class Property {
value().toPath(path);
} else {
const auto &vec = animation().frames_;
if (vec.empty()) return;
if (vec.front().start_ >= frameNo)
return vec.front().value_.start_.toPath(path);
if (vec.back().end_ <= frameNo)
Expand Down Expand Up @@ -659,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 Expand Up @@ -1053,17 +1055,17 @@ class Trim : public Object {
private:
Segment noloop(float start, float end) const
{
assert(start >= 0);
assert(end >= 0);
if (!(start >= 0)) start = 0;
if (!(end >= 0)) end = 0;
Segment s;
s.start = std::min(start, end);
s.end = std::max(start, end);
return s;
}
Segment loop(float start, float end) const
{
assert(start >= 0);
assert(end >= 0);
if (!(start >= 0)) start = 0;
if (!(end >= 0)) end = 0;
Segment s;
s.start = std::max(start, end);
s.end = std::min(start, end);
Expand Down
3 changes: 3 additions & 0 deletions src/vector/freetype/v_ft_stroker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "v_ft_stroker.h"
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "v_ft_math.h"
Expand Down Expand Up @@ -626,6 +627,8 @@ static SW_FT_Error ft_stroke_border_get_counts(SW_FT_StrokeBorder border,
static void ft_stroke_border_export(SW_FT_StrokeBorder border,
SW_FT_Outline* outline)
{
if ((unsigned long)outline->n_points + border->num_points > SHRT_MAX) return;

/* copy point locations */
memcpy(outline->points + outline->n_points, border->points,
border->num_points * sizeof(SW_FT_Vector));
Expand Down
8 changes: 7 additions & 1 deletion src/vector/vbezier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ float VBezier::length() const
if ((len - chord) > 0.01) {
VBezier left, right;
split(&left, &right);
return left.length() + right.length();

float sum = 0;
if (*this != left)
sum += left.length();
if (*this != right)
sum += right.length();
return sum;
}

return len;
Expand Down
13 changes: 13 additions & 0 deletions src/vector/vbezier.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@
#ifndef VBEZIER_H
#define VBEZIER_H

#include <tuple>
#include <vpoint.h>

V_BEGIN_NAMESPACE

class VBezier {
friend bool operator == (const VBezier &l, const VBezier &r);

public:
VBezier() = default;
VPointF pointAt(float t) const;
Expand Down Expand Up @@ -134,6 +137,16 @@ inline void VBezier::split(VBezier *firstHalf, VBezier *secondHalf) const
firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2) * 0.5f;
}

inline bool operator == (const VBezier &l, const VBezier &r)
{
return std::tie(l.x1, l.y1, l.x2, l.y2, l.x3, l.y3, l.x4, l.y4)
== std::tie(r.x1, r.y1, r.x2, r.y2, r.x3, r.y3, r.x4, r.y4);
}
inline bool operator != (const VBezier &l, const VBezier &r)
{
return !(l == r);
}

V_END_NAMESPACE

#endif // VBEZIER_H
1 change: 1 addition & 0 deletions src/vector/vraster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ struct VRleTask {
{
if (mPath.points().size() > SHRT_MAX ||
mPath.points().size() + mPath.segments() > SHRT_MAX) {
mRle.notify();
return;
}

Expand Down