Add more safety on some memory handling

This commit is contained in:
Lion Kortlepel
2020-11-04 14:35:28 +01:00
parent f2d87078ae
commit 36db73b562
6 changed files with 41 additions and 39 deletions

View File

@@ -7,8 +7,8 @@
#include <any> #include <any>
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
#include <mutex>
#include <memory> #include <memory>
#include <mutex>
#include <set> #include <set>
#include <thread> #include <thread>
#include <vector> #include <vector>
@@ -64,7 +64,7 @@ public:
std::string GetFileName() const; std::string GetFileName() const;
lua_State* GetState(); lua_State* GetState();
const lua_State* GetState() const; const lua_State* GetState() const;
char* GetOrigin(); std::string GetOrigin();
std::mutex Lock; std::mutex Lock;
void Reload(); void Reload();
Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false); Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
@@ -73,6 +73,6 @@ public:
void SetStopThread(bool StopThread) { _StopThread = StopThread; } void SetStopThread(bool StopThread) { _StopThread = StopThread; }
bool GetStopThread() const { return _StopThread; } bool GetStopThread() const { return _StopThread; }
}; };
int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* args); int CallFunction(Lua* lua, const std::string& FuncName, std::unique_ptr<LuaArg> args);
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait); int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::unique_ptr<LuaArg> arg, bool Wait);
extern std::set<std::unique_ptr<Lua>> PluginEngine; extern std::set<std::unique_ptr<Lua>> PluginEngine;

View File

