Skip to content

Commit d62c270

Browse files
authored
memory operations (#293)
* memory operations * SecureStrncpy * secure_strncpy * SECURE_C11_FUNCTIONS_AVAILABLE * changes
1 parent ac8fcfa commit d62c270

File tree

2 files changed

+230
-0
lines changed

2 files changed

+230
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#define __STDC_WANT_LIB_EXT1__ 1
2+
#include <string.h>
3+
#include <cstring>
4+
#include <stdexcept>
5+
6+
namespace ZEngine::Helpers
7+
{
8+
constexpr int MEMORY_OP_SUCCESS = 0;
9+
constexpr int MEMORY_OP_FAILURE = -1;
10+
11+
#if defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__) && (__STDC_WANT_LIB_EXT1__ >= 1) || (defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__ >= 1)
12+
#define SECURE_C11_FUNCTIONS_AVAILABLE 1
13+
#else
14+
#define SECURE_C11_FUNCTIONS_AVAILABLE 0
15+
#endif
16+
17+
int secure_memset(void* destination, int value, size_t count, size_t destinationSize)
18+
{
19+
if (!destination)
20+
{
21+
return MEMORY_OP_FAILURE;
22+
}
23+
24+
if (count > destinationSize)
25+
{
26+
return MEMORY_OP_FAILURE;
27+
}
28+
29+
return (std::memset(destination, value, count) == destination) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
30+
}
31+
32+
int secure_memcpy(void* dest, size_t destSize, const void* src, size_t count)
33+
{
34+
if (!dest || !src)
35+
{
36+
return MEMORY_OP_FAILURE;
37+
}
38+
39+
if (count > destSize)
40+
{
41+
return MEMORY_OP_FAILURE;
42+
}
43+
44+
#if SECURE_C11_FUNCTIONS_AVAILABLE
45+
errno_t err = memcpy_s(dest, destSize, src, count);
46+
return (err == 0) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
47+
#else
48+
return (std::memcpy(dest, src, count) == dest) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
49+
50+
#endif
51+
}
52+
53+
int secure_memmove(void* dest, size_t destSize, const void* src, size_t count)
54+
{
55+
if (!dest || !src)
56+
{
57+
return MEMORY_OP_FAILURE;
58+
}
59+
60+
if (count > destSize)
61+
{
62+
return MEMORY_OP_FAILURE;
63+
}
64+
65+
#if SECURE_C11_FUNCTIONS_AVAILABLE
66+
errno_t err = memmove_s(dest, destSize, src, count);
67+
return (err == 0) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
68+
#else
69+
return (std::memmove(dest, src, count) == dest) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
70+
#endif
71+
}
72+
73+
int secure_strncpy(char* dest, size_t destSize, const char* src, size_t count)
74+
{
75+
if (!dest || !src)
76+
{
77+
return MEMORY_OP_FAILURE;
78+
}
79+
80+
if (destSize == 0 || count >= destSize)
81+
{
82+
return MEMORY_OP_FAILURE;
83+
}
84+
85+
#if SECURE_C11_FUNCTIONS_AVAILABLE
86+
errno_t err = strncpy_s(dest, destSize, src, count);
87+
return (err == 0) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
88+
#else
89+
return (std::strncpy(dest, src, count) == dest) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
90+
#endif
91+
}
92+
size_t secure_strlen(const char* str)
93+
{
94+
if (!str)
95+
{
96+
return 0;
97+
}
98+
return std::strlen(str);
99+
}
100+
101+
int secure_strcpy(char* dest, size_t destSize, const char* src)
102+
{
103+
if (!dest || !src)
104+
{
105+
return MEMORY_OP_FAILURE;
106+
}
107+
108+
size_t srcLength = secure_strlen(src);
109+
if (srcLength + 1 > destSize)
110+
{
111+
return MEMORY_OP_FAILURE;
112+
}
113+
114+
#if SECURE_C11_FUNCTIONS_AVAILABLE
115+
errno_t err = strcpy_s(dest, destSize, src);
116+
return (err == 0) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
117+
#else
118+
return (std::strcpy(dest, src) == dest) ? MEMORY_OP_SUCCESS : MEMORY_OP_FAILURE;
119+
#endif
120+
}
121+
122+
int secure_memcmp(const void* ptr1, size_t ptr1Size, const void* ptr2, size_t ptr2Size, size_t num)
123+
{
124+
if (!ptr1 || !ptr2)
125+
{
126+
return MEMORY_OP_FAILURE;
127+
}
128+
129+
if (num > ptr1Size || num > ptr2Size)
130+
{
131+
return MEMORY_OP_FAILURE;
132+
}
133+
134+
return std::memcmp(ptr1, ptr2, num);
135+
}
136+
137+
} // namespace ZEngine::Helpers
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <gtest/gtest.h>
2+
#include "Helpers/MemoryOperations.h"
3+
4+
using namespace ZEngine::Helpers;
5+
6+
TEST(MemoryOperationsTest, SecureMemset)
7+
{
8+
char buffer[10];
9+
10+
EXPECT_EQ(secure_memset(buffer, 'A', 5, sizeof(buffer)), MEMORY_OP_SUCCESS);
11+
EXPECT_EQ(buffer[0], 'A');
12+
EXPECT_EQ(buffer[4], 'A');
13+
14+
EXPECT_EQ(secure_memset(buffer, 'B', sizeof(buffer) + 1, sizeof(buffer)), MEMORY_OP_FAILURE);
15+
EXPECT_EQ(secure_memset(nullptr, 'C', 5, sizeof(buffer)), MEMORY_OP_FAILURE);
16+
}
17+
18+
TEST(MemoryOperationsTest, SecureMemcpy)
19+
{
20+
char src[10] = "Test";
21+
char dest[10];
22+
23+
EXPECT_EQ(secure_memcpy(dest, sizeof(dest), src, sizeof(src)), MEMORY_OP_SUCCESS);
24+
EXPECT_STREQ(dest, "Test");
25+
26+
EXPECT_EQ(secure_memcpy(dest, 5, src, sizeof(src)), MEMORY_OP_FAILURE);
27+
28+
EXPECT_EQ(secure_memcpy(nullptr, sizeof(dest), src, sizeof(src)), MEMORY_OP_FAILURE);
29+
EXPECT_EQ(secure_memcpy(dest, sizeof(dest), nullptr, sizeof(src)), MEMORY_OP_FAILURE);
30+
}
31+
32+
TEST(MemoryOperationsTest, SecureMemmove)
33+
{
34+
char src[20] = "Test";
35+
char dest[20];
36+
37+
EXPECT_EQ(secure_memmove(dest, sizeof(dest), src, sizeof(src)), MEMORY_OP_SUCCESS);
38+
EXPECT_STREQ(dest, "Test");
39+
40+
std::strcpy(src, "Overlap");
41+
EXPECT_EQ(secure_memmove(src + 1, sizeof(src) - 1, src, 7), MEMORY_OP_SUCCESS);
42+
43+
EXPECT_EQ(secure_memmove(dest, 5, src, sizeof(src)), MEMORY_OP_FAILURE);
44+
45+
EXPECT_EQ(secure_memmove(nullptr, sizeof(dest), src, sizeof(src)), MEMORY_OP_FAILURE);
46+
EXPECT_EQ(secure_memmove(dest, sizeof(dest), nullptr, sizeof(src)), MEMORY_OP_FAILURE);
47+
}
48+
49+
TEST(MemoryOperationsTest, SecureStrncpy)
50+
{
51+
char src[] = "Hello";
52+
char dest[10];
53+
54+
EXPECT_EQ(secure_strncpy(dest, sizeof(dest), src, 5), MEMORY_OP_SUCCESS);
55+
EXPECT_STREQ(dest, "Hello");
56+
57+
EXPECT_EQ(secure_strncpy(dest, 6, src, 5), MEMORY_OP_SUCCESS);
58+
EXPECT_EQ(dest[4], 'o');
59+
EXPECT_EQ(dest[5], '\0');
60+
61+
EXPECT_EQ(secure_strncpy(nullptr, sizeof(dest), src, 5), MEMORY_OP_FAILURE);
62+
EXPECT_EQ(secure_strncpy(dest, sizeof(dest), nullptr, 5), MEMORY_OP_FAILURE);
63+
}
64+
65+
TEST(MemoryOperationsTest, SecureStrcpy)
66+
{
67+
char src[] = "Hello";
68+
char dest[10];
69+
70+
EXPECT_EQ(secure_strcpy(dest, sizeof(dest), src), MEMORY_OP_SUCCESS);
71+
EXPECT_STREQ(dest, "Hello");
72+
73+
EXPECT_EQ(secure_strcpy(dest, 5, src), MEMORY_OP_FAILURE);
74+
75+
EXPECT_EQ(secure_strcpy(nullptr, sizeof(dest), src), MEMORY_OP_FAILURE);
76+
EXPECT_EQ(secure_strcpy(dest, sizeof(dest), nullptr), MEMORY_OP_FAILURE);
77+
}
78+
79+
TEST(MemoryOperationsTest, SecureStrlen)
80+
{
81+
char str[] = "Hello";
82+
83+
EXPECT_EQ(secure_strlen(str), 5);
84+
EXPECT_EQ(secure_strlen(""), 0);
85+
EXPECT_EQ(secure_strlen(nullptr), 0);
86+
}
87+
88+
TEST(MemoryOperationsTest, SecureMemcmp)
89+
{
90+
char buffer1[10] = "Test";
91+
char buffer2[10] = "Test";
92+
char buffer3[10] = "Different";
93+
}

0 commit comments

Comments
 (0)