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;
| |||
}
|