aboutsummaryrefslogtreecommitdiff
path: root/src/lib/core
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2026-04-15 10:10:15 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2026-04-15 10:10:15 -0400
commit87779a8c85eec0b71703ed3090a3949761396a15 (patch)
treec99afa5bca18be1ac2de9b937aa72b08d3285d44 /src/lib/core
parent2258cd05bcded0125136c17d51568831ac421bf7 (diff)
downloadstasis-87779a8c85eec0b71703ed3090a3949761396a15.tar.gz
Replace sprintf with snprintf
* A few strcpy and strcat changes as well
Diffstat (limited to 'src/lib/core')
-rw-r--r--src/lib/core/artifactory.c8
-rw-r--r--src/lib/core/conda.c44
-rw-r--r--src/lib/core/docker.c4
-rw-r--r--src/lib/core/github.c8
-rw-r--r--src/lib/core/multiprocessing.c4
-rw-r--r--src/lib/core/recipe.c6
-rw-r--r--src/lib/core/template_func_proto.c6
-rw-r--r--src/lib/core/utils.c36
-rw-r--r--src/lib/core/wheelinfo.c2
9 files changed, 68 insertions, 50 deletions
diff --git a/src/lib/core/artifactory.c b/src/lib/core/artifactory.c
index d5457e7..6a01620 100644
--- a/src/lib/core/artifactory.c
+++ b/src/lib/core/artifactory.c
@@ -60,7 +60,9 @@ int artifactory_download_cli(char *dest,
return -1;
}
- sprintf(path + strlen(path), "/%s", remote_filename);
+ const char *remote_filename_fmt = "/%s";
+ int remote_filename_fmt_len = snprintf(NULL, 0, remote_filename_fmt, remote_filename);
+ snprintf(path + strlen(path), sizeof(path) - remote_filename_fmt_len, remote_filename_fmt, remote_filename);
char *errmsg = NULL;
long fetch_status = download(url, path, &errmsg);
if (HTTP_ERROR(fetch_status)) {
@@ -78,7 +80,7 @@ void jfrt_register_opt_str(char *jfrt_val, const char *opt_name, struct StrList
// no data
return;
}
- snprintf(data, sizeof(data) - 1, "--%s=\"%s\"", opt_name, jfrt_val);
+ snprintf(data, sizeof(data), "--%s=\"%s\"", opt_name, jfrt_val);
strlist_append(&*opt_map, data);
}
@@ -89,7 +91,7 @@ void jfrt_register_opt_bool(bool jfrt_val, const char *opt_name, struct StrList
// option will not be used
return;
}
- snprintf(data, sizeof(data) - 1, "--%s", opt_name);
+ snprintf(data, sizeof(data), "--%s", opt_name);
strlist_append(&*opt_map, data);
}
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index 16483ee..dd336bc 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -18,10 +18,12 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
}
char url[PATH_MAX];
- sprintf(url, "https://micro.mamba.pm/api/micromamba/%s-%s/latest", sys.sysname, sys.machine);
+ const char *url_fmt = "https://micro.mamba.pm/api/micromamba/%s-%s/latest";
+ const int url_fmt_len = snprintf(NULL, 0, url_fmt, sys.sysname, sys.machine);
+ snprintf(url, sizeof(url) - url_fmt_len, url_fmt, sys.sysname, sys.machine);
char installer_path[PATH_MAX];
- sprintf(installer_path, "%s/latest", getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
+ snprintf(installer_path, sizeof(installer_path), "%s/latest", getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
if (access(installer_path, F_OK)) {
char *errmsg = NULL;
@@ -34,12 +36,12 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
}
char mmbin[PATH_MAX];
- sprintf(mmbin, "%s/micromamba", info->micromamba_prefix);
+ snprintf(mmbin, sizeof(mmbin), "%s/micromamba", info->micromamba_prefix);
if (access(mmbin, F_OK)) {
char untarcmd[PATH_MAX * 2];
mkdirs(info->micromamba_prefix, 0755);
- sprintf(untarcmd, "tar -xvf %s -C %s --strip-components=1 bin/micromamba 1>/dev/null", installer_path, info->micromamba_prefix);
+ snprintf(untarcmd, sizeof(untarcmd), "tar -xvf %s -C %s --strip-components=1 bin/micromamba 1>/dev/null", installer_path, info->micromamba_prefix);
int untarcmd_status = system(untarcmd);
if (untarcmd_status) {
return -1;
@@ -47,7 +49,7 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
}
char cmd[STASIS_BUFSIZ] = {0};
- sprintf(cmd, "%s -r %s -p %s ", mmbin, info->conda_prefix, info->conda_prefix);
+ snprintf(cmd, sizeof(cmd), "%s -r %s -p %s ", mmbin, info->conda_prefix, info->conda_prefix);
va_list args;
va_start(args, command);
vsprintf(cmd + strlen(cmd), command, args);
@@ -56,7 +58,7 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
mkdirs(info->conda_prefix, 0755);
char rcpath[PATH_MAX];
- sprintf(rcpath, "%s/.condarc", info->conda_prefix);
+ snprintf(rcpath, sizeof(rcpath), "%s/.condarc", info->conda_prefix);
touch(rcpath);
if (errno == ENOENT) {
errno = 0;
@@ -321,13 +323,13 @@ int conda_activate(const char *root, const char *env_name) {
struct Process proc = {0};
// Where to find conda's init scripts
- sprintf(path_conda, "%s%s", root, init_script_conda);
- sprintf(path_mamba, "%s%s", root, init_script_mamba);
+ snprintf(path_conda, sizeof(path_conda), "%s%s", root, init_script_conda);
+ snprintf(path_mamba, sizeof(path_mamba), "%s%s", root, init_script_mamba);
// Set the path to our stdout log
// Emulate mktemp()'s behavior. Give us a unique file name, but don't use
// the file handle at all. We'll open it as a FILE stream soon enough.
- sprintf(logfile, "%s/%s", globals.tmpdir, "shell_XXXXXX");
+ snprintf(logfile, sizeof(logfile), "%s/%s", globals.tmpdir, "shell_XXXXXX");
int fd = mkstemp(logfile);
if (fd < 0) {
@@ -337,7 +339,7 @@ int conda_activate(const char *root, const char *env_name) {
close(fd);
// Configure our process for output to a log file
- strcpy(proc.f_stdout, logfile);
+ strncpy(proc.f_stdout, logfile, PATH_MAX - 1);
// Verify conda's init scripts are available
if (access(path_conda, F_OK) < 0) {
@@ -478,6 +480,7 @@ int conda_setup_headless() {
char cmd[PATH_MAX];
size_t total = 0;
+ const char *cmd_fmt = "'%s'";
if (globals.conda_packages && strlist_count(globals.conda_packages)) {
memset(cmd, 0, sizeof(cmd));
strcpy(cmd, "install ");
@@ -488,9 +491,10 @@ int conda_setup_headless() {
if (isempty(item)) {
continue;
}
- sprintf(cmd + strlen(cmd), "'%s'", item);
+ const int cmd_fmt_len = snprintf(NULL, 0, cmd_fmt, item);
+ snprintf(cmd + strlen(cmd), sizeof(cmd) - cmd_fmt_len, cmd_fmt, item);
if (i < total - 1) {
- strcat(cmd, " ");
+ strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
}
}
@@ -510,9 +514,10 @@ int conda_setup_headless() {
if (isempty(item)) {
continue;
}
- sprintf(cmd + strlen(cmd), "'%s'", item);
+ const int cmd_fmt_len = snprintf(NULL, 0, cmd_fmt, item);
+ snprintf(cmd + strlen(cmd), sizeof(cmd) - cmd_fmt_len, cmd_fmt, item);
if (i < total - 1) {
- strcat(cmd, " ");
+ strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
}
}
@@ -552,7 +557,7 @@ int conda_env_create_from_uri(char *name, char *uri, char *python_version) {
}
char tempfile[PATH_MAX] = {0};
- sprintf(tempfile, "%s/remote_XXXXXX", globals.tmpdir);
+ snprintf(tempfile, sizeof(tempfile), "%s/remote_XXXXXX", globals.tmpdir);
// Touch a temporary file
int fd = mkstemp(tempfile);
@@ -610,13 +615,13 @@ int conda_env_create(char *name, char *python_version, char *packages) {
int conda_env_remove(char *name) {
char env_command[PATH_MAX];
- sprintf(env_command, "env remove -n %s", name);
+ snprintf(env_command, sizeof(env_command), "env remove -n %s", name);
return conda_exec(env_command);
}
int conda_env_export(char *name, char *output_dir, char *output_filename) {
char env_command[PATH_MAX];
- sprintf(env_command, "env export -n %s -f %s/%s.yml", name, output_dir, output_filename);
+ snprintf(env_command, sizeof(env_command), "env export -n %s -f %s/%s.yml", name, output_dir, output_filename);
return conda_exec(env_command);
}
@@ -637,12 +642,13 @@ char *conda_get_active_environment() {
int conda_index(const char *path) {
char command[PATH_MAX];
- sprintf(command, "index %s", path);
+ snprintf(command, sizeof(command), "index %s", path);
return conda_exec(command);
}
int conda_env_exists(const char *root, const char *name) {
char path[PATH_MAX] = {0};
- snprintf(path, sizeof(path) - 1 - 6, "%s/envs/%s", root, name);
+ const int len = snprintf(NULL, 0, "%s/%s", root, name);
+ snprintf(path, sizeof(path) - len, "%s/envs/%s", root, name);
return access(path, F_OK) == 0;
}
diff --git a/src/lib/core/docker.c b/src/lib/core/docker.c
index 39357ad..fd0a2e2 100644
--- a/src/lib/core/docker.c
+++ b/src/lib/core/docker.c
@@ -93,9 +93,9 @@ int docker_save(const char *image, const char *destdir, const char *compression_
} else {
strncpy(ext, compression_program, sizeof(ext) - 1);
}
- sprintf(cmd, "save \"%s\" | %s > \"%s/%s.tar.%s\"", image, compression_program, destdir, image, ext);
+ snprintf(cmd, sizeof(cmd), "save \"%s\" | %s > \"%s/%s.tar.%s\"", image, compression_program, destdir, image, ext);
} else {
- sprintf(cmd, "save \"%s\" -o \"%s/%s.tar\"", image, destdir, image);
+ snprintf(cmd, sizeof(cmd), "save \"%s\" -o \"%s/%s.tar\"", image, destdir, image);
}
return docker_exec(cmd, 0);
diff --git a/src/lib/core/github.c b/src/lib/core/github.c
index f0c5199..c5281c6 100644
--- a/src/lib/core/github.c
+++ b/src/lib/core/github.c
@@ -58,9 +58,9 @@ int get_github_release_notes(const char *api_token, const char *repo, const char
}
// Render the header data
- sprintf(endpoint_header_auth, endpoint_header_auth_fmt, api_token);
- sprintf(endpoint_post_fields, endpoint_post_fields_fmt, tag, target_commitish);
- sprintf(endpoint_url, endpoint_url_fmt, repo);
+ snprintf(endpoint_header_auth, sizeof(endpoint_header_auth), endpoint_header_auth_fmt, api_token);
+ snprintf(endpoint_post_fields, sizeof(endpoint_post_fields), endpoint_post_fields_fmt, tag, target_commitish);
+ snprintf(endpoint_url, sizeof(endpoint_url), endpoint_url_fmt, repo);
// Begin curl configuration
curl_easy_setopt(curl, CURLOPT_URL, endpoint_url);
@@ -77,7 +77,7 @@ int get_github_release_notes(const char *api_token, const char *repo, const char
// Set the user-agent (github requires one)
char user_agent[20] = {0};
- sprintf(user_agent, "stasis/%s", VERSION);
+ snprintf(user_agent, sizeof(user_agent), "stasis/%s", VERSION);
curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent);
// Execute curl request
diff --git a/src/lib/core/multiprocessing.c b/src/lib/core/multiprocessing.c
index 7ae23c9..f694ad6 100644
--- a/src/lib/core/multiprocessing.c
+++ b/src/lib/core/multiprocessing.c
@@ -74,7 +74,9 @@ int child(struct MultiProcessingPool *pool, struct MultiProcessingTask *task) {
// Set log file name
if (globals.enable_task_logging) {
- sprintf(task->log_file + strlen(task->log_file), "task-%zu-%d.log", mp_global_task_count, task->parent_pid);
+ const char *log_file_fmt = "task-%zu-%d.log";
+ const int log_file_len = snprintf(NULL, 0, log_file_fmt, mp_global_task_count, task->parent_pid);
+ snprintf(task->log_file + strlen(task->log_file), sizeof(task->log_file) - log_file_len, log_file_fmt, mp_global_task_count, task->parent_pid);
}
fp_log = freopen(task->log_file, "w+", stdout);
if (!fp_log) {
diff --git a/src/lib/core/recipe.c b/src/lib/core/recipe.c
index 99d3fe1..cc96139 100644
--- a/src/lib/core/recipe.c
+++ b/src/lib/core/recipe.c
@@ -9,14 +9,14 @@ int recipe_clone(char *recipe_dir, char *url, char *gitref, char **result) {
memset(destdir, 0, sizeof(destdir));
reponame = path_basename(url);
- sprintf(destdir, "%s/%s", recipe_dir, reponame);
+ snprintf(destdir, sizeof(destdir), "%s/%s", recipe_dir, reponame);
if (!*result) {
*result = calloc(PATH_MAX, sizeof(*result));
if (!*result) {
return -1;
}
}
- strncpy(*result, destdir, PATH_MAX);
+ strncpy(*result, destdir, PATH_MAX - 1);
if (!access(destdir, F_OK)) {
if (!strcmp(destdir, "/")) {
@@ -52,7 +52,7 @@ int recipe_get_type(char *repopath) {
for (size_t i = 0; marker[i] != NULL; i++) {
char path[PATH_MAX] = {0};
- sprintf(path, "%s/%s", repopath, marker[i]);
+ snprintf(path, sizeof(path), "%s/%s", repopath, marker[i]);
int result = access(path, F_OK);
if (!result) {
return type[i];
diff --git a/src/lib/core/template_func_proto.c b/src/lib/core/template_func_proto.c
index 52a11b5..d344933 100644
--- a/src/lib/core/template_func_proto.c
+++ b/src/lib/core/template_func_proto.c
@@ -44,7 +44,7 @@ int get_github_release_notes_auto_tplfunc_entrypoint(void *frame, void *data_out
// Using HEAD, GitHub returns the previous tag
char *note = NULL;
char h1_title[NAME_MAX] = {0};
- sprintf(h1_title, "# %s", test->name);
+ snprintf(h1_title, sizeof(h1_title), "# %s", test->name);
strlist_append(&notes_list, h1_title);
result += get_github_release_notes(api_token ? api_token : "anonymous",
repository,
@@ -88,7 +88,7 @@ int get_junitxml_file_entrypoint(void *frame, void *data_out) {
SYSERROR("failed to allocate output string: %s", strerror(errno));
return -1;
}
- sprintf(*output, "%s/results-%s-%s.xml", ctx->storage.results_dir, name, ctx->info.release_name);
+ snprintf(*output, PATH_MAX, "%s/results-%s-%s.xml", ctx->storage.results_dir, name, ctx->info.release_name);
return result;
}
@@ -113,7 +113,7 @@ int get_basetemp_dir_entrypoint(void *frame, void *data_out) {
SYSERROR("failed to allocate output string: %s", strerror(errno));
return -1;
}
- sprintf(*output, "%s/truth-%s-%s", ctx->storage.tmpdir, name, ctx->info.release_name);
+ snprintf(*output, PATH_MAX, "%s/truth-%s-%s", ctx->storage.tmpdir, name, ctx->info.release_name);
return result;
}
diff --git a/src/lib/core/utils.c b/src/lib/core/utils.c
index e106193..2722585 100644
--- a/src/lib/core/utils.c
+++ b/src/lib/core/utils.c
@@ -316,11 +316,13 @@ int git_clone(struct Process *proc, char *url, char *destdir, char *gitref) {
}
static char command[PATH_MAX] = {0};
- sprintf(command, "%s clone -c advice.detachedHead=false --recursive %s", program, url);
+ snprintf(command, sizeof(command), "%s clone -c advice.detachedHead=false --recursive %s", program, url);
if (destdir && access(destdir, F_OK) < 0) {
// Destination directory does not exist
- sprintf(command + strlen(command), " %s", destdir);
+ const char *command_fmt = " %s";
+ const int command_fmt_len = snprintf(NULL, 0, command_fmt, destdir);
+ snprintf(command + strlen(command), sizeof(command) - command_fmt_len, command_fmt, destdir);
// Clone the repo
result = shell(proc, command);
if (result) {
@@ -338,7 +340,7 @@ int git_clone(struct Process *proc, char *url, char *destdir, char *gitref) {
if (!pushd(chdir_to)) {
memset(command, 0, sizeof(command));
- sprintf(command, "%s fetch --all", program);
+ snprintf(command, sizeof(command), "%s fetch --all", program);
result = shell(proc, command);
if (result) {
goto die_pop;
@@ -346,7 +348,7 @@ int git_clone(struct Process *proc, char *url, char *destdir, char *gitref) {
if (gitref != NULL) {
memset(command, 0, sizeof(command));
- sprintf(command, "%s checkout %s", program, gitref);
+ snprintf(command, sizeof(command), "%s checkout %s", program, gitref);
result = shell(proc, command);
if (result) {
@@ -403,7 +405,7 @@ char *git_rev_parse(const char *path, char *args) {
}
// TODO: Use `-C [path]` if the version of git installed supports it
- sprintf(cmd, "git rev-parse %s", args);
+ snprintf(cmd, sizeof(cmd), "git rev-parse %s", args);
FILE *pp = popen(cmd, "r");
if (!pp) {
return NULL;
@@ -453,11 +455,11 @@ void msg(unsigned type, char *fmt, ...) {
}
if (type & STASIS_MSG_L1) {
- sprintf(header, "==>%s" STASIS_COLOR_RESET STASIS_COLOR_WHITE, status);
+ snprintf(header, sizeof(header), "==>%s" STASIS_COLOR_RESET STASIS_COLOR_WHITE, status);
} else if (type & STASIS_MSG_L2) {
- sprintf(header, " ->%s" STASIS_COLOR_RESET, status);
+ snprintf(header, sizeof(header), " ->%s" STASIS_COLOR_RESET, status);
} else if (type & STASIS_MSG_L3) {
- sprintf(header, STASIS_COLOR_BLUE " ->%s" STASIS_COLOR_RESET, status);
+ snprintf(header, sizeof(header), STASIS_COLOR_BLUE " ->%s" STASIS_COLOR_RESET, status);
}
fprintf(stream, "%s", header);
@@ -487,7 +489,7 @@ char *xmkstemp(FILE **fp, const char *mode) {
strcpy(tmpdir, "/tmp");
}
memset(t_name, 0, sizeof(t_name));
- sprintf(t_name, "%s/%s", tmpdir, "STASIS.XXXXXX");
+ snprintf(t_name, sizeof(t_name), "%s/%s", tmpdir, "STASIS.XXXXXX");
fd = mkstemp(t_name);
*fp = fdopen(fd, mode);
@@ -912,13 +914,15 @@ void debug_hexdump(char *data, int len) {
char *pos = start;
while (pos != end) {
if (count == 0) {
- sprintf(addr + strlen(addr), "%p", pos);
+ const char *pos_fmt = "%p";
+ const int pos_fmt_len = snprintf(NULL, 0, pos_fmt, pos);
+ snprintf(addr + strlen(addr), sizeof(addr) - pos_fmt_len, pos_fmt, pos);
}
if (count == 8) {
strcat(bytes, " ");
}
if (count > 15) {
- sprintf(output, "%s | %s | %s", addr, bytes, ascii);
+ snprintf(output, sizeof(output), "%s | %s | %s", addr, bytes, ascii);
puts(output);
memset(output, 0, sizeof(output));
memset(addr, 0, sizeof(addr));
@@ -928,8 +932,13 @@ void debug_hexdump(char *data, int len) {
continue;
}
- sprintf(bytes + strlen(bytes), "%02X ", (unsigned char) *pos);
- sprintf(ascii + strlen(ascii), "%c", isprint(*pos) ? *pos : '.');
+ const char *bytes_fmt = "%02X ";
+ const int bytes_fmt_len = snprintf(NULL, 0, bytes_fmt, (unsigned char) *pos);
+ snprintf(bytes + strlen(bytes), sizeof(bytes) - bytes_fmt_len, bytes_fmt, (unsigned char) *pos);
+
+ const char *ascii_fmt = "%c";
+ // no need to calculate length for a single character
+ snprintf(ascii + strlen(ascii), sizeof(ascii) - 1, ascii_fmt, isprint(*pos) ? *pos : '.');
pos++;
count++;
@@ -1171,4 +1180,3 @@ int get_random_bytes(char *result, size_t maxlen) {
result[bytes ? bytes - 1 : 0] = '\0';
return 0;
}
-
diff --git a/src/lib/core/wheelinfo.c b/src/lib/core/wheelinfo.c
index 1a93a82..86b71cf 100644
--- a/src/lib/core/wheelinfo.c
+++ b/src/lib/core/wheelinfo.c
@@ -8,7 +8,7 @@ struct WheelInfo *wheelinfo_get(const char *basepath, const char *name, char *to
strcpy(package_name, name);
tolower_s(package_name);
- sprintf(package_path, "%s/%s", basepath, package_name);
+ snprintf(package_path, sizeof(package_path), "%s/%s", basepath, package_name);
DIR *dp = opendir(package_path);
if (!dp) {