Skip to content

Commit c7e44b2

Browse files
committed
C TypeTreeHelper - check for slots/setattr on clz
1 parent f40b121 commit c7e44b2

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

UnityPyBoost/TypeTreeHelper.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -533,16 +533,19 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
533533
{
534534
continue;
535535
}
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+
}
536541
PyObject *extra_value = PyDict_GetItem(kwargs, child->_clean_name); // - borrowed ref +/- 0
537542
PyDict_SetItem(extras, child->_clean_name, extra_value); // +1
538543
PyDict_DelItem(kwargs, child->_clean_name); // -1
539544
}
540545

541546
if (PyDict_Size(extras) == 0)
542547
{
543-
Py_DECREF(clz); // 1->0
544-
clz = PyObject_GetAttrString(config->classes, "UnknownObject"); // 0->1
545-
PyDict_SetItemString(kwargs, "__node__", (PyObject *)node);
548+
goto PARSE_CLASS_UNKNOWN;
546549
}
547550

548551
instance = PyObject_Call(clz, args, kwargs);
@@ -551,23 +554,29 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
551554
pos = 0;
552555
while (PyDict_Next(extras, &pos, &key, &value))
553556
{
554-
PyObject_GenericSetAttr(instance, key, value);
557+
if (PyObject_GenericSetAttr(instance, key, value) != 0)
558+
{
559+
Py_DECREF(instance);
560+
goto PARSE_CLASS_UNKNOWN;
561+
}
555562
}
556-
goto PARSE_CLASS_CLEANUP;
557563
}
558-
PyErr_Clear();
559-
560-
// if we still failed to create an instance, fallback to UnknownObject
561-
Py_DECREF(clz);
562-
clz = PyObject_GetAttrString(config->classes, "UnknownObject");
563-
PyDict_SetItemString(kwargs, "__node__", (PyObject *)node);
564-
// merge extras back into kwargs
565-
pos = 0;
566-
while (PyDict_Next(extras, &pos, &key, &value))
564+
else
567565
{
568-
PyDict_SetItem(kwargs, key, value);
566+
PARSE_CLASS_UNKNOWN:
567+
PyErr_Clear();
568+
// if we still failed to create an instance, fallback to UnknownObject
569+
Py_DECREF(clz);
570+
clz = PyObject_GetAttrString(config->classes, "UnknownObject");
571+
PyDict_SetItemString(kwargs, "__node__", (PyObject *)node);
572+
// merge extras back into kwargs
573+
pos = 0;
574+
while (PyDict_Next(extras, &pos, &key, &value))
575+
{
576+
PyDict_SetItem(kwargs, key, value);
577+
}
578+
instance = PyObject_Call(clz, args, kwargs);
569579
}
570-
instance = PyObject_Call(clz, args, kwargs);
571580

572581
PARSE_CLASS_CLEANUP:
573582
Py_DECREF(args);
@@ -852,7 +861,7 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
852861
{
853862
value = read_class<swap, true>(reader, node, config);
854863
}
855-
if (!config->as_dict)
864+
else
856865
{
857866
value = read_class<swap, false>(reader, node, config);
858867
value = parse_class(value, node, config);

0 commit comments

Comments
 (0)