diff options
| author | Joseph Hunkeler <jhunkeler@gmail.com> | 2026-04-15 10:10:15 -0400 |
|---|---|---|
| committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2026-04-15 10:10:15 -0400 |
| commit | 87779a8c85eec0b71703ed3090a3949761396a15 (patch) | |
| tree | c99afa5bca18be1ac2de9b937aa72b08d3285d44 | |
| parent | 2258cd05bcded0125136c17d51568831ac421bf7 (diff) | |
| download | stasis-87779a8c85eec0b71703ed3090a3949761396a15.tar.gz | |
Replace sprintf with snprintf
* A few strcpy and strcat changes as well
37 files changed, 236 insertions, 188 deletions
diff --git a/src/cli/stasis/args.c b/src/cli/stasis/args.c index dbc9c2f..696f3a6 100644 --- a/src/cli/stasis/args.c +++ b/src/cli/stasis/args.c @@ -85,7 +85,7 @@ void usage(char *progname) { int width = get_option_max_width(long_options); for (int x = 0; long_options[x].name != 0; x++) { char tmp[STASIS_NAME_MAX] = {0}; - char output[sizeof(tmp)] = {0}; + char output[STASIS_NAME_MAX] = {0}; char opt_long[50] = {0}; // --? [ARG]? char opt_short[50] = {0}; // -? [ARG]? @@ -105,8 +105,10 @@ void usage(char *progname) { strcat(opt_short, " "); } - sprintf(tmp, " %%-%ds\t%%s\t\t%%s", width + 4); - sprintf(output, tmp, opt_long, opt_short, long_options_help[x]); + const char *opt_fmt = " %%-%ds\t%%s\t\t%%s"; + size_t opt_fmt_len = snprintf(NULL, 0, opt_fmt, width); + snprintf(tmp, sizeof(tmp) - opt_fmt_len, opt_fmt, width + 4); + snprintf(output, sizeof(output), tmp, opt_long, opt_short, long_options_help[x]); puts(output); } } diff --git a/src/cli/stasis/stasis_main.c b/src/cli/stasis/stasis_main.c index 44efc4a..9b3c6ba 100644 --- a/src/cli/stasis/stasis_main.c +++ b/src/cli/stasis/stasis_main.c @@ -45,7 +45,7 @@ static void configure_stasis_ini(struct Delivery *ctx, char **config_input) { if (!*config_input) { SYSDEBUG("%s", "No configuration passed by argument. Using basic config."); char cfgfile[PATH_MAX * 2]; - sprintf(cfgfile, "%s/%s", globals.sysconfdir, "stasis.ini"); + snprintf(cfgfile, sizeof(cfgfile), "%s/%s", globals.sysconfdir, "stasis.ini"); SYSDEBUG("cfgfile: %s", cfgfile); if (!access(cfgfile, F_OK | R_OK)) { *config_input = strdup(cfgfile); @@ -161,9 +161,9 @@ static void check_conda_prefix_length(const struct Delivery *ctx) { } } -static void setup_conda(struct Delivery *ctx, char *installer_url) { +static void setup_conda(struct Delivery *ctx, char *installer_url, const size_t maxlen) { msg(STASIS_MSG_L1, "Conda setup\n"); - delivery_get_conda_installer_url(ctx, installer_url); + delivery_get_conda_installer_url(ctx, installer_url, maxlen); msg(STASIS_MSG_L2, "Downloading: %s\n", installer_url); if (delivery_get_conda_installer(ctx, installer_url)) { msg(STASIS_MSG_ERROR, "download failed: %s\n", installer_url); @@ -429,7 +429,7 @@ static void build_docker(struct Delivery *ctx, const int disabled) { msg(STASIS_MSG_L1 | STASIS_MSG_WARN, "Docker image building is disabled by CLI argument\n"); } else { char dockerfile[PATH_MAX] = {0}; - sprintf(dockerfile, "%s/%s", ctx->storage.build_docker_dir, "Dockerfile"); + snprintf(dockerfile, sizeof(dockerfile), "%s/%s", ctx->storage.build_docker_dir, "Dockerfile"); if (globals.enable_docker) { if (!access(dockerfile, F_OK)) { msg(STASIS_MSG_L1, "Building Docker image\n"); @@ -461,7 +461,7 @@ static void generate_release(struct Delivery *ctx, char *env_name, char *env_nam delivery_export(ctx, (char *[]) {env_name, env_name_testing, NULL}); char specfile[PATH_MAX]; - sprintf(specfile, "%s/%s.yml", ctx->storage.delivery_dir, env_name); + snprintf(specfile, sizeof(specfile), "%s/%s.yml", ctx->storage.delivery_dir, env_name); delivery_rewrite_stage1(ctx, specfile); build_docker(ctx, disable_docker); @@ -666,7 +666,7 @@ int main(int argc, char *argv[]) { check_conda_install_prefix(&ctx); check_conda_prefix_length(&ctx); - setup_conda(&ctx, installer_url); + setup_conda(&ctx, installer_url, sizeof(installer_url)); configure_conda_base(&ctx, envs); configure_conda_purge(&ctx, envs); setup_activate_test_env(&ctx, env_name_testing); diff --git a/src/cli/stasis_indexer/args.c b/src/cli/stasis_indexer/args.c index 2d92ab0..8c9d3fe 100644 --- a/src/cli/stasis_indexer/args.c +++ b/src/cli/stasis_indexer/args.c @@ -30,7 +30,7 @@ void usage(char *name) { for (int i = 0; i < maxopts - 1; i++) { char line[255] = {0}; - sprintf(line, " --%s -%c %-20s", long_options[i].name, long_options[i].val, long_options_help[i]); + snprintf(line, sizeof(line), " --%s -%c %-20s", long_options[i].name, long_options[i].val, long_options_help[i]); puts(line); } diff --git a/src/cli/stasis_indexer/junitxml_report.c b/src/cli/stasis_indexer/junitxml_report.c index 21cf729..d30ee09 100644 --- a/src/cli/stasis_indexer/junitxml_report.c +++ b/src/cli/stasis_indexer/junitxml_report.c @@ -98,7 +98,7 @@ static int write_report_output(struct Delivery *ctx, FILE *destfp, const char *x int indexer_junitxml_report(struct Delivery **ctx, const size_t nelem) { char indexfile[PATH_MAX] = {0}; - sprintf(indexfile, "%s/README.md", (*ctx)->storage.results_dir); + snprintf(indexfile, sizeof(indexfile), "%s/README.md", (*ctx)->storage.results_dir); struct StrList *file_listing = listdir((*ctx)->storage.results_dir); if (!file_listing) { @@ -117,7 +117,7 @@ int indexer_junitxml_report(struct Delivery **ctx, const size_t nelem) { int current_rc = (*ctx)->meta.rc; for (size_t d = 0; d < nelem; d++) { char pattern[PATH_MAX] = {0}; - snprintf(pattern, sizeof(pattern) - 1, "*%s*", ctx[d]->info.release_name); + snprintf(pattern, sizeof(pattern), "*%s*", ctx[d]->info.release_name); // if the result directory contains tests for this release name, print them if (!is_file_in_listing(file_listing, pattern)) { diff --git a/src/cli/stasis_indexer/readmes.c b/src/cli/stasis_indexer/readmes.c index edc6312..91c936f 100644 --- a/src/cli/stasis_indexer/readmes.c +++ b/src/cli/stasis_indexer/readmes.c @@ -12,7 +12,7 @@ int indexer_readmes(struct Delivery **ctx, const size_t nelem) { } char indexfile[PATH_MAX] = {0}; - sprintf(indexfile, "%s/README.md", (*ctx)->storage.delivery_dir); + snprintf(indexfile, sizeof(indexfile), "%s/README.md", (*ctx)->storage.delivery_dir); FILE *indexfp = fopen(indexfile, "w+"); if (!indexfp) { @@ -52,10 +52,10 @@ int indexer_readmes(struct Delivery **ctx, const size_t nelem) { if (!latest_deliveries[i]->meta.name) { continue; } - sprintf(link_name, "latest-py%s-%s-%s.yml", latest_deliveries[i]->meta.python_compact, latest_deliveries[i]->system.platform[DELIVERY_PLATFORM_RELEASE], latest_deliveries[i]->system.arch); - sprintf(readme_name, "README-py%s-%s-%s.md", latest_deliveries[i]->meta.python_compact, latest_deliveries[i]->system.platform[DELIVERY_PLATFORM_RELEASE], latest_deliveries[i]->system.arch); - sprintf(conf_name, "%s.ini", latest_deliveries[i]->info.release_name); - sprintf(conf_name_relative, "../config/%s.ini", latest_deliveries[i]->info.release_name); + snprintf(link_name, sizeof(link_name), "latest-py%s-%s-%s.yml", latest_deliveries[i]->meta.python_compact, latest_deliveries[i]->system.platform[DELIVERY_PLATFORM_RELEASE], latest_deliveries[i]->system.arch); + snprintf(readme_name, sizeof(readme_name), "README-py%s-%s-%s.md", latest_deliveries[i]->meta.python_compact, latest_deliveries[i]->system.platform[DELIVERY_PLATFORM_RELEASE], latest_deliveries[i]->system.arch); + snprintf(conf_name, sizeof(conf_name), "%s.ini", latest_deliveries[i]->info.release_name); + snprintf(conf_name_relative, sizeof(conf_name_relative), "../config/%s.ini", latest_deliveries[i]->info.release_name); if (strstr(link_name, platform) && strstr(link_name, arch)) { fprintf(indexfp, "- Python %s\n", latest_deliveries[i]->meta.python); fprintf(indexfp, " - Info: [README](%s)\n", readme_name); diff --git a/src/cli/stasis_indexer/stasis_indexer_main.c b/src/cli/stasis_indexer/stasis_indexer_main.c index 840e897..5f7ded4 100644 --- a/src/cli/stasis_indexer/stasis_indexer_main.c +++ b/src/cli/stasis_indexer/stasis_indexer_main.c @@ -80,11 +80,11 @@ int indexer_symlinks(struct Delivery **ctx, const size_t nelem) { if (!data[i]->meta.name) { continue; } - sprintf(link_name_spec, "latest-py%s-%s-%s.yml", data[i]->meta.python_compact, data[i]->system.platform[DELIVERY_PLATFORM_RELEASE], data[i]->system.arch); - sprintf(file_name_spec, "%s.yml", data[i]->info.release_name); + snprintf(link_name_spec, sizeof(link_name_spec), "latest-py%s-%s-%s.yml", data[i]->meta.python_compact, data[i]->system.platform[DELIVERY_PLATFORM_RELEASE], data[i]->system.arch); + snprintf(file_name_spec, sizeof(file_name_spec), "%s.yml", data[i]->info.release_name); - sprintf(link_name_readme, "README-py%s-%s-%s.md", data[i]->meta.python_compact, data[i]->system.platform[DELIVERY_PLATFORM_RELEASE], data[i]->system.arch); - sprintf(file_name_readme, "README-%s.md", data[i]->info.release_name); + snprintf(link_name_readme, sizeof(link_name_readme), "README-py%s-%s-%s.md", data[i]->meta.python_compact, data[i]->system.platform[DELIVERY_PLATFORM_RELEASE], data[i]->system.arch); + snprintf(file_name_readme, sizeof(file_name_readme), "README-%s.md", data[i]->info.release_name); if (!access(link_name_spec, F_OK)) { if (unlink(link_name_spec)) { @@ -151,7 +151,7 @@ void indexer_init_dirs(struct Delivery *ctx, const char *workdir) { char newpath[PATH_MAX] = {0}; if (getenv("PATH")) { - sprintf(newpath, "%s/bin:%s", ctx->storage.tools_dir, getenv("PATH")); + snprintf(newpath, sizeof(newpath), "%s/bin:%s", ctx->storage.tools_dir, getenv("PATH")); setenv("PATH", newpath, 1); } else { SYSERROR("%s", "environment variable PATH is undefined. Unable to continue."); @@ -411,7 +411,7 @@ int main(const int argc, char *argv[]) { msg(STASIS_MSG_L1, "Copying indexed delivery to '%s'\n", destdir); char cmd[PATH_MAX] = {0}; - sprintf(cmd, "rsync -ah%s --delete --exclude 'tmp/' --exclude 'tools/' '%s/' '%s/'", globals.verbose ? "v" : "q", workdir, destdir); + snprintf(cmd, sizeof(cmd), "rsync -ah%s --delete --exclude 'tmp/' --exclude 'tools/' '%s/' '%s/'", globals.verbose ? "v" : "q", workdir, destdir); guard_free(destdir); if (globals.verbose) { diff --git a/src/cli/stasis_indexer/website.c b/src/cli/stasis_indexer/website.c index 966391e..e758d47 100644 --- a/src/cli/stasis_indexer/website.c +++ b/src/cli/stasis_indexer/website.c @@ -8,7 +8,7 @@ int indexer_make_website(struct Delivery **ctx) { return -1; } - sprintf(css_filename, "%s/%s", globals.sysconfdir, "stasis_pandoc.css"); + snprintf(css_filename, PATH_MAX, "%s/%s", globals.sysconfdir, "stasis_pandoc.css"); const int have_css = access(css_filename, F_OK | R_OK) == 0; struct StrList *dirs = strlist_init(); @@ -29,13 +29,13 @@ int indexer_make_website(struct Delivery **ctx) { char *filename = path_basename(strlist_item(inputs, x)); char fullpath_src[PATH_MAX] = {0}; char fullpath_dest[PATH_MAX] = {0}; - sprintf(fullpath_src, "%s/%s", root, filename); + snprintf(fullpath_src, sizeof(fullpath_src), "%s/%s", root, filename); if (access(fullpath_src, F_OK)) { continue; } // Replace *.md extension with *.html. - strcpy(fullpath_dest, fullpath_src); + strncpy(fullpath_dest, fullpath_src, sizeof(fullpath_dest) - 1); gen_file_extension_str(fullpath_dest, ".html"); // Convert markdown to html @@ -52,8 +52,8 @@ int indexer_make_website(struct Delivery **ctx) { if (!strcmp(filename, "README.md")) { char link_from[PATH_MAX] = {0}; char link_dest[PATH_MAX] = {0}; - strcpy(link_from, "README.html"); - sprintf(link_dest, "%s/%s", root, "index.html"); + strncpy(link_from, "README.html", sizeof(link_from) - 1); + snprintf(link_dest, sizeof(link_dest), "%s/%s", root, "index.html"); if (symlink(link_from, link_dest)) { SYSERROR("Warning: symlink(%s, %s) failed: %s", link_from, link_dest, strerror(errno)); } 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(¬es_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) { diff --git a/src/lib/delivery/delivery.c b/src/lib/delivery/delivery.c index be6e8ff..bb96dc3 100644 --- a/src/lib/delivery/delivery.c +++ b/src/lib/delivery/delivery.c @@ -265,8 +265,11 @@ void delivery_free(struct Delivery *ctx) { guard_free(ctx->_stasis_ini_fp.mission_path); } -int delivery_format_str(struct Delivery *ctx, char **dest, const char *fmt) { - size_t fmt_len = strlen(fmt); +int delivery_format_str(struct Delivery *ctx, char **dest, size_t maxlen, const char *fmt) { + const size_t fmt_len = strlen(fmt); + if (maxlen < 1) { + maxlen = 1; + } if (!*dest) { *dest = calloc(STASIS_NAME_MAX, sizeof(**dest)); @@ -280,47 +283,47 @@ int delivery_format_str(struct Delivery *ctx, char **dest, const char *fmt) { i++; switch (fmt[i]) { case 'n': // name - strcat(*dest, ctx->meta.name); + strncat(*dest, ctx->meta.name, maxlen - 1); break; case 'c': // codename - strcat(*dest, ctx->meta.codename); + strncat(*dest, ctx->meta.codename, maxlen - 1); break; case 'm': // mission - strcat(*dest, ctx->meta.mission); + strncat(*dest, ctx->meta.mission, maxlen - 1); break; case 'r': // revision - sprintf(*dest + strlen(*dest), "%d", ctx->meta.rc); + snprintf(*dest + strlen(*dest), maxlen, "%d", ctx->meta.rc); break; case 'R': // "final"-aware revision if (ctx->meta.final) - strcat(*dest, "final"); + strncat(*dest, "final", maxlen); else - sprintf(*dest + strlen(*dest), "%d", ctx->meta.rc); + snprintf(*dest + strlen(*dest), maxlen, "%d", ctx->meta.rc); break; case 'v': // version - strcat(*dest, ctx->meta.version); + strncat(*dest, ctx->meta.version, maxlen - 1); break; case 'P': // python version - strcat(*dest, ctx->meta.python); + strncat(*dest, ctx->meta.python, maxlen - 1); break; case 'p': // python version major/minor - strcat(*dest, ctx->meta.python_compact); + strncat(*dest, ctx->meta.python_compact, maxlen - 1); break; case 'a': // system architecture name - strcat(*dest, ctx->system.arch); + strncat(*dest, ctx->system.arch, maxlen - 1); break; case 'o': // system platform (OS) name - strcat(*dest, ctx->system.platform[DELIVERY_PLATFORM_RELEASE]); + strncat(*dest, ctx->system.platform[DELIVERY_PLATFORM_RELEASE], maxlen - 1); break; case 't': // unix epoch - sprintf(*dest + strlen(*dest), "%ld", ctx->info.time_now); + snprintf(*dest + strlen(*dest), maxlen, "%ld", ctx->info.time_now); break; default: // unknown formatter, write as-is - sprintf(*dest + strlen(*dest), "%c%c", fmt[i - 1], fmt[i]); + snprintf(*dest + strlen(*dest), maxlen, "%c%c", fmt[i - 1], fmt[i]); break; } } else { // write non-format text - sprintf(*dest + strlen(*dest), "%c", fmt[i]); + snprintf(*dest + strlen(*dest), maxlen, "%c", fmt[i]); } } return 0; diff --git a/src/lib/delivery/delivery_artifactory.c b/src/lib/delivery/delivery_artifactory.c index 97db752..ca35005 100644 --- a/src/lib/delivery/delivery_artifactory.c +++ b/src/lib/delivery/delivery_artifactory.c @@ -134,7 +134,7 @@ int delivery_mission_render_files(struct Delivery *ctx) { guard_free(data.src); return 1; } - sprintf(data.src, "%s/%s/%s", ctx->storage.mission_dir, ctx->meta.mission, val.as_char_p); + snprintf(data.src, PATH_MAX, "%s/%s/%s", ctx->storage.mission_dir, ctx->meta.mission, val.as_char_p); msg(STASIS_MSG_L2, "%s\n", data.src); int err = 0; @@ -210,7 +210,7 @@ int delivery_series_sync(struct Delivery *ctx) { } char *release_pattern = NULL; - if (delivery_format_str(ctx, &release_pattern, r_fmt) < 0) { + if (delivery_format_str(ctx, &release_pattern, STASIS_NAME_MAX, r_fmt) < 0) { SYSERROR("Unable to render delivery format string: %s", r_fmt); guard_free(r_fmt); return -1; diff --git a/src/lib/delivery/delivery_build.c b/src/lib/delivery/delivery_build.c index 0a86ec4..f3e9630 100644 --- a/src/lib/delivery/delivery_build.c +++ b/src/lib/delivery/delivery_build.c @@ -48,15 +48,15 @@ int delivery_build_recipes(struct Delivery *ctx) { // Perhaps we can key it to the recipe type, because the archive is a requirement imposed // by conda-forge. Hmm. - sprintf(recipe_version, "{%% set version = \"%s\" %%}", tag); - sprintf(recipe_git_url, " url: %s/archive/refs/tags/{{ version }}.tar.gz", ctx->tests->test[i]->repository); - strcpy(recipe_git_rev, ""); - sprintf(recipe_buildno, " number: 0"); + snprintf(recipe_version, sizeof(recipe_version), "{%% set version = \"%s\" %%}", tag); + snprintf(recipe_git_url, sizeof(recipe_git_url), " url: %s/archive/refs/tags/{{ version }}.tar.gz", ctx->tests->test[i]->repository); + strncpy(recipe_git_rev, "", sizeof(recipe_git_rev) - 1); + snprintf(recipe_buildno, sizeof(recipe_buildno), " number: 0"); unsigned flags = REPLACE_TRUNCATE_AFTER_MATCH; //file_replace_text("meta.yaml", "{% set version = ", recipe_version); if (ctx->meta.final) { // remove this. i.e. statis cannot deploy a release to conda-forge - sprintf(recipe_version, "{%% set version = \"%s\" %%}", ctx->tests->test[i]->version); + snprintf(recipe_version, sizeof(recipe_version), "{%% set version = \"%s\" %%}", ctx->tests->test[i]->version); // TODO: replace sha256 of tagged archive // TODO: leave the recipe unchanged otherwise. in theory this should produce the same conda package hash as conda forge. // For now, remove the sha256 requirement @@ -74,25 +74,25 @@ int delivery_build_recipes(struct Delivery *ctx) { char arch[STASIS_NAME_MAX] = {0}; char platform[STASIS_NAME_MAX] = {0}; - strcpy(platform, ctx->system.platform[DELIVERY_PLATFORM]); + strncpy(platform, ctx->system.platform[DELIVERY_PLATFORM], sizeof(platform) - 1); if (strstr(platform, "Darwin")) { memset(platform, 0, sizeof(platform)); - strcpy(platform, "osx"); + strncpy(platform, "osx", sizeof(platform) - 1); } tolower_s(platform); if (strstr(ctx->system.arch, "arm64")) { - strcpy(arch, "arm64"); + strncpy(arch, "arm64", sizeof(arch) - 1); } else if (strstr(ctx->system.arch, "64")) { - strcpy(arch, "64"); + strncpy(arch, "64", sizeof(arch) - 1); } else { - strcat(arch, "32"); // blind guess + strncat(arch, "32", sizeof(arch) - 1); // blind guess } tolower_s(arch); - sprintf(command, "mambabuild --python=%s -m ../.ci_support/%s_%s_.yaml .", + snprintf(command, sizeof(command), "mambabuild --python=%s -m ../.ci_support/%s_%s_.yaml .", ctx->meta.python, platform, arch); } else { - sprintf(command, "mambabuild --python=%s .", ctx->meta.python); + snprintf(command, sizeof(command), "mambabuild --python=%s .", ctx->meta.python); } int status = conda_exec(command); if (status) { @@ -131,7 +131,7 @@ int filter_repo_tags(char *repo, struct StrList *patterns) { int match = fnmatch(pattern, tag, 0); if (!match) { char cmd[PATH_MAX] = {0}; - sprintf(cmd, "git tag -d %s", tag); + snprintf(cmd, sizeof(cmd), "git tag -d %s", tag); result += system(cmd); break; } @@ -398,7 +398,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) { memset(srcdir, 0, sizeof(srcdir)); memset(wheeldir, 0, sizeof(wheeldir)); - sprintf(srcdir, "%s/%s", ctx->storage.build_sources_dir, ctx->tests->test[i]->name); + snprintf(srcdir, sizeof(srcdir), "%s/%s", ctx->storage.build_sources_dir, ctx->tests->test[i]->name); if (git_clone(&proc, ctx->tests->test[i]->repository, srcdir, ctx->tests->test[i]->version)) { SYSERROR("Unable to checkout tag '%s' for package '%s' from repository '%s'\n", ctx->tests->test[i]->version, ctx->tests->test[i]->name, ctx->tests->test[i]->repository); @@ -436,7 +436,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) { strcpy(dname, ctx->tests->test[i]->name); tolower_s(dname); - sprintf(outdir, "%s/%s", ctx->storage.wheel_artifact_dir, dname); + snprintf(outdir, sizeof(outdir), "%s/%s", ctx->storage.wheel_artifact_dir, dname); if (mkdirs(outdir, 0755)) { fprintf(stderr, "failed to create output directory: %s\n", outdir); guard_strlist_free(&result); diff --git a/src/lib/delivery/delivery_conda.c b/src/lib/delivery/delivery_conda.c index 191d93f..79aa1dc 100644 --- a/src/lib/delivery/delivery_conda.c +++ b/src/lib/delivery/delivery_conda.c @@ -1,21 +1,32 @@ #include "delivery.h" -void delivery_get_conda_installer_url(struct Delivery *ctx, char *result) { +void delivery_get_conda_installer_url(struct Delivery *ctx, char *result, size_t maxlen) { + int len = 0; if (ctx->conda.installer_version) { // Use version specified by configuration file - sprintf(result, "%s/%s-%s-%s-%s.sh", ctx->conda.installer_baseurl, + len = snprintf(NULL, 0, ctx->conda.installer_baseurl, + ctx->conda.installer_name, + ctx->conda.installer_version, + ctx->conda.installer_platform, + ctx->conda.installer_arch); + + snprintf(result, maxlen - len, "%s/%s-%s-%s-%s.sh", ctx->conda.installer_baseurl, ctx->conda.installer_name, ctx->conda.installer_version, ctx->conda.installer_platform, ctx->conda.installer_arch); } else { // Use latest installer - sprintf(result, "%s/%s-%s-%s.sh", ctx->conda.installer_baseurl, + len = snprintf(NULL, 0, "%s/%s-%s-%s.sh", ctx->conda.installer_baseurl, ctx->conda.installer_name, ctx->conda.installer_platform, ctx->conda.installer_arch); - } + snprintf(result, maxlen - len, "%s/%s-%s-%s.sh", ctx->conda.installer_baseurl, + ctx->conda.installer_name, + ctx->conda.installer_platform, + ctx->conda.installer_arch); + } } int delivery_get_conda_installer(struct Delivery *ctx, char *installer_url) { @@ -23,7 +34,7 @@ int delivery_get_conda_installer(struct Delivery *ctx, char *installer_url) { char *installer = path_basename(installer_url); memset(script_path, 0, sizeof(script_path)); - sprintf(script_path, "%s/%s", ctx->storage.tmpdir, installer); + snprintf(script_path, sizeof(script_path), "%s/%s", ctx->storage.tmpdir, installer); if (access(script_path, F_OK)) { // Script doesn't exist char *errmsg = NULL; @@ -97,7 +108,7 @@ void delivery_conda_enable(struct Delivery *ctx, char *conda_install_dir) { // way to make sure the file is used. Not setting this variable leads to strange // behavior, especially if a conda environment is already active when STASIS is loaded. char rcpath[PATH_MAX]; - sprintf(rcpath, "%s/%s", conda_install_dir, ".condarc"); + snprintf(rcpath, sizeof(rcpath), "%s/%s", conda_install_dir, ".condarc"); setenv("CONDARC", rcpath, 1); if (runtime_replace(&ctx->runtime.environ, __environ)) { perror("unable to replace runtime environment after activating conda"); diff --git a/src/lib/delivery/delivery_docker.c b/src/lib/delivery/delivery_docker.c index 2c43caf..e5f1c2f 100644 --- a/src/lib/delivery/delivery_docker.c +++ b/src/lib/delivery/delivery_docker.c @@ -19,7 +19,7 @@ int delivery_docker(struct Delivery *ctx) { msg(STASIS_MSG_WARN | STASIS_MSG_L2, "No docker tags defined by configuration. Generating default tag(s).\n"); // generate local tag memset(default_tag, 0, sizeof(default_tag)); - sprintf(default_tag, "%s:%s-py%s", ctx->meta.name, ctx->info.build_name, ctx->meta.python_compact); + snprintf(default_tag, sizeof(default_tag), "%s:%s-py%s", ctx->meta.name, ctx->info.build_name, ctx->meta.python_compact); tolower_s(default_tag); // Add tag @@ -29,7 +29,7 @@ int delivery_docker(struct Delivery *ctx) { if (has_registry) { // generate tag for target registry memset(default_tag, 0, sizeof(default_tag)); - sprintf(default_tag, "%s/%s:%s-py%s", ctx->deploy.docker.registry, ctx->meta.name, ctx->info.build_number, ctx->meta.python_compact); + snprintf(default_tag, sizeof(default_tag), "%s/%s:%s-py%s", ctx->deploy.docker.registry, ctx->meta.name, ctx->info.build_number, ctx->meta.python_compact); tolower_s(default_tag); // Add tag @@ -44,9 +44,12 @@ int delivery_docker(struct Delivery *ctx) { // Append image tags to command for (size_t i = 0; i < total_tags; i++) { char *tag_orig = strlist_item(ctx->deploy.docker.tags, i); - strcpy(tag, tag_orig); + strncpy(tag, tag_orig, sizeof(tag) - 1); docker_sanitize_tag(tag); - sprintf(args + strlen(args), " -t \"%s\" ", tag); + + const char *tag_fmt = " -t \"%s\" "; + const int tag_fmt_len = snprintf(NULL, 0, tag_fmt, tag); + snprintf(args + strlen(args), tag_fmt_len, tag_fmt, tag); } // Append build arguments to command (i.e. --build-arg "key=value" @@ -55,7 +58,10 @@ int delivery_docker(struct Delivery *ctx) { if (!build_arg) { break; } - sprintf(args + strlen(args), " --build-arg \"%s\" ", build_arg); + + const char *build_arg_fmt = " --build-arg \"%s\" "; + const int build_arg_fmt_len = snprintf(NULL, 0, build_arg_fmt, build_arg); + snprintf(args + strlen(args), sizeof(args) - build_arg_fmt_len, build_arg_fmt, build_arg); } // Build the image @@ -65,24 +71,24 @@ int delivery_docker(struct Delivery *ctx) { memset(delivery_file, 0, sizeof(delivery_file)); memset(dest, 0, sizeof(dest)); - sprintf(delivery_file, "%s/%s.yml", ctx->storage.delivery_dir, ctx->info.release_name); + snprintf(delivery_file, sizeof(delivery_file), "%s/%s.yml", ctx->storage.delivery_dir, ctx->info.release_name); if (access(delivery_file, F_OK) < 0) { fprintf(stderr, "docker build cannot proceed without delivery file: %s\n", delivery_file); return -1; } - sprintf(dest, "%s/%s.yml", ctx->storage.build_docker_dir, ctx->info.release_name); + snprintf(dest, sizeof(dest), "%s/%s.yml", ctx->storage.build_docker_dir, ctx->info.release_name); if (copy2(delivery_file, dest, CT_PERM)) { fprintf(stderr, "Failed to copy delivery file to %s: %s\n", dest, strerror(errno)); return -1; } memset(dest, 0, sizeof(dest)); - sprintf(dest, "%s/packages", ctx->storage.build_docker_dir); + snprintf(dest, sizeof(dest), "%s/packages", ctx->storage.build_docker_dir); msg(STASIS_MSG_L2, "Copying conda packages\n"); memset(rsync_cmd, 0, sizeof(rsync_cmd)); - sprintf(rsync_cmd, "rsync -avi --progress '%s' '%s'", ctx->storage.conda_artifact_dir, dest); + snprintf(rsync_cmd, sizeof(rsync_cmd), "rsync -avi --progress '%s' '%s'", ctx->storage.conda_artifact_dir, dest); if (system(rsync_cmd)) { fprintf(stderr, "Failed to copy conda artifacts to docker build directory\n"); return -1; @@ -90,7 +96,7 @@ int delivery_docker(struct Delivery *ctx) { msg(STASIS_MSG_L2, "Copying wheel packages\n"); memset(rsync_cmd, 0, sizeof(rsync_cmd)); - sprintf(rsync_cmd, "rsync -avi --progress '%s' '%s'", ctx->storage.wheel_artifact_dir, dest); + snprintf(rsync_cmd, sizeof(rsync_cmd), "rsync -avi --progress '%s' '%s'", ctx->storage.wheel_artifact_dir, dest); if (system(rsync_cmd)) { fprintf(stderr, "Failed to copy wheel artifacts to docker build directory\n"); } @@ -102,7 +108,7 @@ int delivery_docker(struct Delivery *ctx) { // Test the image // All tags point back to the same image so test the first one we see // regardless of how many are defined - strcpy(tag, strlist_item(ctx->deploy.docker.tags, 0)); + strncpy(tag, strlist_item(ctx->deploy.docker.tags, 0), sizeof(tag) - 1); docker_sanitize_tag(tag); msg(STASIS_MSG_L2, "Executing image test script for %s\n", tag); diff --git a/src/lib/delivery/delivery_export.c b/src/lib/delivery/delivery_export.c index d982ad5..c12a365 100644 --- a/src/lib/delivery/delivery_export.c +++ b/src/lib/delivery/delivery_export.c @@ -4,7 +4,7 @@ static void delivery_export_configuration(const struct Delivery *ctx) { msg(STASIS_MSG_L2, "Exporting delivery configuration\n"); if (!pushd(ctx->storage.cfgdump_dir)) { char filename[PATH_MAX] = {0}; - sprintf(filename, "%s.ini", ctx->info.release_name); + snprintf(filename, sizeof(filename), "%s.ini", ctx->info.release_name); FILE *spec = fopen(filename, "w+"); if (!spec) { msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename); @@ -14,7 +14,7 @@ static void delivery_export_configuration(const struct Delivery *ctx) { fclose(spec); memset(filename, 0, sizeof(filename)); - sprintf(filename, "%s-rendered.ini", ctx->info.release_name); + snprintf(filename, sizeof(filename), "%s-rendered.ini", ctx->info.release_name); spec = fopen(filename, "w+"); if (!spec) { msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename); diff --git a/src/lib/delivery/delivery_init.c b/src/lib/delivery/delivery_init.c index 1666f0a..2f8b21a 100644 --- a/src/lib/delivery/delivery_init.c +++ b/src/lib/delivery/delivery_init.c @@ -182,18 +182,18 @@ int delivery_init_platform(struct Delivery *ctx) { SYSDEBUG("%s", "Setting platform"); strcpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname); if (!strcmp(ctx->system.platform[DELIVERY_PLATFORM], "Darwin")) { - sprintf(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], "osx-%s", archsuffix); - strcpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "MacOSX"); - strcpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "macos"); + snprintf(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], DELIVERY_PLATFORM_MAXLEN, "osx-%s", archsuffix); + strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "MacOSX", DELIVERY_PLATFORM_MAXLEN - 1); + strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "macos", DELIVERY_PLATFORM_MAXLEN - 1); } else if (!strcmp(ctx->system.platform[DELIVERY_PLATFORM], "Linux")) { - sprintf(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], "linux-%s", archsuffix); - strcpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "Linux"); - strcpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "linux"); + snprintf(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], DELIVERY_PLATFORM_MAXLEN, "linux-%s", archsuffix); + strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "Linux", DELIVERY_PLATFORM_MAXLEN - 1); + strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "linux", DELIVERY_PLATFORM_MAXLEN - 1); } else { // Not explicitly supported systems - strcpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], ctx->system.platform[DELIVERY_PLATFORM]); - strcpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], ctx->system.platform[DELIVERY_PLATFORM]); - strcpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], ctx->system.platform[DELIVERY_PLATFORM]); + strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1); + strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1); + strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1); tolower_s(ctx->system.platform[DELIVERY_PLATFORM_RELEASE]); } @@ -203,7 +203,7 @@ int delivery_init_platform(struct Delivery *ctx) { cpu_count = 1; } char ncpus[100] = {0}; - sprintf(ncpus, "%ld", cpu_count); + snprintf(ncpus, sizeof(ncpus), "%ld", cpu_count); // Declare some important bits as environment variables setenv("CPU_COUNT", ncpus, 1); @@ -252,16 +252,16 @@ int delivery_init(struct Delivery *ctx, int render_mode) { delivery_init_dirs_stage1(ctx); char config_local[PATH_MAX]; - sprintf(config_local, "%s/%s", ctx->storage.tmpdir, "config"); + snprintf(config_local, sizeof(config_local), "%s/%s", ctx->storage.tmpdir, "config"); setenv("XDG_CONFIG_HOME", config_local, 1); char cache_local[PATH_MAX]; - sprintf(cache_local, "%s/%s", ctx->storage.tmpdir, "cache"); + snprintf(cache_local, sizeof(cache_local), "%s/%s", ctx->storage.tmpdir, "cache"); setenv("XDG_CACHE_HOME", cache_local, 1); // add tools to PATH char pathvar_tmp[STASIS_BUFSIZ]; - sprintf(pathvar_tmp, "%s/bin:%s", ctx->storage.tools_dir, getenv("PATH")); + snprintf(pathvar_tmp, sizeof(pathvar_tmp), "%s/bin:%s", ctx->storage.tools_dir, getenv("PATH")); setenv("PATH", pathvar_tmp, 1); // Prevent git from paginating output @@ -336,7 +336,7 @@ int bootstrap_build_info(struct Delivery *ctx) { int delivery_exists(struct Delivery *ctx) { int release_exists = DELIVERY_NOT_FOUND; char release_pattern[PATH_MAX] = {0}; - sprintf(release_pattern, "*%s*", ctx->info.release_name); + snprintf(release_pattern, sizeof(release_pattern), "*%s*", ctx->info.release_name); if (globals.enable_artifactory) { if (jfrt_auth_init(&ctx->deploy.jfrog_auth)) { diff --git a/src/lib/delivery/delivery_install.c b/src/lib/delivery/delivery_install.c index 2de80cf..fe3bc66 100644 --- a/src/lib/delivery/delivery_install.c +++ b/src/lib/delivery/delivery_install.c @@ -222,7 +222,9 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha if (!ctx->meta.based_on) { strcat(command_base, " --upgrade"); } - sprintf(command_base + strlen(command_base), " --extra-index-url 'file://%s'", ctx->storage.wheel_artifact_dir); + const char *command_base_fmt = " --extra-index-url 'file://%s'"; + const int len = snprintf(NULL, 0, command_base_fmt, ctx->storage.wheel_artifact_dir); + snprintf(command_base + strlen(command_base), sizeof(command_base) - len, command_base_fmt, ctx->storage.wheel_artifact_dir); } size_t args_alloc_len = STASIS_BUFSIZ; diff --git a/src/lib/delivery/delivery_populate.c b/src/lib/delivery/delivery_populate.c index d41e3a4..3ce29e9 100644 --- a/src/lib/delivery/delivery_populate.c +++ b/src/lib/delivery/delivery_populate.c @@ -256,16 +256,16 @@ int populate_delivery_ini(struct Delivery *ctx, int render_mode) { return -1; } - if (delivery_format_str(ctx, &ctx->info.release_name, ctx->rules.release_fmt)) { + if (delivery_format_str(ctx, &ctx->info.release_name, STASIS_NAME_MAX, ctx->rules.release_fmt)) { fprintf(stderr, "Failed to generate release name. Format used: %s\n", ctx->rules.release_fmt); return -1; } if (!ctx->info.build_name) { - delivery_format_str(ctx, &ctx->info.build_name, ctx->rules.build_name_fmt); + delivery_format_str(ctx, &ctx->info.build_name, STASIS_NAME_MAX, ctx->rules.build_name_fmt); } if (!ctx->info.build_number) { - delivery_format_str(ctx, &ctx->info.build_number, ctx->rules.build_number_fmt); + delivery_format_str(ctx, &ctx->info.build_number, STASIS_NAME_MAX, ctx->rules.build_number_fmt); } // Best I can do to make output directories unique. Annoying. @@ -376,10 +376,10 @@ int populate_mission_ini(struct Delivery **ctx, int render_mode) { // Now populate the rules char missionfile[PATH_MAX] = {0}; if (getenv("STASIS_SYSCONFDIR")) { - sprintf(missionfile, "%s/%s/%s/%s.ini", + snprintf(missionfile, sizeof(missionfile), "%s/%s/%s/%s.ini", getenv("STASIS_SYSCONFDIR"), "mission", (*ctx)->meta.mission, (*ctx)->meta.mission); } else { - sprintf(missionfile, "%s/%s/%s/%s.ini", + snprintf(missionfile, sizeof(missionfile), "%s/%s/%s/%s.ini", globals.sysconfdir, "mission", (*ctx)->meta.mission, (*ctx)->meta.mission); } diff --git a/src/lib/delivery/delivery_postprocess.c b/src/lib/delivery/delivery_postprocess.c index a7bb2b4..d0027e7 100644 --- a/src/lib/delivery/delivery_postprocess.c +++ b/src/lib/delivery/delivery_postprocess.c @@ -11,7 +11,7 @@ char *delivery_get_release_header(struct Delivery *ctx) { char output[STASIS_BUFSIZ]; char stamp[100]; strftime(stamp, sizeof(stamp) - 1, "%c", ctx->info.time_info); - sprintf(output, release_header, + snprintf(output, sizeof(output), release_header, ctx->info.release_name, ctx->rules.release_fmt, stamp, @@ -22,7 +22,7 @@ char *delivery_get_release_header(struct Delivery *ctx) { int delivery_dump_metadata(struct Delivery *ctx) { char filename[PATH_MAX]; - sprintf(filename, "%s/meta-%s.stasis", ctx->storage.meta_dir, ctx->info.release_name); + snprintf(filename, sizeof(filename), "%s/meta-%s.stasis", ctx->storage.meta_dir, ctx->info.release_name); FILE *fp = fopen(filename, "w+"); if (!fp) { return -1; @@ -143,7 +143,7 @@ void delivery_rewrite_spec(struct Delivery *ctx, char *filename, unsigned stage) file_replace_text(filename, "@CONDA_CHANNEL@", ctx->storage.conda_staging_url, 0); } else if (globals.jfrog.repo) { SYSDEBUG("%s", "Will replace conda channel with artifactory repo packages/conda url"); - sprintf(output, "%s/%s/%s/%s/packages/conda", globals.jfrog.url, globals.jfrog.repo, ctx->meta.mission, ctx->info.build_name); + snprintf(output, sizeof(output), "%s/%s/%s/%s/packages/conda", globals.jfrog.url, globals.jfrog.repo, ctx->meta.mission, ctx->info.build_name); file_replace_text(filename, "@CONDA_CHANNEL@", output, 0); } else { SYSDEBUG("%s", "Will replace conda channel with local conda artifact directory"); @@ -153,16 +153,16 @@ void delivery_rewrite_spec(struct Delivery *ctx, char *filename, unsigned stage) if (ctx->storage.wheel_staging_url) { SYSDEBUG("%s", "Will replace pip arguments with wheel staging url"); - sprintf(output, "--extra-index-url %s/%s/%s/packages/wheels", ctx->storage.wheel_staging_url, ctx->meta.mission, ctx->info.build_name); + snprintf(output, sizeof(output), "--extra-index-url %s/%s/%s/packages/wheels", ctx->storage.wheel_staging_url, ctx->meta.mission, ctx->info.build_name); file_replace_text(filename, "@PIP_ARGUMENTS@", ctx->storage.wheel_staging_url, 0); } else if (globals.enable_artifactory && globals.jfrog.url && globals.jfrog.repo) { SYSDEBUG("%s", "Will replace pip arguments with artifactory repo packages/wheel url"); - sprintf(output, "--extra-index-url %s/%s/%s/%s/packages/wheels", globals.jfrog.url, globals.jfrog.repo, ctx->meta.mission, ctx->info.build_name); + snprintf(output, sizeof(output), "--extra-index-url %s/%s/%s/%s/packages/wheels", globals.jfrog.url, globals.jfrog.repo, ctx->meta.mission, ctx->info.build_name); file_replace_text(filename, "@PIP_ARGUMENTS@", output, 0); } else { SYSDEBUG("%s", "Will replace pip arguments with local wheel artifact directory"); msg(STASIS_MSG_WARN, "wheel_staging_dir is not configured. Using fallback: '%s'\n", ctx->storage.wheel_artifact_dir); - sprintf(output, "--extra-index-url file://%s", ctx->storage.wheel_artifact_dir); + snprintf(output, sizeof(output), "--extra-index-url file://%s", ctx->storage.wheel_artifact_dir); file_replace_text(filename, "@PIP_ARGUMENTS@", output, 0); } } @@ -177,7 +177,7 @@ int delivery_copy_conda_artifacts(struct Delivery *ctx) { memset(conda_build_dir, 0, sizeof(conda_build_dir)); memset(subdir, 0, sizeof(subdir)); - sprintf(conda_build_dir, "%s/%s", ctx->storage.conda_install_prefix, "conda-bld"); + snprintf(conda_build_dir, sizeof(conda_build_dir), "%s/%s", ctx->storage.conda_install_prefix, "conda-bld"); // One must run conda build at least once to create the "conda-bld" directory. // When this directory is missing there can be no build artifacts. if (access(conda_build_dir, F_OK) < 0) { @@ -217,7 +217,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) { // Generate a "dumb" local pypi index that is compatible with: // pip install --extra-index-url char top_index[PATH_MAX] = {0}; - sprintf(top_index, "%s/index.html", ctx->storage.wheel_artifact_dir); + snprintf(top_index, sizeof(top_index),"%s/index.html", ctx->storage.wheel_artifact_dir); SYSDEBUG("Opening top-level index for writing: %s", top_index); FILE *top_fp = fopen(top_index, "w+"); if (!top_fp) { @@ -232,7 +232,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) { } char bottom_index[PATH_MAX * 2] = {0}; - sprintf(bottom_index, "%s/%s/index.html", ctx->storage.wheel_artifact_dir, rec->d_name); + snprintf(bottom_index, sizeof(bottom_index), "%s/%s/index.html", ctx->storage.wheel_artifact_dir, rec->d_name); SYSDEBUG("Opening bottom-level for writing: %s", bottom_index); FILE *bottom_fp = fopen(bottom_index, "w+"); if (!bottom_fp) { @@ -248,7 +248,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) { fprintf(top_fp, "<a href=\"%s/\">%s</a><br/>\n", rec->d_name, rec->d_name); char dpath[PATH_MAX * 2] = {0}; - sprintf(dpath, "%s/%s", ctx->storage.wheel_artifact_dir, rec->d_name); + snprintf(dpath, sizeof(dpath), "%s/%s", ctx->storage.wheel_artifact_dir, rec->d_name); struct StrList *packages = listdir(dpath); if (!packages) { closedir(dp); diff --git a/src/lib/delivery/delivery_test.c b/src/lib/delivery/delivery_test.c index 96dbb10..a116479 100644 --- a/src/lib/delivery/delivery_test.c +++ b/src/lib/delivery/delivery_test.c @@ -156,7 +156,7 @@ void delivery_tests_run(struct Delivery *ctx) { } char destdir[PATH_MAX]; - sprintf(destdir, "%s/%s", ctx->storage.build_sources_dir, path_basename(test->repository)); + snprintf(destdir, sizeof(destdir), "%s/%s", ctx->storage.build_sources_dir, path_basename(test->repository)); if (!access(destdir, F_OK)) { msg(STASIS_MSG_L3, "Purging repository %s\n", destdir); @@ -267,7 +267,7 @@ void delivery_tests_run(struct Delivery *ctx) { const struct Test *test = ctx->tests->test[i]; if (test->script_setup) { char destdir[PATH_MAX]; - sprintf(destdir, "%s/%s", ctx->storage.build_sources_dir, path_basename(test->repository)); + snprintf(destdir, sizeof(destdir), "%s/%s", ctx->storage.build_sources_dir, path_basename(test->repository)); if (access(destdir, F_OK)) { SYSERROR("%s: %s", destdir, strerror(errno)); exit(1); @@ -382,7 +382,7 @@ int delivery_fixup_test_results(struct Delivery *ctx) { continue; } - sprintf(path, "%s/%s", ctx->storage.results_dir, rec->d_name); + snprintf(path, sizeof(path), "%s/%s", ctx->storage.results_dir, rec->d_name); msg(STASIS_MSG_L3, "%s\n", rec->d_name); if (xml_pretty_print_in_place(path, STASIS_XML_PRETTY_PRINT_PROG, STASIS_XML_PRETTY_PRINT_ARGS)) { msg(STASIS_MSG_L3 | STASIS_MSG_WARN, "Failed to rewrite file '%s'\n", rec->d_name); diff --git a/src/lib/delivery/include/delivery.h b/src/lib/delivery/include/delivery.h index 68f4b14..e524f4d 100644 --- a/src/lib/delivery/include/delivery.h +++ b/src/lib/delivery/include/delivery.h @@ -321,9 +321,10 @@ int delivery_get_conda_installer(struct Delivery *ctx, char *installer_url); * Generate URL based on Delivery context * @param ctx pointer to Delivery context * @param result pointer to char + * @param maxlen * @return in result */ -void delivery_get_conda_installer_url(struct Delivery *ctx, char *result); +void delivery_get_conda_installer_url(struct Delivery *ctx, char *result, size_t maxlen); /** * Install packages based on Delivery context @@ -394,10 +395,11 @@ void delivery_install_conda(char *install_script, char *conda_install_dir); * * @param ctx pointer to Delivery context * @param dest NULL pointer to string, or initialized string + * @param maxlen * @param fmt release format string * @return 0 on success, -1 on error */ -int delivery_format_str(struct Delivery *ctx, char **dest, const char *fmt); +int delivery_format_str(struct Delivery *ctx, char **dest, size_t maxlen, const char *fmt); // helper function int delivery_gather_tool_versions(struct Delivery *ctx); diff --git a/tests/test_artifactory.c b/tests/test_artifactory.c index 202a67c..0d84289 100644 --- a/tests/test_artifactory.c +++ b/tests/test_artifactory.c @@ -60,7 +60,7 @@ void test_jfrog_cli_rt_download() { char *filename = "empty_file_upload.txt"; char path[PATH_MAX] = {0}; - sprintf(path, "%s/%s", getenv("STASIS_JF_REPO"), filename); + snprintf(path, sizeof(path), "%s/%s", getenv("STASIS_JF_REPO"), filename); STASIS_ASSERT(jfrog_cli_rt_download(&gauth, &dl, filename, ".") == 0, "jf download failed"); STASIS_ASSERT(jfrog_cli_rt_delete(&gauth, path) == 0, "jf delete test artifact failed"); } @@ -93,15 +93,15 @@ int main(int argc, char *argv[]) { } char path[PATH_MAX] = {0}; - sprintf(path, "%s/bin:%s", ctx.storage.tools_dir, getenv("PATH")); + snprintf(path, sizeof(path), "%s/bin:%s", ctx.storage.tools_dir, getenv("PATH")); setenv("PATH", path, 1); // The default config contains the URL information to download jfrog-cli char cfg_path[PATH_MAX] = {0}; if (strstr(sysconfdir, "..")) { - sprintf(cfg_path, "%s/%s/stasis.ini", basedir, sysconfdir); + snprintf(cfg_path, sizeof(cfg_path), "%s/%s/stasis.ini", basedir, sysconfdir); } else { - sprintf(cfg_path, "%s/stasis.ini", sysconfdir); + snprintf(cfg_path, sizeof(cfg_path), "%s/stasis.ini", sysconfdir); } ctx._stasis_ini_fp.cfg = ini_open(cfg_path); if (!ctx._stasis_ini_fp.cfg) { diff --git a/tests/test_conda.c b/tests/test_conda.c index 1d05e7e..9f0e718 100644 --- a/tests/test_conda.c +++ b/tests/test_conda.c @@ -40,7 +40,7 @@ struct Delivery ctx; void test_conda_installation() { char *install_url = calloc(255, sizeof(install_url)); - delivery_get_conda_installer_url(&ctx, install_url); + delivery_get_conda_installer_url(&ctx, install_url, PATH_MAX); delivery_get_conda_installer(&ctx, install_url); delivery_install_conda(ctx.conda.installer_path, ctx.storage.conda_install_prefix); @@ -92,7 +92,7 @@ void test_conda_exec() { void test_python_exec() { const char *python_system_path = find_program("python3"); char python_path[PATH_MAX]; - sprintf(python_path, "%s/bin/python3", ctx.storage.conda_install_prefix); + snprintf(python_path, sizeof(python_path), "%s/bin/python3", ctx.storage.conda_install_prefix); STASIS_ASSERT(strcmp(python_path, python_system_path ? python_system_path : "/not/found") == 0, "conda is not configured correctly."); STASIS_ASSERT(python_exec("-V") == 0, "python is broken"); diff --git a/tests/test_environment.c b/tests/test_environment.c index 4f36883..9a503c0 100644 --- a/tests/test_environment.c +++ b/tests/test_environment.c @@ -58,7 +58,7 @@ void test_runtime() { char output_truth[BUFSIZ] = {0}; char *your_path = runtime_get(env, "PATH"); - sprintf(output_truth, "Your PATH is '%s'.", your_path); + snprintf(output_truth, sizeof(output_truth), "Your PATH is '%s'.", your_path); guard_free(your_path); char *output_expanded = runtime_expand_var(env, "Your PATH is '${PATH}'."); diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index 3a462f1..3b98b77 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -65,7 +65,7 @@ void test_mp_task() { for (size_t i = 0; i < sizeof(commands) / sizeof(*commands); i++) { struct MultiProcessingTask *task; char task_name[100] = {0}; - sprintf(task_name, "mytask%zu", i); + snprintf(task_name, sizeof(task_name), "mytask%zu", i); STASIS_ASSERT_FATAL((task = mp_pool_task(pool, task_name, NULL, commands[i])) != NULL, "Task should not be NULL"); STASIS_ASSERT(task->pid == MP_POOL_PID_UNUSED, "PID should be non-zero at this point"); STASIS_ASSERT(task->parent_pid == MP_POOL_PID_UNUSED, "Parent PID should be non-zero"); diff --git a/tests/test_recipe.c b/tests/test_recipe.c index fc7cc78..3ea21ce 100644 --- a/tests/test_recipe.c +++ b/tests/test_recipe.c @@ -4,7 +4,7 @@ static void make_local_recipe(const char *localdir) { char path[PATH_MAX] = {0}; - sprintf(path, "./%s", localdir); + snprintf(path, sizeof(path), "./%s", localdir); mkdir(path, 0755); if (!pushd(path)) { touch("meta.yaml"); diff --git a/tests/test_system.c b/tests/test_system.c index 2271e13..9e4a862 100644 --- a/tests/test_system.c +++ b/tests/test_system.c @@ -54,7 +54,7 @@ void test_shell_safe_verify_restrictions() { char cmd[PATH_MAX] = {0}; memset(&proc, 0, sizeof(proc)); - sprintf(cmd, "true%c false", invalid_chars[i]); + snprintf(cmd, sizeof(cmd), "true%c false", invalid_chars[i]); shell_safe(&proc, cmd); STASIS_ASSERT(proc.returncode == -1, "expected a negative result due to intentional error"); } diff --git a/tests/test_template.c b/tests/test_template.c index 596c2b7..aaba03b 100644 --- a/tests/test_template.c +++ b/tests/test_template.c @@ -10,8 +10,9 @@ static int adder(struct tplfunc_frame *frame, void *result) { int a = (int) strtol(frame->argv[0].t_char_ptr, NULL, 10); int b = (int) strtol(frame->argv[1].t_char_ptr, NULL, 10); char **ptr = (char **) result; - *ptr = calloc(100, sizeof(*ptr)); - sprintf(*ptr, "%d", a + b); + const size_t sz = 100; + *ptr = calloc(sz, sizeof(*ptr)); + snprintf(*ptr, sz, "%d", a + b); return 0; } @@ -19,8 +20,9 @@ static int subtractor(struct tplfunc_frame *frame, void *result) { int a = (int) strtol(frame->argv[0].t_char_ptr, NULL, 10); int b = (int) strtol(frame->argv[1].t_char_ptr, NULL, 10); char **ptr = (char **) result; - *ptr = calloc(100, sizeof(*ptr)); - sprintf(*ptr, "%d", a - b); + const size_t sz = 100; + *ptr = calloc(sz, sizeof(*ptr)); + snprintf(*ptr, sz, "%d", a - b); return 0; } @@ -28,8 +30,9 @@ static int multiplier(struct tplfunc_frame *frame, void *result) { int a = (int) strtol(frame->argv[0].t_char_ptr, NULL, 10); int b = (int) strtol(frame->argv[1].t_char_ptr, NULL, 10); char **ptr = (char **) result; - *ptr = calloc(100, sizeof(*ptr)); - sprintf(*ptr, "%d", a * b); + const size_t sz = 100; + *ptr = calloc(sz, sizeof(*ptr)); + snprintf(*ptr, sz, "%d", a * b); return 0; } @@ -37,8 +40,9 @@ static int divider(struct tplfunc_frame *frame, void *result) { int a = (int) strtol(frame->argv[0].t_char_ptr, NULL, 10); int b = (int) strtol(frame->argv[1].t_char_ptr, NULL, 10); char **ptr = (char **) result; - *ptr = calloc(100, sizeof(*ptr)); - sprintf(*ptr, "%d", a / b); + size_t sz = 100; + *ptr = calloc(sz, sizeof(*ptr)); + snprintf(*ptr, sz, "%d", a / b); return 0; } diff --git a/tests/test_utils.c b/tests/test_utils.c index cfe79e0..5766f6c 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -129,7 +129,7 @@ void test_isempty_dir() { STASIS_ASSERT(isempty_dir(dname) > 0, "empty directory went undetected"); char path[PATH_MAX]; - sprintf(path, "%s/file.txt", dname); + snprintf(path, sizeof(path), "%s/file.txt", dname); touch(path); STASIS_ASSERT(isempty_dir(dname) == 0, "populated directory went undetected"); @@ -193,7 +193,7 @@ void test_git_clone_and_describe() { // initialize a bare repo so we can clone it char init_cmd[PATH_MAX]; - sprintf(init_cmd, "git init --bare %s", repo_git); + snprintf(init_cmd, sizeof(init_cmd), "git init --bare %s", repo_git); system(init_cmd); // clone the bare repo @@ -366,8 +366,8 @@ void test_rmtree() { for (size_t i = 0; i < sizeof(tree) / sizeof(*tree); i++) { char path[PATH_MAX]; char mockfile[PATH_MAX + 10]; - sprintf(path, "%s/%s", root, tree[i]); - sprintf(mockfile, "%s/%zu.txt", path, i); + snprintf(path, sizeof(path), "%s/%s", root, tree[i]); + snprintf(mockfile, sizeof(mockfile), "%s/%zu.txt", path, i); if (mkdir(path, 0755)) { perror(path); STASIS_ASSERT(false, NULL); diff --git a/tests/test_wheel.c b/tests/test_wheel.c index 1eabb1b..531e4b7 100644 --- a/tests/test_wheel.c +++ b/tests/test_wheel.c @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) { } char *install_url = calloc(255, sizeof(install_url)); - delivery_get_conda_installer_url(&ctx, install_url); + delivery_get_conda_installer_url(&ctx, install_url, PATH_MAX); delivery_get_conda_installer(&ctx, install_url); delivery_install_conda(ctx.conda.installer_path, ctx.storage.conda_install_prefix); guard_free(install_url); |
