summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-06-27 16:29:22 -0400
committerDavid Robillard <d@drobilla.net>2022-07-17 17:40:35 -0400
commit5446b168f42c645f2419a05f9ba1fc1af984322f (patch)
tree6f04cfcebc4b6c90c70a469263768f0d24d6f5fa
parentb4c5465d221ea35b6144b15b44cda72e8ac1d822 (diff)
downloadsuil-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.h32
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);