From 5a7ec3cdecb05e2c38b32737020a60eed8469182 Mon Sep 17 00:00:00 2001 From: glaba13 Date: Thu, 16 Aug 2018 19:01:46 -0400 Subject: [PATCH 1/3] Fix memory leaks --- mask-resource-animation.cpp | 16 +++++- mask-resource-material.cpp | 16 +++++- mask-resource-morph.cpp | 4 ++ mask-resource-skinned-model.cpp | 13 +++++ mask.cpp | 97 +++++++++++++++++++++++++++++---- 5 files changed, 130 insertions(+), 16 deletions(-) diff --git a/mask-resource-animation.cpp b/mask-resource-animation.cpp index 0f775bd..b5ee4e4 100644 --- a/mask-resource-animation.cpp +++ b/mask-resource-animation.cpp @@ -121,16 +121,20 @@ Mask::Resource::Animation::Animation(Mask::MaskData* parent, std::string name, o obs_data_t* chand = obs_data_item_get_obj(el); if (!chand) continue; - + AnimationChannel channel; if (!obs_data_has_user_value(chand, S_NAME)) { + obs_data_release(chand); + obs_data_release(channels); PLOG_ERROR("Animation '%s' channel has no name.", name.c_str()); throw std::logic_error("Animation channel has no name."); } std::string itemName = obs_data_get_string(chand, S_NAME); if (!obs_data_has_user_value(chand, S_TYPE)) { + obs_data_release(chand); + obs_data_release(channels); PLOG_ERROR("Animation '%s' channel has no type.", name.c_str()); throw std::logic_error("Animation channel has no type."); } @@ -148,23 +152,31 @@ Mask::Resource::Animation::Animation(Mask::MaskData* parent, std::string name, o } if (!obs_data_has_user_value(chand, S_PRESTATE)) { + obs_data_release(chand); + obs_data_release(channels); PLOG_ERROR("Animation '%s' channel has no pre state.", name.c_str()); throw std::logic_error("Animation channel has no pre state."); } channel.preState = AnimationBehaviourFromString(obs_data_get_string(chand, S_PRESTATE)); if (!obs_data_has_user_value(chand, S_POSTSTATE)) { + obs_data_release(chand); + obs_data_release(channels); PLOG_ERROR("Animation '%s' channel has no pose state.", name.c_str()); throw std::logic_error("Animation channel has no post state."); } channel.postState = AnimationBehaviourFromString(obs_data_get_string(chand, S_POSTSTATE)); if (!obs_data_has_user_value(chand, S_VALUES)) { + obs_data_release(chand); + obs_data_release(channels); PLOG_ERROR("Animation '%s' channel has no values.", name.c_str()); throw std::logic_error("Animation channel has no values."); } const char* base64data = obs_data_get_string(chand, S_VALUES); if (base64data[0] == '\0') { + obs_data_release(chand); + obs_data_release(channels); PLOG_ERROR("Animation '%s' channel has empty values data.", name.c_str()); throw std::logic_error("Animation channel has empty values data."); } @@ -174,7 +186,9 @@ Mask::Resource::Animation::Animation(Mask::MaskData* parent, std::string name, o channel.values.assign((float*)decoded.data(), (float*)decoded.data() + numFloats); m_channels.emplace_back(channel); + obs_data_release(chand); } + obs_data_release(channels); } Mask::Resource::Animation::~Animation() {} diff --git a/mask-resource-material.cpp b/mask-resource-material.cpp index f27cbc8..f24bed6 100644 --- a/mask-resource-material.cpp +++ b/mask-resource-material.cpp @@ -176,10 +176,10 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs obs_data_t* eld = obs_data_item_get_obj(el); if (!eld) continue; - if (!obs_data_has_user_value(eld, "type")) - continue; - if (!obs_data_has_user_value(eld, "value")) + if (!obs_data_has_user_value(eld, "type")|| !obs_data_has_user_value(eld, "value")) { + obs_data_release(eld); continue; + } std::string type = obs_data_get_string(eld, "type"); if (type == "texture" || type == "image" || type == "sequence") { @@ -203,6 +203,7 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs if (vector) { param.intArray[0] = (int32_t)obs_data_get_int(vector, "x"); param.intArray[1] = (int32_t)obs_data_get_int(vector, "y"); + obs_data_release(vector); } m_parameters.emplace(parameterName, param); } else if (type == "integer3") { @@ -213,6 +214,7 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs param.intArray[0] = (int32_t)obs_data_get_int(vector, "x"); param.intArray[1] = (int32_t)obs_data_get_int(vector, "y"); param.intArray[2] = (int32_t)obs_data_get_int(vector, "z"); + obs_data_release(vector); } m_parameters.emplace(parameterName, param); } else if (type == "integer4") { @@ -224,6 +226,7 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs param.intArray[1] = (int32_t)obs_data_get_int(vector, "y"); param.intArray[2] = (int32_t)obs_data_get_int(vector, "z"); param.intArray[3] = (int32_t)obs_data_get_int(vector, "w"); + obs_data_release(vector); } m_parameters.emplace(parameterName, param); } else if (type == "integer[]") { @@ -240,6 +243,7 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs if (vector) { param.floatArray[0] = (float_t)obs_data_get_double(vector, "x"); param.floatArray[1] = (float_t)obs_data_get_double(vector, "y"); + obs_data_release(vector); } m_parameters.emplace(parameterName, param); } else if (type == "float3") { @@ -250,6 +254,7 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs param.floatArray[0] = (float_t)obs_data_get_double(vector, "x"); param.floatArray[1] = (float_t)obs_data_get_double(vector, "y"); param.floatArray[2] = (float_t)obs_data_get_double(vector, "z"); + obs_data_release(vector); } m_parameters.emplace(parameterName, param); } else if (type == "float4") { @@ -261,6 +266,7 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs param.floatArray[1] = (float_t)obs_data_get_double(vector, "y"); param.floatArray[2] = (float_t)obs_data_get_double(vector, "z"); param.floatArray[3] = (float_t)obs_data_get_double(vector, "w"); + obs_data_release(vector); } m_parameters.emplace(parameterName, param); } else if (type == "float[]") { @@ -274,10 +280,14 @@ Mask::Resource::Material::Material(Mask::MaskData* parent, std::string name, obs obs_data_get_vec4(vector, "y", &(param.matrix.x)); obs_data_get_vec4(vector, "z", &(param.matrix.x)); obs_data_get_vec4(vector, "w", &(param.matrix.x)); + obs_data_release(vector); } m_parameters.emplace(parameterName, param); } + obs_data_release(eld); } + if(prmd) + obs_data_release(prmd); } } diff --git a/mask-resource-morph.cpp b/mask-resource-morph.cpp index fe00919..e70bd2f 100644 --- a/mask-resource-morph.cpp +++ b/mask-resource-morph.cpp @@ -72,6 +72,10 @@ Mask::Resource::Morph::Morph(Mask::MaskData* parent, std::string name, obs_data_ // sanity check numPoints++; } + if (deltasItem) { + obs_data_item_release(&deltasItem); + } + obs_data_release(deltasData); // sanity check if (numPoints > smll::NUM_MORPH_LANDMARKS) { PLOG_ERROR("Bad deltas section in '%s'. Too many deltas.", name.c_str()); diff --git a/mask-resource-skinned-model.cpp b/mask-resource-skinned-model.cpp index 8d722d9..a6aaab7 100644 --- a/mask-resource-skinned-model.cpp +++ b/mask-resource-skinned-model.cpp @@ -132,6 +132,7 @@ Mask::Resource::SkinnedModel::SkinnedModel(Mask::MaskData* parent, std::string n position.x, position.y, position.z); matrix4_identity(&bone.global); + obs_data_release(boneData); } // Skins list @@ -187,6 +188,18 @@ Mask::Resource::SkinnedModel::SkinnedModel(Mask::MaskData* parent, std::string n } m_skins.emplace_back(skin); + obs_data_release(skinData); + obs_data_release(skinBonesData); + if (skinBonesItem) { + obs_data_item_release(&skinBonesItem); + } + } + obs_data_release(skinsData); + if (bonesItem) { + obs_data_item_release(&bonesItem); + } + if (skinsItem) { + obs_data_item_release(&skinsItem); } } diff --git a/mask.cpp b/mask.cpp index 4d0ecf7..bb9df38 100644 --- a/mask.cpp +++ b/mask.cpp @@ -210,10 +210,15 @@ void Mask::MaskData::Load(const std::string& file) { file.c_str()); return; } + for (obs_data_item_t* itm = obs_data_first(partData); itm; obs_data_item_next(&itm)) { std::string name = obs_data_item_get_name(itm); GetPart(name); } + obs_data_release(partData); + if (partDataItem) { + obs_data_item_release(&partDataItem); + } // yield ::Sleep(0); @@ -225,13 +230,20 @@ void Mask::MaskData::Load(const std::string& file) { obs_data_t* resd = obs_data_item_get_obj(el); if (!resd) continue; - if (!obs_data_has_user_value(resd, JSON_TYPE)) + if (!obs_data_has_user_value(resd, JSON_TYPE)) { + obs_data_release(resd); continue; + } std::string resourceType = obs_data_get_string(resd, JSON_TYPE); if (resourceType == "animation") { m_animations.emplace(resourceName, std::dynamic_pointer_cast(GetResource(resourceName))); } + obs_data_release(resd); + } + + if (resources) { + obs_data_release(resources); } } @@ -267,24 +279,51 @@ std::shared_ptr Mask::MaskData::GetResource(const std::st // Lazy Loaded obs_data_item_t* resources = obs_data_item_byname(m_data, JSON_RESOURCES); if (!resources) return nullptr; - if (obs_data_item_gettype(resources) != OBS_DATA_OBJECT) return nullptr; + if (obs_data_item_gettype(resources) != OBS_DATA_OBJECT) { + obs_data_item_release(&resources); + return nullptr; + } obs_data_t* resd = obs_data_item_get_obj(resources); - if (!resd) return nullptr; + if (!resd) { + obs_data_item_release(&resources); + return nullptr; + } obs_data_item_t* element = obs_data_item_byname(resd, name.c_str()); - if (!element) return nullptr; + if (!element) { + obs_data_item_release(&resources); + obs_data_release(resd); + return nullptr; + } if (obs_data_item_gettype(element) != OBS_DATA_OBJECT) return nullptr; obs_data_t* elmd = obs_data_item_get_obj(element); - if (!elmd) return nullptr; + if (!elmd) { + obs_data_item_release(&element); + obs_data_item_release(&resources); + obs_data_release(resd); + return nullptr; + } try { auto res = Resource::IBase::Load(this, name, elmd); if (res) { this->AddResource(name, res); + obs_data_item_release(&element); + obs_data_item_release(&resources); + obs_data_release(resd); + obs_data_release(elmd); return res; } } catch (...) { PLOG_DEBUG("Resource %s has THROWN AN EXCEPTION. MASK DID NOT LOAD CORRECTLY.", name.c_str()); + obs_data_item_release(&element); + obs_data_item_release(&resources); + obs_data_release(resd); + obs_data_release(elmd); return nullptr; } + obs_data_item_release(&element); + obs_data_item_release(&resources); + obs_data_release(resd); + obs_data_release(elmd); return nullptr; } @@ -360,16 +399,43 @@ std::shared_ptr Mask::MaskData::GetPart(const std::string& name) { // Lazy Loaded obs_data_item_t* parts = obs_data_item_byname(m_data, JSON_PARTS); - if (!parts) return nullptr; - if (obs_data_item_gettype(parts) != OBS_DATA_OBJECT) return nullptr; + if (!parts) { + return nullptr; + } + if (obs_data_item_gettype(parts) != OBS_DATA_OBJECT) { + obs_data_item_release(&parts); + return nullptr; + } obs_data_t* resd = obs_data_item_get_obj(parts); - if (!resd) return nullptr; + if (!resd) { + obs_data_item_release(&parts); + return nullptr; + } obs_data_item_t* element = obs_data_item_byname(resd, name.c_str()); - if (!element) return nullptr; - if (obs_data_item_gettype(element) != OBS_DATA_OBJECT) return nullptr; + if (!element) { + obs_data_item_release(&parts); + obs_data_release(resd); + return nullptr; + } + if (obs_data_item_gettype(element) != OBS_DATA_OBJECT) { + obs_data_item_release(&parts); + obs_data_item_release(&element); + obs_data_release(resd); + return nullptr; + } obs_data_t* elmd = obs_data_item_get_obj(element); - if (!elmd) return nullptr; - return LoadPart(name, elmd); + if (!elmd) { + obs_data_item_release(&parts); + obs_data_item_release(&element); + obs_data_release(resd); + return nullptr; + } + std::shared_ptr res = LoadPart(name, elmd); + obs_data_item_release(&parts); + obs_data_item_release(&element); + obs_data_release(resd); + obs_data_release(elmd); + return res; } std::shared_ptr Mask::MaskData::RemovePart(const std::string& name) { @@ -618,12 +684,19 @@ std::shared_ptr Mask::MaskData::LoadPart(std::string name, obs_data_ obs_data_t* rezData = obs_data_item_get_obj(rezItem); if (!rezData) { PLOG_ERROR("Bad resources section in '%s'.", name.c_str()); + if (rezItem) { + obs_data_item_release(&rezItem); + } return current; } for (obs_data_item_t* itm = obs_data_first(rezData); itm; obs_data_item_next(&itm)) { std::string resourceName = obs_data_item_get_string(itm); current->resources.push_back(GetResource(resourceName)); } + if (rezItem) { + obs_data_item_release(&rezItem); + } + obs_data_release(rezData); } // Parent From e1ed310362bc66b27dc19b891b12c058ff823a8f Mon Sep 17 00:00:00 2001 From: glaba13 Date: Thu, 16 Aug 2018 19:06:10 -0400 Subject: [PATCH 2/3] Refactor code --- mask-resource-animation.cpp | 2 +- mask.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mask-resource-animation.cpp b/mask-resource-animation.cpp index b5ee4e4..eb64df5 100644 --- a/mask-resource-animation.cpp +++ b/mask-resource-animation.cpp @@ -121,7 +121,7 @@ Mask::Resource::Animation::Animation(Mask::MaskData* parent, std::string name, o obs_data_t* chand = obs_data_item_get_obj(el); if (!chand) continue; - + AnimationChannel channel; if (!obs_data_has_user_value(chand, S_NAME)) { diff --git a/mask.cpp b/mask.cpp index bb9df38..ca4fab7 100644 --- a/mask.cpp +++ b/mask.cpp @@ -210,7 +210,6 @@ void Mask::MaskData::Load(const std::string& file) { file.c_str()); return; } - for (obs_data_item_t* itm = obs_data_first(partData); itm; obs_data_item_next(&itm)) { std::string name = obs_data_item_get_name(itm); GetPart(name); From eb319f073c4e8399b85e3ed61f5cfc96a52a96f1 Mon Sep 17 00:00:00 2001 From: glaba13 Date: Thu, 16 Aug 2018 19:08:54 -0400 Subject: [PATCH 3/3] Refactor code --- mask-resource-animation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mask-resource-animation.cpp b/mask-resource-animation.cpp index eb64df5..b5ee4e4 100644 --- a/mask-resource-animation.cpp +++ b/mask-resource-animation.cpp @@ -121,7 +121,7 @@ Mask::Resource::Animation::Animation(Mask::MaskData* parent, std::string name, o obs_data_t* chand = obs_data_item_get_obj(el); if (!chand) continue; - + AnimationChannel channel; if (!obs_data_has_user_value(chand, S_NAME)) {