mirror of
https://github.com/intel/compute-runtime.git
synced 2025-11-15 10:14:56 +08:00
Adjust the implementation of strncpy_s() for Linux
This change: - prevents writing memory out of the range of the destination buffer - prevents calling strlen() with non-null terminated c-string - corrects the logic, which validates passed range to proceed when real length fits the destination buffer Related-To: NEO-7264 Signed-off-by: Wrobel, Patryk <patryk.wrobel@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
5bdf758049
commit
dda5b19859
@@ -31,28 +31,6 @@ inline int strcpy_s(char *dst, size_t dstSize, const char *src) { // NOLINT(read
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int strncpy_s(char *dst, size_t numberOfElements, const char *src, size_t count) { // NOLINT(readability-identifier-naming)
|
||||
if ((dst == nullptr) || (src == nullptr)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (numberOfElements < count) {
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
size_t length = strlen(src);
|
||||
if (length > count) {
|
||||
length = count;
|
||||
}
|
||||
memcpy(dst, src, length);
|
||||
|
||||
if (length < numberOfElements) {
|
||||
numberOfElements = length;
|
||||
}
|
||||
dst[numberOfElements] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline size_t strnlen_s(const char *str, size_t count) { // NOLINT(readability-identifier-naming)
|
||||
if (str == nullptr) {
|
||||
return 0;
|
||||
@@ -66,6 +44,22 @@ inline size_t strnlen_s(const char *str, size_t count) { // NOLINT(readability-i
|
||||
return count;
|
||||
}
|
||||
|
||||
inline int strncpy_s(char *dst, size_t numberOfElements, const char *src, size_t count) { // NOLINT(readability-identifier-naming)
|
||||
if ((dst == nullptr) || (src == nullptr)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size_t length = strnlen_s(src, count);
|
||||
if (numberOfElements <= count && numberOfElements <= length) {
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
memcpy(dst, src, length);
|
||||
dst[length] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int memcpy_s(void *dst, size_t destSize, const void *src, size_t count) { // NOLINT(readability-identifier-naming)
|
||||
if ((dst == nullptr) || (src == nullptr)) {
|
||||
return -EINVAL;
|
||||
|
||||
@@ -27,7 +27,7 @@ TEST(StringHelpers, GivenParamsWhenUsingStrncpyThenReturnIsCorrect) {
|
||||
ret = strncpy_s(dst, 1024, nullptr, 1024);
|
||||
EXPECT_EQ(ret, -EINVAL);
|
||||
|
||||
ret = strncpy_s(dst, 512, src, 1024);
|
||||
ret = strncpy_s(dst, 10, src, 1024);
|
||||
EXPECT_EQ(ret, -ERANGE);
|
||||
|
||||
memset(dst, 0, sizeof(dst));
|
||||
@@ -37,19 +37,41 @@ TEST(StringHelpers, GivenParamsWhenUsingStrncpyThenReturnIsCorrect) {
|
||||
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
|
||||
EXPECT_EQ(0, dst[i]);
|
||||
|
||||
memset(dst, 0, sizeof(dst));
|
||||
ret = strncpy_s(dst, strlen(src) / 2, src, strlen(src) / 2);
|
||||
EXPECT_EQ(ret, 0);
|
||||
EXPECT_EQ(0, memcmp(dst, src, strlen(src) / 2));
|
||||
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
|
||||
EXPECT_EQ(0, dst[i]);
|
||||
ret = strncpy_s(dst, 1024, src, 1024);
|
||||
ASSERT_EQ(0, ret);
|
||||
|
||||
strncpy_s(dst, 1024, src, 1024);
|
||||
EXPECT_EQ(0, memcmp(dst, src, strlen(src)));
|
||||
for (size_t i = strlen(src); i < sizeof(dst); i++)
|
||||
EXPECT_EQ(0, dst[i]);
|
||||
}
|
||||
|
||||
TEST(StringHelpers, GivenCountGreaterEqualToNumberOfElementsThenReturnErangeAndSetFirstStringToNullTerminator) {
|
||||
// strncpy_s() copies at most COUNT bytes and appends null-terminator at dst[COUNT].
|
||||
// It means, that for given COUNT, at least COUNT+1 bytes are required in dst buffer.
|
||||
|
||||
const size_t firstWordLength = 9;
|
||||
char src[] = "c-strings are serious business!";
|
||||
|
||||
char dst[firstWordLength] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'};
|
||||
const auto ret = strncpy_s(dst, sizeof(dst), src, firstWordLength);
|
||||
|
||||
EXPECT_EQ(-ERANGE, ret);
|
||||
}
|
||||
|
||||
TEST(StringHelpers, GivenNotNullTerminatedSourceThenCopyAtMostCountBytesAndAppendNulltermination) {
|
||||
// If null-terminator is missing, then strncpy_s() copies COUNT bytes and stores it at dst[COUNT].
|
||||
|
||||
const size_t srcLength = 8;
|
||||
char src[srcLength] = {'c', '-', 's', 't', 'r', 'i', 'n', 'g'};
|
||||
|
||||
const size_t nullterminatorLength = 1;
|
||||
char dst[srcLength + nullterminatorLength] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'};
|
||||
const auto ret = strncpy_s(dst, sizeof(dst), src, srcLength);
|
||||
|
||||
ASSERT_EQ(0, ret);
|
||||
EXPECT_STREQ("c-string", dst);
|
||||
}
|
||||
|
||||
TEST(StringHelpers, GivenParamsWhenUsingMemmoveThenReturnIsCorrect) {
|
||||
char dst[1024] = "";
|
||||
char src[1024] = "HelloWorld";
|
||||
|
||||
Reference in New Issue
Block a user