199 lines
4.9 KiB
MQL5
199 lines
4.9 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| SecureMemory.mqh |
|
||
|
|
//| Copyright 2025, EscapeEA |
|
||
|
|
//| https://www.escapeea.com |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property copyright "Copyright 2025, EscapeEA"
|
||
|
|
#property link "https://www.escapeea.com"
|
||
|
|
#property version "1.10" // Added RAII support and error context
|
||
|
|
#property strict
|
||
|
|
|
||
|
|
#include "RAII.mqh"
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| RAII wrapper for dynamic memory allocation |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
template<typename T>
|
||
|
|
class CSafePtr {
|
||
|
|
private:
|
||
|
|
T* m_ptr;
|
||
|
|
|
||
|
|
// Prevent copying
|
||
|
|
CSafePtr(const CSafePtr&);
|
||
|
|
void operator=(const CSafePtr&);
|
||
|
|
|
||
|
|
public:
|
||
|
|
// Default constructor
|
||
|
|
CSafePtr() : m_ptr(NULL) {}
|
||
|
|
|
||
|
|
// Constructor with allocation
|
||
|
|
CSafePtr(T* ptr) : m_ptr(ptr) {}
|
||
|
|
|
||
|
|
// Destructor
|
||
|
|
~CSafePtr() {
|
||
|
|
SafeDelete(m_ptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get the raw pointer
|
||
|
|
T* Get() const {
|
||
|
|
return m_ptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Release ownership
|
||
|
|
T* Release() {
|
||
|
|
T* ptr = m_ptr;
|
||
|
|
m_ptr = NULL;
|
||
|
|
return ptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Reset the pointer
|
||
|
|
void Reset(T* ptr = NULL) {
|
||
|
|
if(m_ptr != ptr) {
|
||
|
|
SafeDelete(m_ptr);
|
||
|
|
m_ptr = ptr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Dereference operators
|
||
|
|
T* operator->() const {
|
||
|
|
return m_ptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
T& operator*() const {
|
||
|
|
return *m_ptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Boolean check
|
||
|
|
bool IsValid() const {
|
||
|
|
return m_ptr != NULL;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Safely delete an object and nullify the pointer |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
template<typename T>
|
||
|
|
void SafeDelete(T* &ptr, const string context = "") {
|
||
|
|
if(CheckPointer(ptr) == POINTER_DYNAMIC) {
|
||
|
|
string typeName = typename(T);
|
||
|
|
delete ptr;
|
||
|
|
ptr = NULL;
|
||
|
|
|
||
|
|
// Log the deletion if context is provided
|
||
|
|
if(context != "") {
|
||
|
|
PrintFormat("[%s] Safely deleted %s object", context, typeName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| RAII wrapper for secure string clearing |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
class CSecureString {
|
||
|
|
private:
|
||
|
|
string m_str;
|
||
|
|
|
||
|
|
// Prevent copying
|
||
|
|
CSecureString(const CSecureString&);
|
||
|
|
void operator=(const CSecureString&);
|
||
|
|
|
||
|
|
public:
|
||
|
|
CSecureString(const string str) {
|
||
|
|
m_str = str;
|
||
|
|
}
|
||
|
|
~CSecureString() {
|
||
|
|
// Overwrite the string with zeros before clearing
|
||
|
|
uchar array[];
|
||
|
|
StringToCharArray(m_str, array, 0, -1, CP_ACP);
|
||
|
|
ArrayInitialize(array, 0);
|
||
|
|
m_str = "";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get the string value
|
||
|
|
string Get() const {
|
||
|
|
return m_str;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get string value
|
||
|
|
string ToString() const {
|
||
|
|
return m_str;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| RAII wrapper for secure array clearing |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
template<typename T>
|
||
|
|
class CSecureArray {
|
||
|
|
private:
|
||
|
|
T &m_array[];
|
||
|
|
|
||
|
|
// Prevent copying
|
||
|
|
CSecureArray(const CSecureArray&);
|
||
|
|
void operator=(const CSecureArray&);
|
||
|
|
|
||
|
|
public:
|
||
|
|
CSecureArray(T &array[]) {
|
||
|
|
ArrayCopy(m_array, array);
|
||
|
|
}
|
||
|
|
|
||
|
|
~CSecureArray() {
|
||
|
|
SecureArrayClear(m_array, "CSecureArray");
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Safe memory management functions |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
|
||
|
|
//--- Safe delete for arrays
|
||
|
|
template<typename T>
|
||
|
|
void SafeArrayDelete(T &array[]) {
|
||
|
|
for(int i = 0; i < ArraySize(array); i++) {
|
||
|
|
if(CheckPointer(array[i]) == POINTER_DYNAMIC) {
|
||
|
|
delete array[i];
|
||
|
|
array[i] = NULL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ArrayFree(array);
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Safe string copy with length checking
|
||
|
|
bool SafeStringCopy(string &dest, const string source, const int max_length) {
|
||
|
|
int src_len = StringLen(source);
|
||
|
|
if(src_len >= max_length) {
|
||
|
|
Print("Error: String too long in SafeStringCopy");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Clear destination
|
||
|
|
dest = "";
|
||
|
|
|
||
|
|
// Copy source to destination
|
||
|
|
if(src_len > 0) {
|
||
|
|
dest = source;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Secure memory zeroing
|
||
|
|
template<typename T>
|
||
|
|
void SecureZeroMemory(T &data[], uint size) {
|
||
|
|
if(size > 0 && size <= ArraySize(data)) {
|
||
|
|
for(uint i = 0; i < size; i++) {
|
||
|
|
data[i] = (T)0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Memory allocation with null check
|
||
|
|
template<typename T>
|
||
|
|
T* SafeNew() {
|
||
|
|
T *ptr = new T();
|
||
|
|
if(ptr == NULL) {
|
||
|
|
Print("Fatal Error: Memory allocation failed for ", typename(T));
|
||
|
|
ExpertRemove();
|
||
|
|
}
|
||
|
|
return ptr;
|
||
|
|
}
|