From 8c3b3e61e6ede5d7b3c27298e72270171a0dc13d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 30 May 2019 15:48:38 +0200 Subject: [PATCH] loader: Change strcpy_sx() to be limited version of strcpy_s() The strcpy_sx() now reports errors and behaves as strcpy_s() when buffer is too small (nulls the buffer). But it does not have all the checks. --- lib/loader/loader.c | 13 ++++++++++--- test/unittests/test_loader.cpp | 23 +++++++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/loader/loader.c b/lib/loader/loader.c index b81d22ed3..72b2afaac 100644 --- a/lib/loader/loader.c +++ b/lib/loader/loader.c @@ -54,14 +54,21 @@ #if !defined(EVMC_LOADER_MOCK) static #endif - void + int strcpy_sx(char* restrict dest, size_t destsz, const char* restrict src) { size_t len = strlen(src); - if (len > destsz - 1) - len = destsz - 1; + if (len >= destsz) + { + // The input src will not fit into the dest buffer. + // Set the first byte of the dest to null to make it effectively empty string + // and return error. + dest[0] = 0; + return 1; + } memcpy(dest, src, len); dest[len] = 0; + return 0; } #endif diff --git a/test/unittests/test_loader.cpp b/test/unittests/test_loader.cpp index 9f73ae989..010cbd685 100644 --- a/test/unittests/test_loader.cpp +++ b/test/unittests/test_loader.cpp @@ -20,7 +20,7 @@ extern "C" { #define strcpy_sx strcpy_s #else /// Declaration of internal function defined in loader.c. -void strcpy_sx(char* dest, size_t destsz, const char* src); +int strcpy_sx(char* dest, size_t destsz, const char* src); #endif /// The library path expected by mocked evmc_test_load_library(). @@ -127,13 +127,24 @@ static evmc_instance* create_failure() TEST_F(loader, strcpy_sx) { - const auto input = "12"; - char buf[2] = {0x0f, 0x0e}; - static_assert(sizeof(input) > sizeof(buf), ""); - - strcpy_sx(buf, sizeof(buf), input); + const char input_empty[] = ""; + const char input_that_fits[] = "x"; + const char input_too_big[] = "12"; + char buf[2] = {0x0f, 0x0f}; + static_assert(sizeof(input_empty) <= sizeof(buf), ""); + static_assert(sizeof(input_that_fits) <= sizeof(buf), ""); + static_assert(sizeof(input_too_big) > sizeof(buf), ""); + + EXPECT_EQ(strcpy_sx(buf, sizeof(buf), input_empty), 0); EXPECT_EQ(buf[0], 0); + EXPECT_EQ(buf[1], 0x0f); + + EXPECT_EQ(strcpy_sx(buf, sizeof(buf), input_that_fits), 0); + EXPECT_EQ(buf[0], 'x'); EXPECT_EQ(buf[1], 0); + + EXPECT_NE(strcpy_sx(buf, sizeof(buf), input_too_big), 0); + EXPECT_EQ(buf[0], 0); } TEST_F(loader, load_nonexistent)