aboutsummaryrefslogtreecommitdiff
path: root/src/lib/delivery
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/delivery')
-rw-r--r--src/lib/delivery/delivery.c39
-rw-r--r--src/lib/delivery/delivery_artifactory.c14
-rw-r--r--src/lib/delivery/delivery_build.c34
-rw-r--r--src/lib/delivery/delivery_conda.c27
-rw-r--r--src/lib/delivery/delivery_docker.c28
-rw-r--r--src/lib/delivery/delivery_export.c4
-rw-r--r--src/lib/delivery/delivery_init.c34
-rw-r--r--src/lib/delivery/delivery_install.c22
-rw-r--r--src/lib/delivery/delivery_populate.c10
-rw-r--r--src/lib/delivery/delivery_postprocess.c24
-rw-r--r--src/lib/delivery/delivery_test.c12
-rw-r--r--src/lib/delivery/include/delivery.h6
12 files changed, 139 insertions, 115 deletions
diff --git a/src/lib/delivery/delivery.c b/src/lib/delivery/delivery.c
index be6e8ff..7d78878 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;
@@ -335,11 +338,11 @@ void delivery_defer_packages(struct Delivery *ctx, int type) {
if (DEFER_CONDA == type) {
dataptr = ctx->conda.conda_packages;
deferred = ctx->conda.conda_packages_defer;
- strcpy(mode, "conda");
+ strncpy(mode, "conda", sizeof(mode) - 1);
} else if (DEFER_PIP == type) {
dataptr = ctx->conda.pip_packages;
deferred = ctx->conda.pip_packages_defer;
- strcpy(mode, "pip");
+ strncpy(mode, "pip", sizeof(mode) - 1);
} else {
SYSERROR("BUG: type %d does not map to a supported package manager!\n", type);
exit(1);
diff --git a/src/lib/delivery/delivery_artifactory.c b/src/lib/delivery/delivery_artifactory.c
index 97db752..0a74241 100644
--- a/src/lib/delivery/delivery_artifactory.c
+++ b/src/lib/delivery/delivery_artifactory.c
@@ -4,8 +4,8 @@ int delivery_init_artifactory(struct Delivery *ctx) {
int status = 0;
char dest[PATH_MAX] = {0};
char filepath[PATH_MAX] = {0};
- snprintf(dest, sizeof(dest) - 1, "%s/bin", ctx->storage.tools_dir);
- snprintf(filepath, sizeof(dest) - 1, "%s/bin/jf", ctx->storage.tools_dir);
+ snprintf(dest, sizeof(dest), "%s/bin", ctx->storage.tools_dir);
+ snprintf(filepath, sizeof(dest), "%s/bin/jf", ctx->storage.tools_dir);
if (!access(filepath, F_OK)) {
// already have it
@@ -32,7 +32,7 @@ int delivery_init_artifactory(struct Delivery *ctx) {
// JFROG_CLI_HOME_DIR is where .jfrog is stored
char path[PATH_MAX] = {0};
- snprintf(path, sizeof(path) - 1, "%s/.jfrog", ctx->storage.build_dir);
+ snprintf(path, sizeof(path), "%s/.jfrog", ctx->storage.build_dir);
setenv("JFROG_CLI_HOME_DIR", path, 1);
// JFROG_CLI_TEMP_DIR is where the obvious is stored
@@ -84,8 +84,8 @@ int delivery_artifact_upload(struct Delivery *ctx) {
for (size_t f = 0; f < strlist_count(ctx->deploy.jfrog[i].files); f++) {
char dest[PATH_MAX] = {0};
char files[PATH_MAX] = {0};
- snprintf(dest, sizeof(dest) - 1, "%s/%s", ctx->deploy.jfrog[i].repo, ctx->deploy.jfrog[i].dest);
- snprintf(files, sizeof(files) - 1, "%s", strlist_item(ctx->deploy.jfrog[i].files, f));
+ snprintf(dest, sizeof(dest), "%s/%s", ctx->deploy.jfrog[i].repo, ctx->deploy.jfrog[i].dest);
+ snprintf(files, sizeof(files), "%s", strlist_item(ctx->deploy.jfrog[i].files, f));
status += jfrog_cli_rt_upload(&ctx->deploy.jfrog_auth, &ctx->deploy.jfrog[i].upload_ctx, files, dest);
}
}
@@ -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..3ff5df7 100644
--- a/src/lib/delivery/delivery_build.c
+++ b/src/lib/delivery/delivery_build.c
@@ -37,7 +37,7 @@ int delivery_build_recipes(struct Delivery *ctx) {
tag[strlen(ctx->tests->test[i]->repository_info_tag)] = '\0';
}
} else {
- strcpy(tag, ctx->tests->test[i]->version);
+ strncpy(tag, ctx->tests->test[i]->version, sizeof(tag) - 1);
}
//sprintf(recipe_version, "{%% set version = GIT_DESCRIBE_TAG ~ \".dev\" ~ GIT_DESCRIBE_NUMBER ~ \"+\" ~ GIT_DESCRIBE_HASH %%}");
@@ -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);
@@ -434,9 +434,9 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) {
COE_CHECK_ABORT(dep_status, "Unreproducible delivery");
}
- strcpy(dname, ctx->tests->test[i]->name);
+ strncpy(dname, ctx->tests->test[i]->name, sizeof(dname) - 1);
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..d6898a4 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;
@@ -61,7 +72,7 @@ void delivery_install_conda(char *install_script, char *conda_install_dir) {
// Proceed with the installation
// -b = batch mode (non-interactive)
char cmd[PATH_MAX] = {0};
- snprintf(cmd, sizeof(cmd) - 1, "%s %s -b -p %s",
+ snprintf(cmd, sizeof(cmd), "%s %s -b -p %s",
find_program("bash"),
install_script,
conda_install_dir);
@@ -73,7 +84,7 @@ void delivery_install_conda(char *install_script, char *conda_install_dir) {
// Proceed with the installation
// -b = batch mode (non-interactive)
char cmd[PATH_MAX] = {0};
- snprintf(cmd, sizeof(cmd) - 1, "%s %s -b -p %s",
+ snprintf(cmd, sizeof(cmd), "%s %s -b -p %s",
find_program("bash"),
install_script,
conda_install_dir);
@@ -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..ff877f0 100644
--- a/src/lib/delivery/delivery_init.c
+++ b/src/lib/delivery/delivery_init.c
@@ -174,26 +174,26 @@ int delivery_init_platform(struct Delivery *ctx) {
}
if (!strcmp(ctx->system.arch, "x86_64")) {
- strcpy(archsuffix, "64");
+ strncpy(archsuffix, "64", sizeof(archsuffix) - 1);
} else {
- strcpy(archsuffix, ctx->system.arch);
+ strncpy(archsuffix, ctx->system.arch, sizeof(archsuffix) - 1);
}
SYSDEBUG("%s", "Setting platform");
- strcpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname);
+ strncpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname, DELIVERY_PLATFORM_MAXLEN - 1);
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..1e2b82c 100644
--- a/src/lib/delivery/delivery_install.c
+++ b/src/lib/delivery/delivery_install.c
@@ -145,16 +145,16 @@ int delivery_purge_packages(struct Delivery *ctx, const char *env_name, int use_
case PKG_USE_CONDA:
fn = conda_exec;
list = ctx->conda.conda_packages_purge;
- strcpy(package_manager, "conda");
+ strncpy(package_manager, "conda", sizeof(package_manager) - 1);
// conda is already configured for "always_yes"
- strcpy(subcommand, "remove");
+ strncpy(subcommand, "remove", sizeof(subcommand) - 1);
break;
case PKG_USE_PIP:
fn = pip_exec;
list = ctx->conda.pip_packages_purge;
- strcpy(package_manager, "pip");
+ strncpy(package_manager, "pip", sizeof(package_manager) - 1);
// avoid user prompt to remove packages
- strcpy(subcommand, "uninstall -y");
+ strncpy(subcommand, "uninstall -y", sizeof(subcommand) - 1);
break;
default:
SYSERROR("Unknown package manager: %d", use_pkg_manager);
@@ -203,7 +203,7 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha
}
memset(command_base, 0, sizeof(command_base));
- strcat(command_base, "install");
+ strncat(command_base, "install", sizeof(command_base) - strlen(command_base) - 1);
typedef int (*Runner)(const char *);
Runner runner = NULL;
@@ -214,15 +214,17 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha
}
if (INSTALL_PKG_CONDA_DEFERRED & type) {
- strcat(command_base, " --use-local");
+ strncat(command_base, " --use-local", sizeof(command_base) - strlen(command_base) - 1);
} else if (INSTALL_PKG_PIP_DEFERRED & type) {
// Don't change the baseline package set unless we're working with a
// new build. Release candidates will need to keep packages as stable
// as possible between releases.
if (!ctx->meta.based_on) {
- strcat(command_base, " --upgrade");
+ strncat(command_base, " --upgrade", sizeof(command_base) - strlen(command_base) - 1);
}
- 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;
@@ -287,9 +289,9 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha
char req[255] = {0};
if (!strcmp(name, info->name)) {
- strcpy(req, info->name);
+ strncpy(req, info->name, sizeof(req) - 1);
} else {
- strcpy(req, name);
+ strncpy(req, name, sizeof(req) - 1);
char *spec = find_version_spec(req);
if (spec) {
*spec = 0;
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..8cb4e65 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) {
@@ -186,7 +186,7 @@ int delivery_copy_conda_artifacts(struct Delivery *ctx) {
return 0;
}
- snprintf(cmd, sizeof(cmd) - 1, "rsync -avi --progress %s/%s %s",
+ snprintf(cmd, sizeof(cmd), "rsync -avi --progress %s/%s %s",
conda_build_dir,
ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR],
ctx->storage.conda_artifact_dir);
@@ -200,7 +200,7 @@ int delivery_index_conda_artifacts(struct Delivery *ctx) {
int delivery_copy_wheel_artifacts(struct Delivery *ctx) {
char cmd[PATH_MAX] = {0};
- snprintf(cmd, sizeof(cmd) - 1, "rsync -avi --progress %s/*/dist/*.whl %s",
+ snprintf(cmd, sizeof(cmd), "rsync -avi --progress %s/*/dist/*.whl %s",
ctx->storage.build_sources_dir,
ctx->storage.wheel_artifact_dir);
return system(cmd);
@@ -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..a088cd7 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);
@@ -200,11 +200,11 @@ void delivery_tests_run(struct Delivery *ctx) {
msg(STASIS_MSG_L3, "Queuing task for %s\n", test->name);
memset(&proc, 0, sizeof(proc));
- strcpy(cmd, test->script);
+ strncpy(cmd, test->script, strlen(test->script) + STASIS_BUFSIZ - 1);
char *cmd_rendered = tpl_render(cmd);
if (cmd_rendered) {
if (strcmp(cmd_rendered, cmd) != 0) {
- strcpy(cmd, cmd_rendered);
+ strncpy(cmd, cmd_rendered, strlen(test->script) + STASIS_BUFSIZ - 1);
cmd[strlen(cmd_rendered) ? strlen(cmd_rendered) - 1 : 0] = 0;
}
guard_free(cmd_rendered);
@@ -229,7 +229,7 @@ void delivery_tests_run(struct Delivery *ctx) {
if (!globals.enable_parallel || !test->parallel) {
selected = SERIAL;
memset(pool_name, 0, sizeof(pool_name));
- strcpy(pool_name, "serial");
+ strncpy(pool_name, "serial", sizeof(pool_name) - 1);
}
if (asprintf(&runner_cmd, runner_cmd_fmt, cmd) < 0) {
@@ -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);