Core: Fix memory leaks with PySequence_GetItem

This commit is contained in:
wmayer
2024-05-08 23:40:27 +02:00
parent 5b98af4591
commit 58988a7482
6 changed files with 63 additions and 66 deletions

View File

@@ -217,10 +217,10 @@ static const std::map<std::string, int> &getStatusMap() {
return statusMap;
}
PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args)
PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args)
{
char* name;
PyObject *pyValue;
char* name {};
PyObject* pyValue {};
if (!PyArg_ParseTuple(args, "sO", &name, &pyValue))
return nullptr;
@@ -232,47 +232,51 @@ PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args)
auto linkProp = Base::freecad_dynamic_cast<App::PropertyLinkBase>(prop);
std::bitset<32> status(prop->getStatus());
size_t count = 1;
bool isSeq = false;
std::vector<Py::Object> items;
if (PyList_Check(pyValue) || PyTuple_Check(pyValue)) {
isSeq = true;
count = PySequence_Size(pyValue);
Py::Sequence seq(pyValue);
for (const auto& it : seq) {
items.emplace_back(it);
}
}
else {
items.emplace_back(pyValue);
}
for(size_t i=0; i<count; ++i) {
Py::Object item;
if (isSeq)
item = Py::Object(PySequence_GetItem(pyValue,i));
else
item = Py::Object(pyValue);
for (const auto& item : items) {
bool value = true;
if (item.isString()) {
const auto &statusMap = getStatusMap();
auto v = static_cast<std::string>(Py::String(item));
if(v.size()>1 && v[0] == '-') {
if (v.size() > 1 && v[0] == '-') {
value = false;
v = v.substr(1);
}
auto it = statusMap.find(v);
if(it == statusMap.end()) {
if(linkProp && v == "AllowPartial") {
if (it == statusMap.end()) {
if (linkProp && v == "AllowPartial") {
linkProp->setAllowPartial(value);
continue;
}
PyErr_Format(PyExc_ValueError, "Unknown property status '%s'", v.c_str());
return nullptr;
}
status.set(it->second,value);
status.set(it->second, value);
}
else if (item.isNumeric()) {
int v = Py::Int(item);
if(v<0) {
if (v < 0) {
value = false;
v = -v;
}
if(v==0 || v>31)
if (v == 0 || v > 31) {
PyErr_Format(PyExc_ValueError, "Status value out of range '%d'", v);
status.set(v,value);
return nullptr;
}
status.set(v, value);
}
else {
PyErr_SetString(PyExc_TypeError, "Expects status type to be Int or String");