Skip to content

Commit 670c84e

Browse files
committed
1.20.21 - TypeTreeHelper.cpp - slots check fix
1 parent b2b893b commit 670c84e

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

UnityPy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "1.20.20"
1+
__version__ = "1.20.21"
22

33
from .environment import Environment as Environment
44
from .helpers.ArchiveStorageManager import (

UnityPyBoost/TypeTreeHelper.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
485485
// dict iterator values
486486
PyObject *key, *value = nullptr;
487487
Py_ssize_t pos;
488+
// slots check
489+
PyObject *slots = nullptr;
488490

489491
if (node->_data_type == NodeDataType::PPtr)
490492
{
@@ -518,6 +520,16 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
518520
}
519521
PyErr_Clear();
520522

523+
// if __slots__ is defined, setattr for non-slots attributes will fail
524+
// so we can skip the extra field check
525+
slots = PyObject_GetAttrString(clz, "__slots__");
526+
if (PyTuple_Check(slots) && PyTuple_GET_SIZE(slots) > 0)
527+
{
528+
Py_XDECREF(slots);
529+
goto PARSE_CLASS_UNKNOWN;
530+
}
531+
Py_XDECREF(slots);
532+
521533
// possibly extra fields
522534
annotations = get_annotations(clz);
523535
if (annotations == nullptr)
@@ -533,11 +545,6 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
533545
{
534546
continue;
535547
}
536-
if (PyObject_HasAttrString(clz, "__slots__"))
537-
{
538-
// if __slots__ is defined, setattr for non-slots attributes will fail
539-
goto PARSE_CLASS_UNKNOWN;
540-
}
541548
PyObject *extra_value = PyDict_GetItem(kwargs, child->_clean_name); // - borrowed ref +/- 0
542549
PyDict_SetItem(extras, child->_clean_name, extra_value); // +1
543550
PyDict_DelItem(kwargs, child->_clean_name); // -1
@@ -570,10 +577,13 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
570577
clz = PyObject_GetAttrString(config->classes, "UnknownObject");
571578
PyDict_SetItemString(kwargs, "__node__", (PyObject *)node);
572579
// merge extras back into kwargs
573-
pos = 0;
574-
while (PyDict_Next(extras, &pos, &key, &value))
580+
if (extras != nullptr)
575581
{
576-
PyDict_SetItem(kwargs, key, value);
582+
pos = 0;
583+
while (PyDict_Next(extras, &pos, &key, &value))
584+
{
585+
PyDict_SetItem(kwargs, key, value);
586+
}
577587
}
578588
instance = PyObject_Call(clz, args, kwargs);
579589
}

0 commit comments

Comments
 (0)