@@ -20,7 +20,7 @@ typedef unsigned long DWORD, *PDWORD, *LPDWORD;
std::vector<std::string> QConsoleOut; std::vector<std::string> QConsoleOut;
std::string CInputBuff; std::string CInputBuff;
std::mutex MLock; std::mutex MLock;
Lua* LuaConsole; std::unique_ptr<Lua> LuaConsole;
void HandleInput(const std::string& cmd) { void HandleInput(const std::string& cmd) {
std::cout << std::endl; std::cout << std::endl;
if (cmd == "exit") { if (cmd == "exit") {
@@ -130,7 +130,7 @@ void SetupConsole() {
} }
void ConsoleInit() { void ConsoleInit() {
SetupConsole(); SetupConsole();
LuaConsole = new Lua(true); LuaConsole = std::make_unique<Lua>(true);
printf("> "); printf("> ");
std::thread In(ReadCin); std::thread In(ReadCin);
In.detach(); In.detach();

View File

@@ -13,10 +13,10 @@
#include <iostream> #include <iostream>
#include <utility> #include <utility>
LuaArg* CreateArg(lua_State* L, int T, int S) { std::unique_ptr<LuaArg> CreateArg(lua_State* L, int T, int S) {
if (S > T) if (S > T)
return nullptr; return nullptr;
auto* temp = new LuaArg; std::unique_ptr<LuaArg> temp(new LuaArg);
for (int C = S; C <= T; C++) { for (int C = S; C <= T; C++) {
if (lua_isstring(L, C)) { if (lua_isstring(L, C)) {
temp->args.emplace_back(std::string(lua_tostring(L, C))); temp->args.emplace_back(std::string(lua_tostring(L, C)));
@@ -52,11 +52,11 @@ void SendError(lua_State* L, const std::string& msg) {
} }
warn(a + Sec(" | Incorrect Call of ") + msg); warn(a + Sec(" | Incorrect Call of ") + msg);
} }
int Trigger(Lua* lua, const std::string& R, LuaArg* arg) { int Trigger(Lua* lua, const std::string& R, std::unique_ptr<LuaArg> arg) {
std::lock_guard<std::mutex> lockGuard(lua->Lock); std::lock_guard<std::mutex> lockGuard(lua->Lock);
std::packaged_task<int()> task([lua, R, arg] { return CallFunction(lua, R, arg); }); std::packaged_task<int(std::unique_ptr<LuaArg>)> task([lua, R](std::unique_ptr<LuaArg> arg) { return CallFunction(lua, R, std::move(arg)); });
std::future<int> f1 = task.get_future(); std::future<int> f1 = task.get_future();
std::thread t(std::move(task)); std::thread t(std::move(task), std::move(arg));
t.detach(); t.detach();
auto status = f1.wait_for(std::chrono::seconds(5)); auto status = f1.wait_for(std::chrono::seconds(5));
if (status != std::future_status::timeout) if (status != std::future_status::timeout)
@@ -64,11 +64,11 @@ int Trigger(Lua* lua, const std::string& R, LuaArg* arg) {
SendError(lua->GetState(), R + " took too long to respond"); SendError(lua->GetState(), R + " took too long to respond");
return 0; return 0;
} }
int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) { int FutureWait(Lua* lua, const std::string& R, std::unique_ptr<LuaArg> arg, bool Wait) {
Assert(lua); Assert(lua);
std::packaged_task<int()> task([lua, R, arg] { return Trigger(lua, R, arg); }); std::packaged_task<int(std::unique_ptr<LuaArg>)> task([lua, R](std::unique_ptr<LuaArg> arg) { return Trigger(lua, R, std::move(arg)); });
std::future<int> f1 = task.get_future(); std::future<int> f1 = task.get_future();
std::thread t(std::move(task)); std::thread t(std::move(task), std::move(arg));
t.detach(); t.detach();
int T = 0; int T = 0;
if (Wait) if (Wait)
@@ -78,16 +78,16 @@ int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) {
return f1.get(); return f1.get();
return 0; return 0;
} }
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait) { int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::unique_ptr<LuaArg> arg, bool Wait) {
int R = 0; int R = 0;
for (auto& Script : PluginEngine) { for (auto& Script : PluginEngine) {
if (Script->IsRegistered(Event)) { if (Script->IsRegistered(Event)) {
if (local) { if (local) {
if (Script->GetPluginName() == Caller->GetPluginName()) { if (Script->GetPluginName() == Caller->GetPluginName()) {
R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); R += FutureWait(Script.get(), Script->GetRegistered(Event), std::move(arg), Wait);
} }
} else } else
R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); R += FutureWait(Script.get(), Script->GetRegistered(Event), std::move(arg), Wait);
} }
} }
return R; return R;
@@ -553,15 +553,11 @@ void Lua::Reload() {
CallFunction(this, Sec("onInit"), nullptr); CallFunction(this, Sec("onInit"), nullptr);
} }
} }
char* Lua::GetOrigin() { std::string Lua::GetOrigin() {
std::string T = GetFileName().substr(GetFileName().find('\\')); return GetFileName().substr(GetFileName().find('\\'));
char* Data = new char[T.size()];
ZeroMemory(Data, T.size());
memcpy(Data, T.c_str(), T.size());
return Data;
} }
int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) { int CallFunction(Lua* lua, const std::string& FuncName, std::unique_ptr<LuaArg> Arg) {
lua_State* luaState = lua->GetState(); lua_State* luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str()); lua_getglobal(luaState, FuncName.c_str());
if (lua_isfunction(luaState, -1)) { if (lua_isfunction(luaState, -1)) {
@@ -569,11 +565,9 @@ int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) {
if (Arg != nullptr) { if (Arg != nullptr) {
Size = int(Arg->args.size()); Size = int(Arg->args.size());
Arg->PushArgs(luaState); Arg->PushArgs(luaState);
delete Arg;
Arg = nullptr;
} }
int R = 0; int R = 0;
char* Origin = lua->GetOrigin(); std::string Origin = lua->GetOrigin();
#ifdef WIN32 #ifdef WIN32
__try { __try {
#endif // WIN32 #endif // WIN32
@@ -584,10 +578,9 @@ int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) {
} }
} }
#ifdef WIN32 #ifdef WIN32
} __except (Handle(GetExceptionInformation(), Origin)) { } __except (Handle(GetExceptionInformation(), Origin.data())) {
} }
#endif // WIN32 #endif // WIN32
delete[] Origin;
} }
ClearStack(luaState); ClearStack(luaState);
return 0; return 0;
@@ -672,5 +665,6 @@ fs::file_time_type Lua::GetLastWrite() {
} }
Lua::~Lua() { Lua::~Lua() {
info("closing lua state");
lua_close(luaState); lua_close(luaState);
} }

View File

