diff options
author | David Robillard <d@drobilla.net> | 2022-06-27 16:29:22 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-07-17 17:40:35 -0400 |
commit | 5446b168f42c645f2419a05f9ba1fc1af984322f (patch) | |
tree | 6f04cfcebc4b6c90c70a469263768f0d24d6f5fa | |
parent | b4c5465d221ea35b6144b15b44cda72e8ac1d822 (diff) | |
download | suil-5446b168f42c645f2419a05f9ba1fc1af984322f.tar.gz suil-5446b168f42c645f2419a05f9ba1fc1af984322f.tar.bz2 suil-5446b168f42c645f2419a05f9ba1fc1af984322f.zip |
Avoid snprintf when loading modules
Clang warned about out of bounds writes here on some platforms, though I think
it's a false positive. In any case, it's hard to tell because this "calculate
then snprintf and hope it fits" pattern is error-prone. Replace it with one
that is more verbose, but also more explicit and regular with no room for
misinterpretation.
-rw-r--r-- | src/suil_internal.h | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/suil_internal.h b/src/suil_internal.h index ac6e563..b496ed8 100644 --- a/src/suil_internal.h +++ b/src/suil_internal.h @@ -113,21 +113,25 @@ suil_host_init(void); static inline void* suil_open_module(const char* module_name) { +#define N_SLICES 4 + const char* const env_dir = getenv("SUIL_MODULE_DIR"); const char* const mod_dir = env_dir ? env_dir : SUIL_MODULE_DIR; - const size_t path_len = - strlen(mod_dir) + strlen(SUIL_DIR_SEP SUIL_MODULE_PREFIX SUIL_MODULE_EXT) + - strlen(module_name) + 2; - - char* const path = (char*)calloc(path_len, 1); - snprintf(path, - path_len, - "%s%s%s%s%s", - mod_dir, - SUIL_DIR_SEP, - SUIL_MODULE_PREFIX, - module_name, - SUIL_MODULE_EXT); + + const char* const slices[N_SLICES] = { + mod_dir, SUIL_DIR_SEP SUIL_MODULE_PREFIX, module_name, SUIL_MODULE_EXT}; + + const size_t lengths[N_SLICES] = { + strlen(slices[0]), strlen(slices[1]), strlen(slices[2]), strlen(slices[3])}; + + const size_t path_len = lengths[0] + lengths[1] + lengths[2] + lengths[3]; + char* const path = (char*)calloc(path_len + 1, 1); + + size_t offset = 0; + for (size_t i = 0; i < N_SLICES; ++i) { + memcpy(path + offset, slices[i], lengths[i]); + offset += lengths[i]; + } dylib_error(); void* lib = dylib_open(path, DYLIB_NOW); @@ -137,6 +141,8 @@ suil_open_module(const char* module_name) free(path); return lib; + +#undef N_SLICES } typedef void (*SuilVoidFunc)(void); |