mirror of https://github.com/status-im/evmc.git
Merge pull request #307 from ethereum/loader_strcpy_s
loader: Fix strcpy_s()
This commit is contained in:
commit
0f2416da0c
|
@ -42,18 +42,33 @@
|
|||
#define ATTR_FORMAT(...)
|
||||
#endif
|
||||
|
||||
#if !_WIN32
|
||||
#if _WIN32
|
||||
#define strcpy_sx strcpy_s
|
||||
#else
|
||||
/*
|
||||
* Provide strcpy_s() for GNU libc.
|
||||
* Limited variant of strcpy_s().
|
||||
*
|
||||
* Provided for C standard libraries where strcpy_s() is not available.
|
||||
* The availability check might need to adjusted for other C standard library implementations.
|
||||
*/
|
||||
static void strcpy_s(char* dest, size_t destsz, const char* src)
|
||||
#if !defined(EVMC_LOADER_MOCK)
|
||||
static
|
||||
#endif
|
||||
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
|
||||
|
||||
|
@ -124,7 +139,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
|
|||
const char prefix[] = "evmc_create_";
|
||||
const size_t prefix_length = strlen(prefix);
|
||||
char prefixed_name[sizeof(prefix) + PATH_MAX_LENGTH];
|
||||
strcpy_s(prefixed_name, sizeof(prefixed_name), prefix);
|
||||
strcpy_sx(prefixed_name, sizeof(prefixed_name), prefix);
|
||||
|
||||
// Find filename in the path.
|
||||
const char* sep_pos = strrchr(filename, '/');
|
||||
|
@ -142,7 +157,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
|
|||
name_pos += lib_prefix_length;
|
||||
|
||||
char* base_name = prefixed_name + prefix_length;
|
||||
strcpy_s(base_name, PATH_MAX_LENGTH, name_pos);
|
||||
strcpy_sx(base_name, PATH_MAX_LENGTH, name_pos);
|
||||
|
||||
// Trim the file extension.
|
||||
char* ext_pos = strrchr(prefixed_name, '.');
|
||||
|
|
|
@ -16,6 +16,13 @@ static constexpr bool is_windows = false;
|
|||
#endif
|
||||
|
||||
extern "C" {
|
||||
#if _WIN32
|
||||
#define strcpy_sx strcpy_s
|
||||
#else
|
||||
/// Declaration of internal function defined in loader.c.
|
||||
int strcpy_sx(char* dest, size_t destsz, const char* src);
|
||||
#endif
|
||||
|
||||
/// The library path expected by mocked evmc_test_load_library().
|
||||
extern const char* evmc_test_library_path;
|
||||
|
||||
|
@ -118,6 +125,28 @@ static evmc_instance* create_failure()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
TEST_F(loader, strcpy_sx)
|
||||
{
|
||||
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)
|
||||
{
|
||||
constexpr auto path = "nonexistent";
|
||||
|
|
Loading…
Reference in New Issue