@@ -47,7 +47,8 @@ void VehicleParser(Client*c,const std::string& Pckt){
Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+"-"+std::to_string(CarID)+Packet.substr(4); Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+"-"+std::to_string(CarID)+Packet.substr(4);
if(c->GetCarCount() >= MaxCars || if(c->GetCarCount() >= MaxCars ||
TriggerLuaEvent(Sec("onVehicleSpawn"),false,nullptr, TriggerLuaEvent(Sec("onVehicleSpawn"),false,nullptr,
new LuaArg{{c->GetID(),CarID,Packet.substr(3)}},true)){ std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),CarID,Packet.substr(3)}}),
true)){
Respond(c,Packet,true); Respond(c,Packet,true);
std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(CarID); std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(CarID);
Respond(c,Destroy,true); Respond(c,Destroy,true);
@@ -67,7 +68,8 @@ void VehicleParser(Client*c,const std::string& Pckt){
} }
if(PID != -1 && VID != -1 && PID == c->GetID()){ if(PID != -1 && VID != -1 && PID == c->GetID()){
if(!TriggerLuaEvent(Sec("onVehicleEdited"),false,nullptr, if(!TriggerLuaEvent(Sec("onVehicleEdited"),false,nullptr,
new LuaArg{{c->GetID(),VID,Packet.substr(3)}},true)) { std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),VID,Packet.substr(3)}}),
true)) {
SendToAll(c, Packet, false, true); SendToAll(c, Packet, false, true);
Apply(c,VID,Packet); Apply(c,VID,Packet);
}else{ }else{
@@ -87,7 +89,7 @@ void VehicleParser(Client*c,const std::string& Pckt){
if(PID != -1 && VID != -1 && PID == c->GetID()){ if(PID != -1 && VID != -1 && PID == c->GetID()){
SendToAll(nullptr,Packet,true,true); SendToAll(nullptr,Packet,true,true);
TriggerLuaEvent(Sec("onVehicleDeleted"),false,nullptr, TriggerLuaEvent(Sec("onVehicleDeleted"),false,nullptr,
new LuaArg{{c->GetID(),VID}},false); std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),VID}}),false);
c->DeleteCar(VID); c->DeleteCar(VID);
debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID)); debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID));
} }
@@ -107,7 +109,7 @@ void SyncClient(Client*c){
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
Respond(c,Sec("Sn")+c->GetName(),true); Respond(c,Sec("Sn")+c->GetName(),true);
SendToAll(c,Sec("JWelcome ")+c->GetName()+"!",false,true); SendToAll(c,Sec("JWelcome ")+c->GetName()+"!",false,true);
TriggerLuaEvent(Sec("onPlayerJoin"),false,nullptr,new LuaArg{{c->GetID()}},false); TriggerLuaEvent(Sec("onPlayerJoin"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
for (Client*client : CI->Clients) { for (Client*client : CI->Clients) {
if(client != nullptr){ if(client != nullptr){
if (client != c) { if (client != c) {
@@ -144,7 +146,7 @@ void HandleEvent(Client*c ,const std::string&Data){
Name = t; Name = t;
break; break;
case 2: case 2:
TriggerLuaEvent(Name, false, nullptr,new LuaArg{{c->GetID(),t}},false); TriggerLuaEvent(Name, false, nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),t}}),false);
break; break;
default: default:
break; break;
@@ -189,9 +191,10 @@ void GlobalParser(Client*c, const std::string& Pack){
return; return;
case 'C': case 'C':
if(Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)break; if(Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)break;
if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,new LuaArg{ if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,
std::unique_ptr<LuaArg>(new LuaArg{
{c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1)} {c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1)}
},true))break; }),true))break;
SendToAll(nullptr, Packet, true, true); SendToAll(nullptr, Packet, true, true);
return; return;
case 'E': case 'E':

View File

@@ -71,7 +71,7 @@ void OnDisconnect(Client*c,bool kicked){
Packet = Sec("L")+c->GetName()+Sec(" Left the server!"); Packet = Sec("L")+c->GetName()+Sec(" Left the server!");
SendToAll(c, Packet,false,true); SendToAll(c, Packet,false,true);
Packet.clear(); Packet.clear();
TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,new LuaArg{{c->GetID()}},false); TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
c->ClearCars(); c->ClearCars();
CI->RemoveClient(c); ///Removes the Client from existence CI->RemoveClient(c); ///Removes the Client from existence
} }
@@ -80,10 +80,10 @@ void OnConnect(Client*c){
info(Sec("Client connected")); info(Sec("Client connected"));
c->SetID(OpenID()); c->SetID(OpenID());
info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName()); info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName());
TriggerLuaEvent(Sec("onPlayerConnecting"),false,nullptr,new LuaArg{{c->GetID()}},false); TriggerLuaEvent(Sec("onPlayerConnecting"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
SyncResources(c); SyncResources(c);
if(c->GetStatus() < 0)return; if(c->GetStatus() < 0)return;
Respond(c,"M"+MapName,true); //Send the Map on connect Respond(c,"M"+MapName,true); //Send the Map on connect
info(c->GetName() + Sec(" : Connected")); info(c->GetName() + Sec(" : Connected"));
TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,new LuaArg{{c->GetID()}},false); TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
} }

View File

@@ -1,5 +1,6 @@
#include "Startup.h" #include "Startup.h"
#include "CustomAssert.h" #include "CustomAssert.h"
#include "Curl/curl.h"
#include <thread> #include <thread>
#include <iostream> #include <iostream>
[[noreturn]] void loop(){ [[noreturn]] void loop(){
@@ -11,6 +12,8 @@
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
DebugPrintTID(); DebugPrintTID();
// curl needs to be initialized to properly deallocate its resources later
Assert(curl_global_init(CURL_GLOBAL_DEFAULT) == CURLE_OK);
#ifdef DEBUG #ifdef DEBUG
std::thread t1(loop); std::thread t1(loop);
t1.detach(); t1.detach();
@@ -23,5 +26,7 @@ int main(int argc, char* argv[]) {
HBInit(); HBInit();
StatInit(); StatInit();
NetMain(); NetMain();
// clean up curl at the end to be sure
curl_global_cleanup();
return 0; return 0;
} }