Skip to content

Commit

Permalink
some more tokenizer error checks
Browse files Browse the repository at this point in the history
  • Loading branch information
nem0 committed Jul 7, 2017
1 parent 8713970 commit 80c3552
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 46 deletions.
65 changes: 20 additions & 45 deletions src/ofbx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,22 +402,20 @@ static OptionalError<DataView> readLongString(Cursor* cursor)

static OptionalError<Property*> readProperty(Cursor* cursor)
{
Property* prop = new Property;
if (cursor->current == cursor->end) return Error("Reading past the end");

std::unique_ptr<Property> prop = std::make_unique<Property>();
prop->next = nullptr;
prop->type = *cursor->current;
++cursor->current;
prop->value.begin = cursor->current;

switch (prop->type)
{
case 'S':
case 'S':
{
OptionalError<DataView> val = readLongString(cursor);
if (val.isError())
{
delete prop;
return Error();
}
if (val.isError()) return Error();
prop->value = val.getValue();
break;
}
Expand All @@ -430,11 +428,8 @@ static OptionalError<Property*> readProperty(Cursor* cursor)
case 'R':
{
OptionalError<u32> len = read<u32>(cursor);
if (len.isError())
{
delete prop;
return Error();
}
if (len.isError()) return Error();
if (cursor->current + len.getValue() > cursor->end) return Error("Reading past the end");
cursor->current += len.getValue();
break;
}
Expand All @@ -447,20 +442,16 @@ static OptionalError<Property*> readProperty(Cursor* cursor)
OptionalError<u32> length = read<u32>(cursor);
OptionalError<u32> encoding = read<u32>(cursor);
OptionalError<u32> comp_len = read<u32>(cursor);
if (length.isError() | encoding.isError() | comp_len.isError())
{
delete prop;
return Error();
}
if (length.isError() | encoding.isError() | comp_len.isError()) return Error();
if (cursor->current + comp_len.getValue() > cursor->end) return Error("Reading past the end");
cursor->current += comp_len.getValue();
break;
}
default:
delete prop;
return Error("Unknown property type");
}
prop->value.end = cursor->current;
return prop;
return prop.release();
}


Expand All @@ -479,7 +470,7 @@ static OptionalError<Element*> readElement(Cursor* cursor)
OptionalError<DataView> id = readShortString(cursor);
if (id.isError()) return Error();

Element* element = new Element;
std::unique_ptr<Element> element = std::make_unique<Element>();
element->first_property = nullptr;
element->id = id.getValue();

Expand All @@ -490,42 +481,30 @@ static OptionalError<Element*> readElement(Cursor* cursor)
for (u32 i = 0; i < prop_count.getValue(); ++i)
{
OptionalError<Property*> prop = readProperty(cursor);
if (prop.isError())
{
delete element;
return Error();
}
if (prop.isError()) return Error();

*prop_link = prop.getValue();
prop_link = &(*prop_link)->next;
}

if (cursor->current - cursor->begin >= end_offset.getValue()) return element;
if (cursor->current - cursor->begin >= end_offset.getValue()) return element.release();

constexpr int BLOCK_SENTINEL_LENGTH = 13;

Element** link = &element->child;
while (cursor->current - cursor->begin < (end_offset.getValue() - BLOCK_SENTINEL_LENGTH))
{
OptionalError<Element*> child = readElement(cursor);
if (child.isError())
{
delete element;
return Error();
}
if (child.isError()) return Error();

*link = child.getValue();
link = &(*link)->sibling;
}

if (cursor->current + BLOCK_SENTINEL_LENGTH > cursor->end)
{
delete element;
return Error("Reading past the end");
}
if (cursor->current + BLOCK_SENTINEL_LENGTH > cursor->end) return Error("Reading past the end");

cursor->current += BLOCK_SENTINEL_LENGTH;
return element;
return element.release();
}


Expand All @@ -539,7 +518,7 @@ static OptionalError<Element*> tokenize(const u8* data, size_t size)
const Header* header = (const Header*)cursor.current;
cursor.current += sizeof(*header);

Element* root = new Element;
std::unique_ptr<Element> root = std::make_unique<Element>();
root->first_property = nullptr;
root->id.begin = nullptr;
root->id.end = nullptr;
Expand All @@ -550,16 +529,12 @@ static OptionalError<Element*> tokenize(const u8* data, size_t size)
for (;;)
{
OptionalError<Element*> child = readElement(&cursor);
if (child.isError())
{
delete root;
return Error();
}
if (child.isError()) return Error();
*element = child.getValue();
if (!*element) return root;
if (!*element) return root.release();
element = &(*element)->sibling;
}
return root;
return root.release();
}


Expand Down
4 changes: 3 additions & 1 deletion src/ofbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,13 @@ struct IScene
virtual IElement* getRootElement() const = 0;
virtual Object* getRoot() const = 0;
virtual const TakeInfo* getTakeInfo(const char* name) const = 0;
virtual ~IScene() {}
virtual int getMeshCount() const = 0;
virtual const Mesh* getMesh(int index) const = 0;
virtual int getAnimationStackCount() const = 0;
virtual const AnimationStack* getAnimationStack(int index) const = 0;

protected:
virtual ~IScene() {}
};


Expand Down

0 comments on commit 80c3552

Please sign in to comment.