Skip to content

Commit bfd881c

Browse files
committed
fix(TypeTreeHelper): check if array size < 0, add TypeTreeNode.__repr__
1 parent 62bf310 commit bfd881c

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

UnityPy/helpers/TypeTreeHelper.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ def read_value(
199199

200200
# size = read_value(node.m_Children[0].m_Children[0], reader, as_dict)
201201
size = reader.read_int()
202+
if size < 0:
203+
raise ValueError("Negative length read from TypeTree")
202204
subtype = node.m_Children[0].m_Children[1]
203205
if metaflag_is_aligned(subtype.m_MetaFlag):
204206
value = read_value_array(subtype, reader, config, size)

UnityPy/helpers/TypeTreeNode.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class TypeTreeNodeC:
4444
def __attrs_post_init__(self):
4545
self._clean_name = clean_name(self.m_Name)
4646

47+
def __repr__(self):
48+
return f"TypeTreeNode(m_Level={self.m_Level}, m_Type='{self.m_Type}', \
49+
m_Name='{self.m_Name}', m_MetaFlag={self.m_MetaFlag})"
50+
4751

4852
TYPETREENODE_KEYS = [
4953
"m_Level",

UnityPyBoost/TypeTreeHelper.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ inline bool _read_length(ReaderT *reader, int32_t *length)
295295
{
296296
swap_any_inplace(length);
297297
}
298+
if (*length < 0)
299+
{
300+
PyErr_SetString(PyExc_ValueError, "Negative length read from TypeTree");
301+
return false;
302+
}
298303
reader->ptr += sizeof(int32_t);
299304
return true;
300305
}
@@ -346,12 +351,12 @@ inline PyObject *read_pair(ReaderT *reader, TypeTreeNodeObject *node, TypeTreeRe
346351
}
347352

348353
PyObject *first = read_typetree_value<swap>(reader, (TypeTreeNodeObject *)PyList_GET_ITEM(node->m_Children, 0), config);
349-
if (!first)
354+
if (first == NULL)
350355
{
351356
return NULL;
352357
}
353358
PyObject *second = read_typetree_value<swap>(reader, (TypeTreeNodeObject *)PyList_GET_ITEM(node->m_Children, 1), config);
354-
if (!second)
359+
if (second == NULL)
355360
{
356361
Py_DECREF(first);
357362
return NULL;
@@ -380,13 +385,13 @@ inline PyObject *read_pair_array(ReaderT *reader, TypeTreeNodeObject *node, Type
380385
for (auto i = 0; i < count; i++)
381386
{
382387
PyObject *first = read_typetree_value<swap>(reader, first_child, config);
383-
if (!first)
388+
if (first == NULL)
384389
{
385390
Py_DECREF(list);
386391
return NULL;
387392
}
388393
PyObject *second = read_typetree_value<swap>(reader, second_child, config);
389-
if (!second)
394+
if (second == NULL)
390395
{
391396
Py_DECREF(first);
392397
Py_DECREF(list);
@@ -422,7 +427,7 @@ inline PyObject *read_class(ReaderT *reader, TypeTreeNodeObject *node, TypeTreeR
422427
}
423428
}
424429
PyObject *child_value = read_typetree_value<swap>(reader, child, config); // child_value: 1 refcount
425-
if (!child_value)
430+
if (child_value == NULL)
426431
{
427432
Py_DECREF(value); // value: 0 refcount
428433
return NULL;
@@ -488,6 +493,11 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
488493
// slots check
489494
PyObject *slots = nullptr;
490495

496+
if (kwargs == NULL)
497+
{
498+
return NULL;
499+
}
500+
491501
if (node->_data_type == NodeDataType::PPtr)
492502
{
493503
clz = PyObject_GetAttrString(config->classes, "PPtr");
@@ -792,7 +802,7 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
792802
child_value = read_typetree_value<swap>(reader, child, config);
793803
}
794804

795-
if (!child_value)
805+
if (child_value == NULL)
796806
{
797807
Py_DECREF(value);
798808
return NULL;
@@ -857,7 +867,7 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
857867
for (int i = 0; i < length; i++)
858868
{
859869
PyObject *item = read_typetree_value<swap>(reader, child, config);
860-
if (!item)
870+
if (item == NULL)
861871
{
862872
Py_DECREF(value);
863873
return NULL;
@@ -885,7 +895,7 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
885895
}
886896
}
887897

888-
if (align)
898+
if (align && value != NULL)
889899
{
890900
align4(reader);
891901
}
@@ -940,7 +950,7 @@ PyObject *read_typetree_value_array(ReaderT *reader, TypeTreeNodeObject *node, T
940950
default:
941951
value = PyErr_Format(PyExc_ValueError, "Unsupported type for read_typetree_value_array: %d", node->_data_type);
942952
}
943-
if (align)
953+
if (align && value != NULL)
944954
{
945955
align4(reader);
946956
}
@@ -1050,7 +1060,7 @@ PyObject *read_typetree(PyObject *self, PyObject *args, PyObject *kwargs)
10501060
Py_XDECREF(config.assetfile);
10511061
Py_XDECREF(config.classes);
10521062

1053-
return Py_BuildValue("(Nn)", value, bytes_read);
1063+
return (value != NULL) ? Py_BuildValue("(Nn)", value, bytes_read) : NULL;
10541064
}
10551065

10561066
// TypeTreeNode impl
@@ -1206,6 +1216,16 @@ static int TypeTreeNode_init(TypeTreeNodeObject *self, PyObject *args, PyObject
12061216
return 0;
12071217
}
12081218

1219+
static PyObject *TypeTreeNode_repr(TypeTreeNodeObject *self)
1220+
{
1221+
return PyUnicode_FromFormat(
1222+
"TypeTreeNode(m_Level=%R, m_Type=%R, m_Name=%R, m_MetaFlag=%R)",
1223+
self->m_Level,
1224+
self->m_Type,
1225+
self->m_Name,
1226+
self->m_MetaFlag);
1227+
}
1228+
12091229
static PyMemberDef TypeTreeNode_members[] = {
12101230
{"m_Level", T_OBJECT_EX, offsetof(TypeTreeNodeObject, m_Level), 0, ""},
12111231
{"m_Type", T_OBJECT_EX, offsetof(TypeTreeNodeObject, m_Type), 0, ""},
@@ -1240,6 +1260,7 @@ static PyTypeObject TypeTreeNodeType = []() -> PyTypeObject
12401260
type.tp_init = (initproc)TypeTreeNode_init;
12411261
type.tp_members = TypeTreeNode_members;
12421262
type.tp_finalize = (destructor)TypeTreeNode_finalize;
1263+
type.tp_repr = (reprfunc)TypeTreeNode_repr;
12431264
return type;
12441265
}();
12451266

0 commit comments

Comments
 (0)