Skip to content

Commit

Permalink
Fix gigantic memory leak with FName::ToString
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Oct 22, 2023
1 parent 40870d6 commit b14e344
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 12 deletions.
12 changes: 7 additions & 5 deletions shared/sdk/AActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "ScriptRotator.hpp"
#include "UCameraComponent.hpp"
#include "TArray.hpp"
#include "FMalloc.hpp"

#include "AActor.hpp"

Expand Down Expand Up @@ -219,23 +220,24 @@ std::vector<UActorComponent*> AActor::get_components_by_class(UClass* uclass) {
TArray<UActorComponent*> ReturnValue{}; // 0x8
}; // Size: 0x18

static Params_K2_GetComponentsByClass params{};

Params_K2_GetComponentsByClass params{};
params.ComponentClass = uclass;

this->process_event(func, &params);

std::vector<UActorComponent*> ret{};

for (int i = 0; i < params.ReturnValue.count; ++i) {
ret.push_back(params.ReturnValue.data[i]);
if (params.ReturnValue.data != nullptr) {
for (int i = 0; i < params.ReturnValue.count; ++i) {
ret.push_back(params.ReturnValue.data[i]);
}
}

return ret;
}

std::vector<UActorComponent*> AActor::get_all_components() {
const auto actor_component_t = sdk::find_uobject<sdk::UClass>(L"Class /Script/Engine.ActorComponent");
static const auto actor_component_t = sdk::find_uobject<sdk::UClass>(L"Class /Script/Engine.ActorComponent");

if (actor_component_t == nullptr) {
return {};
Expand Down
8 changes: 4 additions & 4 deletions shared/sdk/CVar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ bool IConsoleCommand::Execute(const wchar_t* args) {
}

bool IConsoleCommand::Execute(const std::vector<std::wstring>& args) {
std::vector<sdk::TArray<wchar_t>> args_vec{};
std::vector<sdk::TArrayLite<wchar_t>> args_vec{};

for (const auto& arg : args) {
auto& arr = args_vec.emplace_back();
Expand All @@ -758,7 +758,7 @@ bool IConsoleCommand::Execute(const std::vector<std::wstring>& args) {
}

FakeOutputDevice fake_output_device{};
sdk::TArray<sdk::TArray<wchar_t>> fake_args_vec{};
sdk::TArrayLite<sdk::TArrayLite<wchar_t>> fake_args_vec{};

fake_args_vec.data = args_vec.data();
fake_args_vec.count = args_vec.size();
Expand All @@ -768,7 +768,7 @@ bool IConsoleCommand::Execute(const std::vector<std::wstring>& args) {
return execute_internal(fake_args_vec, nullptr, &fake_output_device);
}

bool IConsoleCommand::execute_internal(const sdk::TArray<sdk::TArray<wchar_t>>& args, void* world, void* output_device) {
bool IConsoleCommand::execute_internal(const sdk::TArrayLite<sdk::TArrayLite<wchar_t>>& args, void* world, void* output_device) {
const auto info = locate_vtable_indices();

if (!info) {
Expand All @@ -782,7 +782,7 @@ bool IConsoleCommand::execute_internal(const sdk::TArray<sdk::TArray<wchar_t>>&
return false;
}

using ExecuteFn = bool(*)(IConsoleCommand*, sdk::TArray<sdk::TArray<wchar_t>> const*, void*, void*);
using ExecuteFn = bool(*)(IConsoleCommand*, sdk::TArrayLite<sdk::TArrayLite<wchar_t>> const*, void*, void*);
const auto func = (*(ExecuteFn**)this)[info->execute_index];

return func(this, &args, world, output_device);
Expand Down
2 changes: 1 addition & 1 deletion shared/sdk/CVar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ struct IConsoleCommand : IConsoleObject {
bool Execute(const std::vector<std::wstring>& args);

protected:
bool execute_internal(const sdk::TArray<sdk::TArray<wchar_t>>& args, void* world, void* output_device);
bool execute_internal(const sdk::TArrayLite<sdk::TArrayLite<wchar_t>>& args, void* world, void* output_device);
};

struct IConsoleVariable : IConsoleObject {
Expand Down
1 change: 0 additions & 1 deletion shared/sdk/FMalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ FMalloc* FMalloc::get() {
}

uint32_t distance_from_ret = 0;

utility::exhaustive_decode((uint8_t*)fn, 100, [&](utility::ExhaustionContext& ctx) -> utility::ExhaustionResult {
++distance_from_ret;
return utility::ExhaustionResult::CONTINUE;
Expand Down
7 changes: 6 additions & 1 deletion shared/sdk/FName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,11 @@ std::wstring FName::to_string() const {

fn(this, &buffer);

return buffer.data;
if (buffer.data != nullptr) {
std::wstring result = buffer.data;
return result;
}

return std::wstring{};
}
}
19 changes: 19 additions & 0 deletions shared/sdk/TArray.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
#pragma once

#include <sdk/FMalloc.hpp>

namespace sdk {
template<typename T>
struct TArrayLite {
T* data{nullptr};
int32_t count{0};
int32_t capacity{0};
};

template<typename T>
struct TArray {
~TArray() {
if (data == nullptr) {
return;
}

if (auto m = FMalloc::get(); m != nullptr) {
m->free(data);
}
}

T* data{nullptr};
int32_t count{0};
int32_t capacity{0};
Expand Down

0 comments on commit b14e344

Please sign in to comment.