aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2026-06-02 17:04:13 -0400
committerGitHub <noreply@github.com>2026-06-02 17:04:13 -0400
commit252b9646c1cb0538123d51ced4a733f3dcfc266b (patch)
tree84b300af068db367bd9f3262487aeef3c7ba22d0 /src
parentd8ee8c27444a56bb98dd8bd67a019a1e9efbcc10 (diff)
downloadstasis-252b9646c1cb0538123d51ced4a733f3dcfc266b.tar.gz
Safe strings, finally (#145)
* Add string copy and catonate replacements * safe_strncpy * safe_strncat * Replace string functions * gbo.ini: Update tweakwcs to 0.9.0 * generic.ini: Update tweakwcs to 0.9.0
Diffstat (limited to 'src')
-rw-r--r--src/cli/stasis/args.c12
-rw-r--r--src/cli/stasis/stasis_main.c26
-rw-r--r--src/cli/stasis_indexer/helpers.c43
-rw-r--r--src/cli/stasis_indexer/junitxml_report.c3
-rw-r--r--src/cli/stasis_indexer/stasis_indexer_main.c29
-rw-r--r--src/cli/stasis_indexer/website.c7
-rw-r--r--src/lib/core/artifactory.c32
-rw-r--r--src/lib/core/conda.c49
-rw-r--r--src/lib/core/copy.c3
-rw-r--r--src/lib/core/docker.c28
-rw-r--r--src/lib/core/environment.c9
-rw-r--r--src/lib/core/github.c2
-rw-r--r--src/lib/core/include/str.h3
-rw-r--r--src/lib/core/ini.c35
-rw-r--r--src/lib/core/multiprocessing.c2
-rw-r--r--src/lib/core/recipe.c3
-rw-r--r--src/lib/core/relocation.c3
-rw-r--r--src/lib/core/str.c41
-rw-r--r--src/lib/core/strlist.c6
-rw-r--r--src/lib/core/system.c2
-rw-r--r--src/lib/core/template.c5
-rw-r--r--src/lib/core/template_func_proto.c6
-rw-r--r--src/lib/core/utils.c67
-rw-r--r--src/lib/core/wheel.c3
-rw-r--r--src/lib/core/wheelinfo.c6
-rw-r--r--src/lib/delivery/delivery_build.c30
-rw-r--r--src/lib/delivery/delivery_docker.c6
-rw-r--r--src/lib/delivery/delivery_init.c29
-rw-r--r--src/lib/delivery/delivery_install.c48
-rw-r--r--src/lib/delivery/delivery_test.c15
30 files changed, 230 insertions, 323 deletions
diff --git a/src/cli/stasis/args.c b/src/cli/stasis/args.c
index eb096bc..c1bf031 100644
--- a/src/cli/stasis/args.c
+++ b/src/cli/stasis/args.c
@@ -89,20 +89,20 @@ void usage(char *progname) {
char opt_long[50] = {0}; // --? [ARG]?
char opt_short[50] = {0}; // -? [ARG]?
- strncat(opt_long, "--", sizeof(opt_long) - strlen(opt_long) - 1);
- strncat(opt_long, long_options[x].name, sizeof(opt_long) - strlen(opt_long) - 1);
+ safe_strncat(opt_long, "--", sizeof(opt_long));
+ safe_strncat(opt_long, long_options[x].name, sizeof(opt_long));
if (long_options[x].has_arg) {
- strncat(opt_long, " ARG", sizeof(opt_long) - strlen(opt_long) - 1);
+ safe_strncat(opt_long, " ARG", sizeof(opt_long));
}
if (long_options[x].val <= 'z') {
- strncat(opt_short, "-", sizeof(opt_short) - strlen(opt_short) - 1);
+ safe_strncat(opt_short, "-", sizeof(opt_short));
opt_short[1] = (char) long_options[x].val;
if (long_options[x].has_arg) {
- strncat(opt_short, " ARG", sizeof(opt_short) - strlen(opt_short) - 1);
+ safe_strncat(opt_short, " ARG", sizeof(opt_short));
}
} else {
- strncat(opt_short, " ", sizeof(opt_short) - strlen(opt_short) - 1);
+ safe_strncat(opt_short, " ", sizeof(opt_short));
}
snprintf(tmp, sizeof(tmp) - strlen(tmp), " %%-%ds\t%%s\t\t%%s", width + 4);
diff --git a/src/cli/stasis/stasis_main.c b/src/cli/stasis/stasis_main.c
index fb4ed80..e660f6b 100644
--- a/src/cli/stasis/stasis_main.c
+++ b/src/cli/stasis/stasis_main.c
@@ -17,11 +17,10 @@ static void setup_sysconfdir() {
// environment variable
char stasis_sysconfdir_tmp[PATH_MAX];
if (getenv("STASIS_SYSCONFDIR")) {
- strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp) - 1);
+ safe_strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp));
} else {
- strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp) - 1);
+ safe_strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp));
}
- stasis_sysconfdir_tmp[sizeof(stasis_sysconfdir_tmp) - 1] = '\0';
globals.sysconfdir = realpath(stasis_sysconfdir_tmp, NULL);
if (!globals.sysconfdir) {
@@ -567,8 +566,7 @@ int main(int argc, char *argv[]) {
globals.continue_on_error = true;
break;
case 'p':
- strncpy(python_override_version, optarg, sizeof(python_override_version) - 1);
- python_override_version[sizeof(python_override_version) - 1] = '\0';
+ safe_strncpy(python_override_version, optarg, sizeof(python_override_version));
break;
case 'l':
globals.cpu_limit = strtol(optarg, NULL, 10);
@@ -699,22 +697,10 @@ int main(int argc, char *argv[]) {
check_requirements(&ctx);
configure_jfrog_cli(&ctx);
- /*
- delivery_free(&ctx);
- tpl_free();
- globals_free();
- return 0;
- */
-
runtime_apply(ctx.runtime.environ);
- strncpy(env_name, ctx.info.release_name, sizeof(env_name) - 1);
- env_name[sizeof(env_name) - 1] = '\0';
-
- strncpy(env_name_testing, env_name, sizeof(env_name_testing) - 1);
- env_name_testing[sizeof(env_name_testing) - 1] = '\0';
-
- strncat(env_name_testing, "-test", sizeof(env_name_testing) - strlen(env_name_testing) - 1);
- env_name_testing[sizeof(env_name_testing) - 1] = '\0';
+ safe_strncpy(env_name, ctx.info.release_name, sizeof(env_name));
+ safe_strncpy(env_name_testing, env_name, sizeof(env_name_testing));
+ safe_strncat(env_name_testing, "-test", sizeof(env_name_testing));
char *envs[] = {
"release", env_name,
diff --git a/src/cli/stasis_indexer/helpers.c b/src/cli/stasis_indexer/helpers.c
index 92e2dd4..3ef96e4 100644
--- a/src/cli/stasis_indexer/helpers.c
+++ b/src/cli/stasis_indexer/helpers.c
@@ -98,48 +98,46 @@ int pandoc_exec(const char *in_file, const char *out_file, const char *css_file,
if (!get_pandoc_version(&pandoc_version)) {
// < 2.19
if (pandoc_version < 0x02130000) {
- strncat(pandoc_versioned_args, "--self-contained ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1);
+ safe_strncat(pandoc_versioned_args, "--self-contained ", sizeof(pandoc_versioned_args));
} else {
// >= 2.19
- strncat(pandoc_versioned_args, "--embed-resources ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1);
+ safe_strncat(pandoc_versioned_args, "--embed-resources ", sizeof(pandoc_versioned_args));
}
// >= 1.15.0.4
if (pandoc_version >= 0x010f0004) {
- strncat(pandoc_versioned_args, "--standalone ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1);
+ safe_strncat(pandoc_versioned_args, "--standalone ", sizeof(pandoc_versioned_args));
}
// >= 1.10.0.1
if (pandoc_version >= 0x010a0001) {
- strncat(pandoc_versioned_args, "-f gfm+autolink_bare_uris ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1);
+ safe_strncat(pandoc_versioned_args, "-f gfm+autolink_bare_uris ", sizeof(pandoc_versioned_args));
}
// > 3.1.9
if (pandoc_version > 0x03010900) {
- strncat(pandoc_versioned_args, "-f gfm+alerts ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1);
+ safe_strncat(pandoc_versioned_args, "-f gfm+alerts ", sizeof(pandoc_versioned_args));
}
}
// Converts a markdown file to html
char cmd[STASIS_BUFSIZ] = {0};
- strncpy(cmd, "pandoc ", sizeof(cmd) - 1);
- cmd[sizeof(cmd) - 1] = '\0';
+ safe_strncpy(cmd, "pandoc ", sizeof(cmd));
- strncat(cmd, pandoc_versioned_args, sizeof(cmd) - strlen(cmd) - 1);
- cmd[sizeof(cmd) - 1] = '\0';
+ safe_strncat(cmd, pandoc_versioned_args, sizeof(cmd));
if (css_file && strlen(css_file)) {
- strncat(cmd, "--css ", sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, css_file, sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, "--css ", sizeof(cmd));
+ safe_strncat(cmd, css_file, sizeof(cmd));
}
- strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, "--metadata title=\"", sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, title, sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, "\" ", sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, "-o ", sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, out_file, sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, in_file, sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, " ", sizeof(cmd));
+ safe_strncat(cmd, "--metadata title=\"", sizeof(cmd));
+ safe_strncat(cmd, title, sizeof(cmd));
+ safe_strncat(cmd, "\" ", sizeof(cmd));
+ safe_strncat(cmd, "-o ", sizeof(cmd));
+ safe_strncat(cmd, out_file, sizeof(cmd));
+ safe_strncat(cmd, " ", sizeof(cmd));
+ safe_strncat(cmd, in_file, sizeof(cmd));
if (globals.verbose) {
puts(cmd);
@@ -406,11 +404,10 @@ int write_manifest(const char *path, char **exclude_path, FILE *fp) {
continue;
}
char filepath[PATH_MAX] = {0};
- strncpy(filepath, path, PATH_MAX - 1);
- filepath[PATH_MAX - 1] = '\0';
+ safe_strncpy(filepath, path, PATH_MAX);
- strncat(filepath, "/", sizeof(filepath) - strlen(filepath) - 1);
- strncat(filepath, rec->d_name, sizeof(filepath) - strlen(filepath) - 1);
+ safe_strncat(filepath, "/", sizeof(filepath));
+ safe_strncat(filepath, rec->d_name, sizeof(filepath));
if (rec->d_type == DT_DIR) {
write_manifest(filepath, exclude_path, fp);
diff --git a/src/cli/stasis_indexer/junitxml_report.c b/src/cli/stasis_indexer/junitxml_report.c
index a7dcd06..300b7e5 100644
--- a/src/cli/stasis_indexer/junitxml_report.c
+++ b/src/cli/stasis_indexer/junitxml_report.c
@@ -55,8 +55,7 @@ static int write_report_output(struct Delivery *ctx, FILE *destfp, const char *x
}
char short_name[PATH_MAX] = {0};
- strncpy(short_name, bname, sizeof(short_name) - 1);
- short_name[sizeof(short_name) - 1] = '\0';
+ safe_strncpy(short_name, bname, sizeof(short_name));
replace_text(short_name, short_name_pattern, "", 0);
replace_text(short_name, "results-", "", 0);
diff --git a/src/cli/stasis_indexer/stasis_indexer_main.c b/src/cli/stasis_indexer/stasis_indexer_main.c
index e87122e..45bbb6c 100644
--- a/src/cli/stasis_indexer/stasis_indexer_main.c
+++ b/src/cli/stasis_indexer/stasis_indexer_main.c
@@ -13,14 +13,11 @@ int indexer_combine_rootdirs(const char *dest, char **rootdirs, const size_t roo
char destdir_with_output[PATH_MAX] = {0};
char *destdir = destdir_bare;
- strncpy(destdir_bare, dest, sizeof(destdir_bare) - 1);
- destdir[sizeof(destdir_bare) - 1] = '\0';
+ safe_strncpy(destdir_bare, dest, sizeof(destdir_bare));
- strncpy(destdir_with_output, dest, sizeof(destdir_with_output) - 1);
- destdir_with_output[sizeof(destdir_with_output) - 1] = '\0';
+ safe_strncpy(destdir_with_output, dest, sizeof(destdir_with_output));
- strncat(destdir_with_output, "/output", sizeof(destdir_with_output) - strlen(destdir_with_output) - 1);
- destdir_with_output[sizeof(destdir_with_output) - 1] = '\0';
+ safe_strncat(destdir_with_output, "/output", sizeof(destdir_with_output));
if (!access(destdir_with_output, F_OK)) {
destdir = destdir_with_output;
@@ -31,14 +28,11 @@ int indexer_combine_rootdirs(const char *dest, char **rootdirs, const size_t roo
char srcdir_bare[PATH_MAX] = {0};
char srcdir_with_output[PATH_MAX] = {0};
char *srcdir = srcdir_bare;
- strncpy(srcdir_bare, rootdirs[i], sizeof(srcdir_bare) - 1);
- srcdir_bare[sizeof(srcdir_bare) - 1] = '\0';
+ safe_strncpy(srcdir_bare, rootdirs[i], sizeof(srcdir_bare));
- strncpy(srcdir_with_output, rootdirs[i], sizeof(srcdir_with_output) - 1);
- srcdir_with_output[sizeof(srcdir_with_output) - 1] = '\0';
+ safe_strncpy(srcdir_with_output, rootdirs[i], sizeof(srcdir_with_output));
- strncat(srcdir_with_output, "/output", sizeof(srcdir_with_output) - strlen(srcdir_with_output) - 1);
- srcdir_with_output[sizeof(srcdir_with_output) - 1] = '\0';
+ safe_strncat(srcdir_with_output, "/output", sizeof(srcdir_with_output));
if (access(srcdir_bare, F_OK)) {
SYSWARN("%s does not exist", srcdir_bare);
@@ -266,11 +260,10 @@ int main(const int argc, char *argv[]) {
char stasis_sysconfdir_tmp[PATH_MAX];
if (getenv("STASIS_SYSCONFDIR")) {
- strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp) - 1);
+ safe_strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp));
} else {
- strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp) - 1);
+ safe_strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp));
}
- stasis_sysconfdir_tmp[sizeof(stasis_sysconfdir_tmp) - 1] = '\0';
globals.sysconfdir = realpath(stasis_sysconfdir_tmp, NULL);
if (!globals.sysconfdir) {
@@ -281,9 +274,9 @@ int main(const int argc, char *argv[]) {
char workdir_template[PATH_MAX] = {0};
const char *system_tmp = getenv("TMPDIR");
if (system_tmp) {
- strncat(workdir_template, system_tmp, sizeof(workdir_template) - strlen(workdir_template) - 1);
+ safe_strncat(workdir_template, system_tmp, sizeof(workdir_template));
} else {
- strncat(workdir_template, "/tmp/stasis", sizeof(workdir_template) - strlen(workdir_template) - 1);
+ safe_strncat(workdir_template, "/tmp/stasis", sizeof(workdir_template));
}
if (mkdirs(workdir_template, 0700)) {
@@ -291,7 +284,7 @@ int main(const int argc, char *argv[]) {
exit(1);
}
- strncat(workdir_template, "/stasis-combine.XXXXXX", sizeof(workdir_template) - strlen(workdir_template) - 1);
+ safe_strncat(workdir_template, "/stasis-combine.XXXXXX", sizeof(workdir_template));
char *workdir = mkdtemp(workdir_template);
if (!workdir) {
SYSERROR("Unable to create temporary directory: %s", workdir_template);
diff --git a/src/cli/stasis_indexer/website.c b/src/cli/stasis_indexer/website.c
index 07ad6ad..edab735 100644
--- a/src/cli/stasis_indexer/website.c
+++ b/src/cli/stasis_indexer/website.c
@@ -35,9 +35,7 @@ int indexer_make_website(struct Delivery **ctx) {
}
// Replace *.md extension with *.html.
- strncpy(fullpath_dest, fullpath_src, sizeof(fullpath_dest) - 1);
- fullpath_dest[sizeof(fullpath_dest) - 1] = '\0';
-
+ safe_strncpy(fullpath_dest, fullpath_src, sizeof(fullpath_dest));
gen_file_extension_str(fullpath_dest, sizeof(fullpath_dest), ".html");
// Convert markdown to html
@@ -54,8 +52,7 @@ int indexer_make_website(struct Delivery **ctx) {
if (!strcmp(filename, "README.md")) {
char link_from[PATH_MAX] = {0};
char link_dest[PATH_MAX] = {0};
- strncpy(link_from, "README.html", sizeof(link_from) - 1);
- link_dest[sizeof(link_dest) - 1] = '\0';
+ safe_strncpy(link_from, "README.html", sizeof(link_from));
snprintf(link_dest, sizeof(link_dest), "%s/%s", root, "index.html");
if (symlink(link_from, link_dest)) {
SYSWARN("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 d4b48fb..db6fbbe 100644
--- a/src/lib/core/artifactory.c
+++ b/src/lib/core/artifactory.c
@@ -25,18 +25,15 @@ int artifactory_download_cli(char *dest,
// convert platform string to lower-case
SYSDEBUG("Set os_ident");
- strncpy(os_ident, os, sizeof(os_ident) - 1);
- os_ident[sizeof(os_ident) - 1] = '\0';
+ safe_strncpy(os_ident, os, sizeof(os_ident));
tolower_s(os_ident);
SYSDEBUG("os_ident=%s", os_ident);
// translate OS identifier
if (!strcmp(os_ident, "darwin") || startswith(os_ident, "macos")) {
- strncpy(os_ident, "mac", sizeof(os_ident) - 1);
- os_ident[sizeof(os_ident) - 1] = '\0';
+ safe_strncpy(os_ident, "mac", sizeof(os_ident));
} else if (!strcmp(os_ident, "linux")) {
- strncpy(os_ident, "linux", sizeof(os_ident) - 1);
- os_ident[sizeof(os_ident) - 1] = '\0';
+ safe_strncpy(os_ident, "linux", sizeof(os_ident));
} else {
SYSERROR("unknown operating system: %s", os_ident);
return -1;
@@ -44,25 +41,23 @@ int artifactory_download_cli(char *dest,
// translate ARCH identifier
SYSDEBUG("Set arch_ident");
- strncpy(arch_ident, arch, sizeof(arch_ident) - 1);
- arch_ident[sizeof(arch_ident) - 1] = '\0';
+ safe_strncpy(arch_ident, arch, sizeof(arch_ident));
SYSDEBUG("arch_ident=%s", arch_ident);
if (startswith(arch_ident, "i") && endswith(arch_ident, "86")) {
- strncpy(arch_ident, "386", sizeof(arch_ident) - 1);
+ safe_strncpy(arch_ident, "386", sizeof(arch_ident));
} else if (!strcmp(arch_ident, "amd64") || !strcmp(arch_ident, "x86_64") || !strcmp(arch_ident, "x64")) {
if (!strcmp(os_ident, "mac")) {
- strncpy(arch_ident, "386", sizeof(arch_ident) - 1);
+ safe_strncpy(arch_ident, "386", sizeof(arch_ident));
} else {
- strncpy(arch_ident, "amd64", sizeof(arch_ident) - 1);
+ safe_strncpy(arch_ident, "amd64", sizeof(arch_ident));
}
} else if (!strcmp(arch_ident, "arm64") || !strcmp(arch_ident, "aarch64")) {
- strncpy(arch_ident, "arm64", sizeof(arch_ident) - 1);
+ safe_strncpy(arch_ident, "arm64", sizeof(arch_ident));
} else {
SYSERROR("unknown architecture: %s", arch_ident);
return -1;
}
- arch_ident[sizeof(arch_ident) - 1] = '\0';
SYSDEBUG("Construct URL");
@@ -75,8 +70,7 @@ int artifactory_download_cli(char *dest,
os_ident, // ...
arch_ident, // jfrog-cli-linux-x86_64
remote_filename); // jf
- strncpy(path, dest, sizeof(path) - 1);
- path[sizeof(path) - 1] = '\0';
+ safe_strncpy(path, dest, sizeof(path));
if (mkdirs(path, 0755)) {
SYSERROR("%s: %s", path, strerror(errno));
@@ -272,11 +266,9 @@ int jfrog_cli(struct JFRT_Auth *auth, const char *subsystem, const char *task, c
}
if (!globals.verbose) {
- strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout) - 1);
- proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0';
+ safe_strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout));
- strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr) - 1);
- proc.f_stderr[sizeof(proc.f_stderr) - 1] = '\0';
+ safe_strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr));
}
return shell(&proc, cmd);
}
@@ -444,7 +436,7 @@ int jfrog_cli_rt_upload(struct JFRT_Auth *auth, struct JFRT_Upload *ctx, char *s
if (base) {
src = base;
} else {
- strncat(src, "/", sizeof(src) - strlen(src) - 1);
+ safe_strncat(src, "/", sizeof(src));
}
pushd(new_src);
}
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index 6083023..c9eb750 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -3,6 +3,7 @@
//
#include "conda.h"
+#include "version_compare.h"
int micromamba(const struct MicromambaInfo *info, char *command, ...) {
struct utsname sys;
@@ -10,13 +11,11 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
tolower_s(sys.sysname);
if (!strcmp(sys.sysname, "darwin")) {
- strncpy(sys.sysname, "osx", sizeof(sys.sysname) - 1);
- sys.sysname[sizeof(sys.sysname) - 1] = '\0';
+ safe_strncpy(sys.sysname, "osx", sizeof(sys.sysname));
}
if (!strcmp(sys.machine, "x86_64")) {
- strncpy(sys.machine, "64", sizeof(sys.machine) - 1);
- sys.machine[sizeof(sys.machine) - 1] = '\0';
+ safe_strncpy(sys.machine, "64", sizeof(sys.machine));
}
if (!info->download_dir || isempty(info->download_dir)) {
@@ -99,6 +98,7 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
}
setenv("CONDARC", rcpath, 1);
+ setenv("MAMBARC", rcpath, 1);
setenv("MAMBA_ROOT_PREFIX", info->conda_prefix, 1);
int status = system(cmd);
unsetenv("MAMBA_ROOT_PREFIX");
@@ -160,8 +160,7 @@ int pkg_index_provides(int mode, const char *index, const char *spec, const char
}
// Normalize the local spec string
- strncpy(spec_local, spec, sizeof(spec_local) - 1);
- spec_local[sizeof(spec_local) - 1] = '\0';
+ safe_strncpy(spec_local, spec, sizeof(spec_local));
tolower_s(spec_local);
lstrip(spec_local);
strip(spec_local);
@@ -189,15 +188,13 @@ int pkg_index_provides(int mode, const char *index, const char *spec, const char
if (mode == PKG_USE_PIP) {
// Do an installation in dry-run mode to see if the package exists in the given index.
// The --force argument ignores local installation and cache, and actually polls the remote index(es)
- strncpy(cmd, "python -m pip install --force --dry-run --no-cache --no-deps ", sizeof(cmd) - 1);
- cmd[sizeof(cmd) - 1] = '\0';
+ safe_strncpy(cmd, "python -m pip install --force --dry-run --no-cache --no-deps ", sizeof(cmd));
if (index) {
snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), "--index-url='%s' ", index);
}
snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), "'%s' ", spec_local);
} else if (mode == PKG_USE_CONDA) {
- strncpy(cmd, "mamba search ", sizeof(cmd) - 1);
- cmd[sizeof(cmd) - 1] = '\0';
+ safe_strncpy(cmd, "mamba search ", sizeof(cmd));
if (index) {
snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), "--channel '%s' ", index);
@@ -271,14 +268,13 @@ int conda_exec(const char *args) {
};
char conda_as[10] = {0};
- strncpy(conda_as, "conda", sizeof(conda_as) - 1);
+ safe_strncpy(conda_as, "conda", sizeof(conda_as));
for (size_t i = 0; mamba_commands[i] != NULL; i++) {
if (startswith(args, mamba_commands[i])) {
- strncpy(conda_as, "mamba", sizeof(conda_as) - 1);
+ safe_strncpy(conda_as, "mamba", sizeof(conda_as));
break;
}
}
- conda_as[sizeof(conda_as) - 1] = '\0';
const char *command_fmt = "%s %s";
@@ -385,8 +381,7 @@ int conda_activate(const char *root, const char *env_name) {
close(fd);
// Configure our process for output to a log file
- strncpy(proc.f_stdout, logfile, sizeof(proc.f_stdout) - 1);
- proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0';
+ safe_strncpy(proc.f_stdout, logfile, sizeof(proc.f_stdout));
// Verify conda's init scripts are available
if (access(path_conda, F_OK) < 0) {
@@ -450,6 +445,7 @@ int conda_activate(const char *root, const char *env_name) {
if (env0_to_runtime(logfile) < 0) {
return -1;
}
+
remove(logfile);
return 0;
}
@@ -459,22 +455,21 @@ int conda_check_required() {
struct StrList *result = NULL;
char cmd[PATH_MAX] = {0};
const char *conda_minimum_viable_tools[] = {
- "boa",
"conda-build",
NULL
};
// Construct a "conda list" command that searches for all required packages
// using conda's (python's) regex matching
- strncat(cmd, "conda list '", sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, "conda list '", sizeof(cmd));
for (size_t i = 0; conda_minimum_viable_tools[i] != NULL; i++) {
- strncat(cmd, "^", sizeof(cmd) - strlen(cmd) - 1);
- strncat(cmd, conda_minimum_viable_tools[i], sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, "^", sizeof(cmd));
+ safe_strncat(cmd, conda_minimum_viable_tools[i], sizeof(cmd));
if (conda_minimum_viable_tools[i + 1] != NULL) {
- strncat(cmd, "|", sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, "|", sizeof(cmd));
}
}
- strncat(cmd, "' | cut -d ' ' -f 1", sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, "' | cut -d ' ' -f 1", sizeof(cmd));
// Verify all required packages are installed
char *cmd_out = shell_output(cmd, &status);
@@ -530,8 +525,7 @@ int conda_setup_headless() {
const char *cmd_fmt = "'%s'";
if (globals.conda_packages && strlist_count(globals.conda_packages)) {
memset(cmd, 0, sizeof(cmd));
- strncpy(cmd, "install ", sizeof(cmd) - 1);
- cmd[sizeof(cmd) - 1] = '\0';
+ safe_strncpy(cmd, "install ", sizeof(cmd));
total = strlist_count(globals.conda_packages);
for (size_t i = 0; i < total; i++) {
@@ -542,7 +536,7 @@ int conda_setup_headless() {
snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), cmd_fmt, item);
if (i < total - 1) {
- strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, " ", sizeof(cmd));
}
}
@@ -554,8 +548,7 @@ int conda_setup_headless() {
if (globals.pip_packages && strlist_count(globals.pip_packages)) {
memset(cmd, 0, sizeof(cmd));
- strncpy(cmd, "install ", sizeof(cmd) - 1);
- cmd[sizeof(cmd) - 1] = '\0';
+ safe_strncpy(cmd, "install ", sizeof(cmd));
total = strlist_count(globals.pip_packages);
for (size_t i = 0; i < total; i++) {
@@ -565,7 +558,7 @@ int conda_setup_headless() {
}
snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), cmd_fmt, item);
if (i < total - 1) {
- strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1);
+ safe_strncat(cmd, " ", sizeof(cmd));
}
}
@@ -613,7 +606,7 @@ int conda_env_create_from_uri(char *name, char *uri, char *python_version) {
unlink(tempfile);
// We'll create a new file with the same random bits, ending with .yml
- strncat(tempfile, ".yml", sizeof(tempfile) - strlen(tempfile) - 1);
+ safe_strncat(tempfile, ".yml", sizeof(tempfile));
char *errmsg = NULL;
const long http_code = download(uri_fs ? uri_fs : uri, tempfile, &errmsg);
if (HTTP_ERROR(http_code)) {
diff --git a/src/lib/core/copy.c b/src/lib/core/copy.c
index 7666e67..f11f919 100644
--- a/src/lib/core/copy.c
+++ b/src/lib/core/copy.c
@@ -14,8 +14,7 @@ int copy2(const char *src, const char *dest, unsigned int op) {
}
char dname[1024] = {0};
- strncpy(dname, dest, sizeof(dname) - 1);
- dname[sizeof(dname) - 1] = '\0';
+ safe_strncpy(dname, dest, sizeof(dname));
char *dname_endptr = strrchr(dname, '/');
if (dname_endptr != NULL) {
diff --git a/src/lib/core/docker.c b/src/lib/core/docker.c
index 484f476..84fdfd5 100644
--- a/src/lib/core/docker.c
+++ b/src/lib/core/docker.c
@@ -18,12 +18,10 @@ int docker_exec(const char *args, const unsigned flags) {
}
if (final_flags & STASIS_DOCKER_QUIET_STDOUT) {
- strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout) - 1);
- proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0';
+ safe_strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout));
}
if (final_flags & STASIS_DOCKER_QUIET_STDERR) {
- strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr) - 1);
- proc.f_stderr[sizeof(proc.f_stderr) - 1] = '\0';
+ safe_strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr));
}
if (!final_flags) {
@@ -71,12 +69,11 @@ int docker_build(const char *dirpath, const char *args, int engine) {
memset(cmd, 0, sizeof(cmd));
if (engine & STASIS_DOCKER_BUILD) {
- strncpy(build, "build", sizeof(build) - 1);
+ safe_strncpy(build, "build", sizeof(build));
}
if (engine & STASIS_DOCKER_BUILD_X) {
- strncpy(build, "buildx build", sizeof(build) - 1);
+ safe_strncpy(build, "buildx build", sizeof(build));
}
- build[sizeof(build) - 1] = '\0';
snprintf(cmd, sizeof(cmd), "%s %s %s", build, args, dirpath);
return docker_exec(cmd, 0);
@@ -88,17 +85,16 @@ int docker_save(const char *image, const char *destdir, const char *compression_
if (compression_program && strlen(compression_program)) {
char ext[255] = {0};
if (startswith(compression_program, "zstd")) {
- strncpy(ext, "zst", sizeof(ext) - 1);
+ safe_strncpy(ext, "zst", sizeof(ext));
} else if (startswith(compression_program, "xz")) {
- strncpy(ext, "xz", sizeof(ext) - 1);
+ safe_strncpy(ext, "xz", sizeof(ext));
} else if (startswith(compression_program, "gzip")) {
- strncpy(ext, "gz", sizeof(ext) - 1);
+ safe_strncpy(ext, "gz", sizeof(ext));
} else if (startswith(compression_program, "bzip2")) {
- strncpy(ext, "bz2", sizeof(ext) - 1);
+ safe_strncpy(ext, "bz2", sizeof(ext));
} else {
- strncpy(ext, compression_program, sizeof(ext) - 1);
+ safe_strncpy(ext, compression_program, sizeof(ext));
}
- ext[sizeof(ext) - 1] = '\0';
snprintf(cmd, sizeof(cmd), "save \"%s\" | %s > \"%s/%s.tar.%s\"", image, compression_program, destdir, image, ext);
} else {
snprintf(cmd, sizeof(cmd), "save \"%s\" -o \"%s/%s.tar\"", image, destdir, image);
@@ -126,11 +122,9 @@ static char *docker_ident() {
}
memset(&proc, 0, sizeof(proc));
- strncpy(proc.f_stdout, tempfile, sizeof(proc.f_stdout) - 1);
- proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0';
+ safe_strncpy(proc.f_stdout, tempfile, sizeof(proc.f_stdout));
- strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr) - 1);
- proc.f_stderr[sizeof(proc.f_stderr) - 1] = '\0';
+ safe_strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr));
shell(&proc, "docker --version");
diff --git a/src/lib/core/environment.c b/src/lib/core/environment.c
index 4258004..4623db8 100644
--- a/src/lib/core/environment.c
+++ b/src/lib/core/environment.c
@@ -80,17 +80,16 @@ void runtime_export(RuntimeEnv *env, char **keys) {
for (size_t i = 0; borne[i] != NULL; i++) {
if (strcmp(sh, borne[i]) == 0) {
- strncpy(export_command, "export", sizeof(export_command) - 1);
+ safe_strncpy(export_command, "export", sizeof(export_command));
break;
}
}
for (size_t i = 0; unborne[i] != NULL; i++) {
if (strcmp(sh, unborne[i]) == 0) {
- strncpy(export_command, "setenv", sizeof(export_command) - 1);
+ safe_strncpy(export_command, "setenv", sizeof(export_command));
break;
}
}
- export_command[sizeof(export_command) - 1] = '\0';
for (size_t i = 0; i < strlist_count(env); i++) {
char output[STASIS_BUFSIZ] = {0};
@@ -309,7 +308,7 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) {
// Handle literal statement "$$var"
// Value becomes "$var" (unexpanded)
if (strncmp(&input[i], delim_literal, strlen(delim_literal)) == 0) {
- strncat(expanded, &delim, 2);
+ safe_strncat(expanded, &delim, 2);
i += strlen(delim_literal);
// Ignore opening brace
if (input[i] == '{') {
@@ -356,7 +355,7 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) {
continue;
}
// Append expanded environment variable to output
- strncat(expanded, tmp, STASIS_BUFSIZ - 1);
+ safe_strncat(expanded, tmp, STASIS_BUFSIZ);
guard_free(tmp);
}
diff --git a/src/lib/core/github.c b/src/lib/core/github.c
index 992ab32..6a8d9e9 100644
--- a/src/lib/core/github.c
+++ b/src/lib/core/github.c
@@ -113,7 +113,7 @@ int get_github_release_notes(const char *api_token, const char *repo, const char
// Extract release notes
*output = calloc(strlen(data_offset) + 1, sizeof(**output));
// Copy output (including terminator)
- strncpy(*output, data_offset, strlen(data_offset) + 1);
+ safe_strncpy(*output, data_offset, strlen(data_offset) + 1);
} else if ((data_offset = strstr(line, field_message))) {
// Skip past the message field
data_offset += strlen(field_message);
diff --git a/src/lib/core/include/str.h b/src/lib/core/include/str.h
index 3e7c3a4..2f86242 100644
--- a/src/lib/core/include/str.h
+++ b/src/lib/core/include/str.h
@@ -324,4 +324,7 @@ char *to_short_version(const char *s);
void unindent(char *s);
+int safe_strncpy(char *dst, const char *src, size_t dsize);
+int safe_strncat(char *dst, const char *src, size_t dsize);
+
#endif //STASIS_STR_H
diff --git a/src/lib/core/ini.c b/src/lib/core/ini.c
index 3c0377f..e727511 100644
--- a/src/lib/core/ini.c
+++ b/src/lib/core/ini.c
@@ -183,8 +183,7 @@ int ini_getval(struct INIFILE *ini, char *section_name, char *key, int type, int
case INIVAL_TYPE_STR_ARRAY:
// TODO: data_copy should be at least equal to the length of the data. The use of STASIS_BUFSIZ below is
// the root cause of crashes when stasis reads long arrays.
- strncpy(tbufp, data_copy, sizeof(tbuf) - 1);
- tbuf[sizeof(tbuf) - 1] = '\0';
+ safe_strncpy(tbufp, data_copy, sizeof(tbuf));
guard_free(data_copy);
data_copy = calloc(STASIS_BUFSIZ, sizeof(*data_copy));
@@ -194,11 +193,10 @@ int ini_getval(struct INIFILE *ini, char *section_name, char *key, int type, int
while ((token = strsep(&tbufp, "\n")) != NULL) {
//lstrip(token);
if (!isempty(token)) {
- strncat(data_copy, token, STASIS_BUFSIZ - strlen(data_copy) - 1);
- strncat(data_copy, "\n", STASIS_BUFSIZ - strlen(data_copy) - 1);
+ safe_strncat(data_copy, token, STASIS_BUFSIZ);
+ safe_strncat(data_copy, "\n", STASIS_BUFSIZ);
}
}
- data_copy[STASIS_BUFSIZ - 1] = '\0';
strip(data_copy);
result->as_char_p = strdup(data_copy);
break;
@@ -359,7 +357,7 @@ int ini_data_append(struct INIFILE **ini, char *section_name, char *key, char *v
}
size_t value_len_old = strlen(data->value);
size_t value_len = strlen(value);
- size_t value_len_new = value_len_old + value_len;
+ size_t value_len_new = value_len_old + value_len + 1;
char *value_tmp = NULL;
value_tmp = realloc(data->value, value_len_new + 2);
if (!value_tmp) {
@@ -368,7 +366,7 @@ int ini_data_append(struct INIFILE **ini, char *section_name, char *key, char *v
}
data->value = value_tmp;
- strncat(data->value, value, value_len_new - strlen(data->value));
+ safe_strncat(data->value, value, value_len_new);
}
return 0;
}
@@ -559,8 +557,7 @@ struct INIFILE *ini_open(const char *filename) {
ini = NULL;
return NULL;
}
- strncpy(current_section, "default", sizeof(current_section) - 1);
- current_section[sizeof(current_section) - 1] = '\0';
+ safe_strncpy(current_section, "default", sizeof(current_section));
// Open the configuration file for reading
FILE *fp = fopen(filename, "r");
@@ -640,8 +637,7 @@ struct INIFILE *ini_open(const char *filename) {
// Record the name of the section. This is used until another section is found.
memset(current_section, 0, sizeof(current_section));
- strncpy(current_section, section_name, sizeof(current_section) - 1);
- current_section[sizeof(current_section) - 1] = '\0';
+ safe_strncpy(current_section, section_name, sizeof(current_section));
guard_free(section_name);
memset(line, 0, sizeof(line));
@@ -664,22 +660,19 @@ struct INIFILE *ini_open(const char *filename) {
const size_t key_len = operator - line;
memset(key, 0, key_size);
- strncpy(key, line, key_len);
- key[key_size - 1] = '\0';
+ safe_strncpy(key, line, key_len + 1);
lstrip(key);
strip(key);
memset(key_last, 0, key_last_size);
- strncpy(key_last, key, key_last_size - 1);
- key_last[key_last_size - 1] = '\0';
+ safe_strncpy(key_last, key, key_last_size + 1);
reading_value = 1;
if (strlen(operator) > 1) {
- strncpy(value, &operator[1], sizeof(value) - 1);
+ safe_strncpy(value, &operator[1], sizeof(value));
} else {
- strncpy(value, "", sizeof(value) - 1);
+ safe_strncpy(value, "", sizeof(value));
}
- value[sizeof(value) - 1] = '\0';
if (isempty(value)) {
//printf("%s is probably long raw data\n", key);
@@ -693,10 +686,8 @@ struct INIFILE *ini_open(const char *filename) {
}
strip(value);
} else {
- strncpy(key, key_last, key_size - 1);
- key[key_size - 1] = '\0';
- strncpy(value, line, sizeof(value) - 1);
- value[sizeof(value) - 1] = '\0';
+ safe_strncpy(key, key_last, key_size + 1);
+ safe_strncpy(value, line, sizeof(value));
}
memset(line, 0, sizeof(line));
diff --git a/src/lib/core/multiprocessing.c b/src/lib/core/multiprocessing.c
index b17bdc1..6c64888 100644
--- a/src/lib/core/multiprocessing.c
+++ b/src/lib/core/multiprocessing.c
@@ -198,7 +198,7 @@ struct MultiProcessingTask *mp_pool_task(struct MultiProcessingPool *pool, const
if (globals.enable_task_logging) {
snprintf(slot->log_file, sizeof(slot->log_file), "%s", pool->log_root);
// FORTIFY_SOURCE won't leave snprintf alone. The chance for truncation is slim anyway.
- strncat(slot->log_file, "/", sizeof(slot->log_file) - strlen(slot->log_file));
+ safe_strncat(slot->log_file, "/", sizeof(slot->log_file));
} else {
snprintf(slot->log_file, sizeof(slot->log_file), "/dev/stdout");
}
diff --git a/src/lib/core/recipe.c b/src/lib/core/recipe.c
index 0ee1ef8..8cc8e21 100644
--- a/src/lib/core/recipe.c
+++ b/src/lib/core/recipe.c
@@ -16,8 +16,7 @@ int recipe_clone(char *recipe_dir, char *url, char *gitref, char **result) {
return -1;
}
}
- strncpy(*result, destdir, PATH_MAX - 1);
- (*result)[PATH_MAX - 1] = '\0';
+ safe_strncpy(*result, destdir, PATH_MAX);
if (!access(destdir, F_OK)) {
if (!strcmp(destdir, "/")) {
diff --git a/src/lib/core/relocation.c b/src/lib/core/relocation.c
index 8204101..6afd198 100644
--- a/src/lib/core/relocation.c
+++ b/src/lib/core/relocation.c
@@ -10,7 +10,7 @@
* ~~~{.c}
* size_t str_maxlen = 100;
* char *str = calloc(str_maxlen, sizeof(char));
- * strncpy(str, "This are a test.", str_maxlen - 1);
+ * safe_strncpy(str, "This are a test.", str_maxlen);
* if (replace_text(str, "are", "is")) {
* fprintf(stderr, "string replacement failed\n");
* exit(1);
@@ -84,6 +84,7 @@ int replace_text(char *original, const char *target, const char *replacement, un
// truncate whatever remains of the original buffer
memset(original + buffer_len, 0, original_len - buffer_len);
}
+
// replace original with contents of buffer
strncpy(original, buffer, buffer_len + 1);
original[buffer_len] = '\0';
diff --git a/src/lib/core/str.c b/src/lib/core/str.c
index c31ce5e..a04293f 100644
--- a/src/lib/core/str.c
+++ b/src/lib/core/str.c
@@ -78,9 +78,8 @@ void strchrdel(char *sptr, const char *chars) {
for (size_t i = 0; i < strlen(chars); i++) {
char ch[2] = {0};
- strncpy(ch, &chars[i], 1);
- ch[sizeof(ch) - 1] = '\0';
- replace_text(sptr, ch, "", 0);
+ safe_strncpy(ch, &chars[i], sizeof(ch));
+ replace_text(sptr, (char *) ch, "", 0);
}
}
@@ -137,8 +136,7 @@ char** split(char *_sptr, const char* delim, size_t max)
guard_array_n_free(result, i);
return NULL;
}
- strncpy(result[i], token, STASIS_BUFSIZ - 1);
- result[i][STASIS_BUFSIZ - 1] = '\0';
+ safe_strncpy(result[i], token, STASIS_BUFSIZ);
}
// pos is non-zero when maximum split is reached
@@ -150,8 +148,7 @@ char** split(char *_sptr, const char* delim, size_t max)
guard_array_n_free(result, i);
return NULL;
}
- strncpy(result[i], &orig[pos], STASIS_BUFSIZ - 1);
- result[i][STASIS_BUFSIZ - 1] = '\0';
+ safe_strncpy(result[i], &orig[pos], STASIS_BUFSIZ);
}
guard_free(sptr);
@@ -175,9 +172,9 @@ char *join(char **arr, const char *separator) {
result = (char *)calloc(total_bytes, sizeof(char));
for (int i = 0; i < records; i++) {
- strncat(result, arr[i], total_bytes - (result ? strlen(result) - 1 : 0));
+ safe_strncat(result, arr[i], total_bytes);
if (i < (records - 1)) {
- strncat(result, separator, total_bytes - strlen(result) - 1);
+ safe_strncat(result, separator, total_bytes);
}
}
return result;
@@ -230,11 +227,11 @@ char *join_ex(char *separator, ...) {
result = calloc(size + 1, sizeof(char));
for (size_t i = 0; i < argc; i++) {
// Append argument to string
- strncat(result, argv[i], size - (result ? strlen(result) - 1 : 0)); // no -1 because +1 above
+ safe_strncat(result, argv[i], size + 1); // no -1 because +1 above
// Do not append a trailing separator when we reach the last argument
if (i < (argc - 1)) {
- strncat(result, separator, size - strlen(result)); // no -1 because +1 above
+ safe_strncat(result, separator, size + 1); // no -1 because +1 above
}
guard_free(argv[i]);
}
@@ -586,8 +583,7 @@ char *normalize_space(char *s) {
// Rewrite the input string
const size_t result_len = strlen(result) + 1;
- strncpy(result, tmp_orig, result_len);
- result[result_len] = '\0';
+ safe_strncpy(result, tmp_orig, result_len);
guard_free(tmp_orig);
return result;
@@ -750,3 +746,22 @@ char *remove_extras(char *s) {
return s;
}
+int safe_strncpy(char *dst, const char *src, const size_t dsize) {
+ return snprintf(dst, dsize, "%s", src);
+}
+
+int safe_strncat(char *dst, const char *src, const size_t dsize) {
+ const size_t used = strnlen(dst, dsize);
+ if (used == dsize) {
+ SYSERROR("destination is not NUL terminated: %p", dst);
+ return -1;
+ }
+ const size_t maxlen = dsize - used;
+ const int len = snprintf(dst + strlen(dst), maxlen, "%s", src);
+ if (len < 0) {
+ SYSERROR("encoding error");
+ } else if ((size_t) len >= maxlen) {
+ SYSWARN("destination truncated: %p", dst);
+ }
+ return len;
+} \ No newline at end of file
diff --git a/src/lib/core/strlist.c b/src/lib/core/strlist.c
index 5cd3f4a..60f3a1f 100644
--- a/src/lib/core/strlist.c
+++ b/src/lib/core/strlist.c
@@ -88,8 +88,7 @@ int strlist_append_file(struct StrList *pStrList, char *_path, ReaderFn *readerF
if (is_url) {
int fd;
char tempfile[PATH_MAX] = {0};
- strncpy(tempfile, "/tmp/.remote_file.XXXXXX", sizeof(tempfile) - 1);
- tempfile[sizeof(tempfile) - 1] = '\0';
+ safe_strncpy(tempfile, "/tmp/.remote_file.XXXXXX", sizeof(tempfile));
if ((fd = mkstemp(tempfile)) < 0) {
retval = -1;
@@ -449,8 +448,7 @@ void strlist_set(struct StrList **pStrList, size_t index, char *value) {
const size_t len = strlen(value) + 1;
memset((*pStrList)->data[index], '\0', len);
- strncpy((*pStrList)->data[index], value, len);
- (*pStrList)->data[index][len] = '\0';
+ safe_strncpy((*pStrList)->data[index], value, len);
}
}
diff --git a/src/lib/core/system.c b/src/lib/core/system.c
index d0956f4..4f1ece6 100644
--- a/src/lib/core/system.c
+++ b/src/lib/core/system.c
@@ -182,7 +182,7 @@ char *shell_output(const char *command, int *status) {
}
result = tmp;
}
- strncat(result, line, current_size - strlen(result) - 1);
+ safe_strncat(result, line, current_size);
memset(line, 0, sizeof(line));
}
*status = pclose(pp);
diff --git a/src/lib/core/template.c b/src/lib/core/template.c
index 8396b1e..fa29104 100644
--- a/src/lib/core/template.c
+++ b/src/lib/core/template.c
@@ -235,8 +235,7 @@ char *tpl_render(char *str) {
value = strdup(env_val ? env_val : "");
} else if (do_func) { // {{ func:NAME(a, ...) }}
char func_name_temp[STASIS_NAME_MAX] = {0};
- strncpy(func_name_temp, type_stop + 1, sizeof(func_name_temp) - 1);
- func_name_temp[sizeof(func_name_temp) - 1] = '\0';
+ safe_strncpy(func_name_temp, type_stop + 1, sizeof(func_name_temp));
char *param_begin = strchr(func_name_temp, '(');
if (!param_begin) {
@@ -296,7 +295,7 @@ char *tpl_render(char *str) {
// Append replacement value
grow(z, &output_bytes, &output);
- strncat(output, value, output_bytes - strlen(output) - 1);
+ safe_strncat(output, value, output_bytes);
guard_free(value);
output[z] = 0;
}
diff --git a/src/lib/core/template_func_proto.c b/src/lib/core/template_func_proto.c
index 54a8860..5cdc441 100644
--- a/src/lib/core/template_func_proto.c
+++ b/src/lib/core/template_func_proto.c
@@ -80,8 +80,7 @@ int get_junitxml_file_entrypoint(struct tplfunc_frame *frame, void *data_out) {
return -1;
}
char nametmp[PATH_MAX] = {0};
- strncpy(nametmp, cwd, sizeof(nametmp) - 1);
- nametmp[sizeof(nametmp) - 1] = '\0';
+ safe_strncpy(nametmp, cwd, sizeof(nametmp));
char *name = path_basename(nametmp);
@@ -107,8 +106,7 @@ int get_basetemp_dir_entrypoint(struct tplfunc_frame *frame, void *data_out) {
return -1;
}
char nametmp[PATH_MAX] = {0};
- strncpy(nametmp, cwd, sizeof(nametmp) - 1);
- nametmp[sizeof(nametmp) - 1] = '\0';
+ safe_strncpy(nametmp, cwd, sizeof(nametmp));
char *name = path_basename(nametmp);
*output = calloc(PATH_MAX, sizeof(**output));
diff --git a/src/lib/core/utils.c b/src/lib/core/utils.c
index d869143..b4a520d 100644
--- a/src/lib/core/utils.c
+++ b/src/lib/core/utils.c
@@ -37,8 +37,7 @@ int rmtree(char *_path) {
char path[PATH_MAX] = {0};
struct dirent *d_entity;
- strncpy(path, _path, sizeof(path) - 1);
- path[sizeof(path) - 1] = '\0';
+ safe_strncpy(path, _path, sizeof(path));
DIR *dir = opendir(path);
if (!dir) {
@@ -47,9 +46,9 @@ int rmtree(char *_path) {
while ((d_entity = readdir(dir)) != NULL) {
char abspath[PATH_MAX] = {0};
- strncat(abspath, path, sizeof(abspath) - strlen(abspath) - 1);
- strncat(abspath, DIR_SEP, sizeof(abspath) - strlen(abspath) - 1);
- strncat(abspath, d_entity->d_name, sizeof(abspath) - strlen(abspath) - 1);
+ safe_strncat(abspath, path, sizeof(abspath));
+ safe_strncat(abspath, DIR_SEP, sizeof(abspath));
+ safe_strncat(abspath, d_entity->d_name, sizeof(abspath));
if (!strcmp(d_entity->d_name, ".") || !strcmp(d_entity->d_name, "..") || !strcmp(abspath, path)) {
continue;
@@ -93,7 +92,7 @@ char *expandpath(const char *_path) {
memset(ptmp, '\0', sizeof(tmp));
memset(result, '\0', sizeof(result));
- strncpy(ptmp, _path, PATH_MAX - 1);
+ safe_strncpy(ptmp, _path, PATH_MAX);
// Check whether there's a reason to continue processing the string
if (*ptmp != '~') {
@@ -107,8 +106,7 @@ char *expandpath(const char *_path) {
for (size_t i = 0; i < sizeof(homes) / sizeof(*homes); i++) {
char *tmphome;
if ((tmphome = getenv(homes[i])) != NULL) {
- strncpy(home, tmphome, PATH_MAX - 1);
- home[PATH_MAX - 1] = '\0';
+ safe_strncpy(home, tmphome, PATH_MAX);
break;
}
}
@@ -125,10 +123,10 @@ char *expandpath(const char *_path) {
}
// Construct the new path
- strncat(result, home, sizeof(result) - strlen(home) + 1);
+ safe_strncat(result, home, sizeof(result));
if (sep) {
- strncat(result, DIR_SEP, sizeof(result) - strlen(home) + 1);
- strncat(result, ptmp, sizeof(result) - strlen(home) + 1);
+ safe_strncat(result, DIR_SEP, sizeof(result));
+ safe_strncat(result, ptmp, sizeof(result));
}
return strdup(result);
@@ -280,14 +278,13 @@ char *find_program(const char *name) {
result[0] = '\0';
while ((path_elem = strsep(&path, PATH_SEP))) {
char abspath[PATH_MAX] = {0};
- strncat(abspath, path_elem, sizeof(abspath) - strlen(abspath) - 1);
- strncat(abspath, DIR_SEP, sizeof(abspath) - strlen(abspath) - 1);
- strncat(abspath, name, sizeof(abspath) - strlen(abspath) - 1);
+ safe_strncat(abspath, path_elem, sizeof(abspath));
+ safe_strncat(abspath, DIR_SEP, sizeof(abspath));
+ safe_strncat(abspath, name, sizeof(abspath));
if (access(abspath, F_OK) < 0) {
continue;
}
- strncpy(result, abspath, sizeof(result) - 1);
- result[sizeof(result) - 1] = '\0';
+ safe_strncpy(result, abspath, sizeof(result));
break;
}
path = path_orig;
@@ -455,16 +452,15 @@ void msg(unsigned type, char *fmt, ...) {
// for error output
stream = stderr;
fprintf(stream, "%s", STASIS_COLOR_RED);
- strncpy(status, " ERROR: ", sizeof(status) - 1);
+ safe_strncpy(status, " ERROR: ", sizeof(status));
} else if (type & STASIS_MSG_WARN) {
stream = stderr;
fprintf(stream, "%s", STASIS_COLOR_YELLOW);
- strncpy(status, " WARNING: ", sizeof(status) - 1);
+ safe_strncpy(status, " WARNING: ", sizeof(status));
} else {
fprintf(stream, "%s", STASIS_COLOR_GREEN);
- strncpy(status, " ", sizeof(status) - 1);
+ safe_strncpy(status, " ", sizeof(status));
}
- status[sizeof(status) - 1] = '\0';
if (type & STASIS_MSG_L1) {
snprintf(header, sizeof(header), "==>%s" STASIS_COLOR_RESET STASIS_COLOR_WHITE, status);
@@ -507,8 +503,7 @@ char *xmkstemp(FILE **fp, const char *mode) {
char tmpdir[PATH_MAX] = {0};
char t_name[PATH_MAX * 2] = {0};
- strncpy(tmpdir, globals.tmpdir ? globals.tmpdir : "/tmp/stasis", sizeof(tmpdir) - 1);
- tmpdir[sizeof(tmpdir) - 1] = '\0';
+ safe_strncpy(tmpdir, globals.tmpdir ? globals.tmpdir : "/tmp/stasis", sizeof(tmpdir));
if (mkdirs(tmpdir, 0700) < 0) {
SYSERROR("unable to create sub-directories in %s", tmpdir);
@@ -739,7 +734,7 @@ int fix_tox_conf(const char *filename, char **result, size_t maxlen) {
return -1;
}
value = tmp;
- strncat(value, with_posargs, (strlen(value) + strlen(with_posargs)) - strlen(value) - 1);
+ safe_strncat(value, with_posargs, (strlen(value) + strlen(with_posargs)));
ini_setval(&toxini, INI_SETVAL_REPLACE, section_name, key, value);
}
}
@@ -754,7 +749,7 @@ int fix_tox_conf(const char *filename, char **result, size_t maxlen) {
fclose(fptemp);
// Store path to modified config
- strncpy(*result, tempfile, maxlen - 1);
+ safe_strncpy(*result, tempfile, maxlen);
(*result)[maxlen - 1] = '\0';
guard_free(tempfile);
@@ -807,8 +802,7 @@ int redact_sensitive(const char **to_redact, size_t to_redact_size, char *src, c
if (!tmp) {
return -1;
}
- strncpy(tmp, src, maxlen);
- tmp[maxlen] = '\0';
+ safe_strncpy(tmp, src, maxlen);
for (size_t i = 0; i < to_redact_size; i++) {
if (to_redact[i] && strstr(tmp, to_redact[i])) {
@@ -818,8 +812,7 @@ int redact_sensitive(const char **to_redact, size_t to_redact_size, char *src, c
}
memset(dest, 0, maxlen);
- strncpy(dest, tmp, maxlen);
- dest[maxlen] = '\0';
+ safe_strncpy(dest, tmp, maxlen);
guard_free(tmp);
return 0;
@@ -872,16 +865,15 @@ long get_cpu_count() {
int mkdirs(const char *_path, mode_t mode) {
char *token;
char pathbuf[PATH_MAX] = {0};
- strncpy(pathbuf, _path, sizeof(pathbuf) - 1);
- pathbuf[sizeof(pathbuf) - 1] = '\0';
+ safe_strncpy(pathbuf, _path, sizeof(pathbuf));
char *path = pathbuf;
errno = 0;
char result[PATH_MAX] = {0};
int status = 0;
while ((token = strsep(&path, "/")) != NULL && !status) {
- strncat(result, token, sizeof result - strlen(result) - 1);
- strncat(result, "/", sizeof result - strlen(result) - 1);
+ safe_strncat(result, token, sizeof result);
+ safe_strncat(result, "/", sizeof result);
status = mkdir(result, mode);
if (status && errno == EEXIST) {
status = 0;
@@ -946,7 +938,7 @@ int env_manipulate_pathstr(const char *key, char *path, int mode) {
int gen_file_extension_str(char *filename, const size_t maxlen, const char *extension) {
char *ext_orig = strrchr(filename, '.');
if (!ext_orig) {
- strncat(filename, extension, maxlen - strlen(filename) - 1);
+ safe_strncat(filename, extension, maxlen);
return 0;
}
@@ -974,7 +966,7 @@ void debug_hexdump(char *data, int len) {
snprintf(addr + strlen(addr), sizeof(addr) - strlen(addr), "%p", pos);
}
if (count == 8) {
- strncat(bytes, " ", sizeof(bytes) - strlen(bytes) - 1);
+ safe_strncat(bytes, " ", sizeof(bytes));
}
if (count > 15) {
snprintf(output, sizeof(output), "%s | %s | %s", addr, bytes, ascii);
@@ -996,11 +988,11 @@ void debug_hexdump(char *data, int len) {
if (count <= 8) {
// Add group padding
- strncat(bytes, " ", sizeof(bytes) - strlen(bytes) - 1);
+ safe_strncat(bytes, " ", sizeof(bytes));
}
const int padding = 16 - count;
for (int i = 0; i < padding; i++) {
- strncat(bytes, " ", sizeof(bytes) - strlen(bytes) - 1);
+ safe_strncat(bytes, " ", sizeof(bytes));
}
snprintf(output, sizeof(output), "%s | %s | %s", addr, bytes, ascii);
puts(output);
@@ -1276,8 +1268,7 @@ char *center_text(const char *s, const size_t maxwidth) {
for (; i < middle; i++) {
result[i] = ' ';
}
- strncpy(&result[i], s, maxwidth - middle - 1);
- result[maxwidth] = '\0';
+ safe_strncpy(&result[i], s, maxwidth - middle);
return result;
}
diff --git a/src/lib/core/wheel.c b/src/lib/core/wheel.c
index e94060a..bb8d106 100644
--- a/src/lib/core/wheel.c
+++ b/src/lib/core/wheel.c
@@ -1159,8 +1159,7 @@ int wheel_get_entry_point(struct Wheel *pkg, const char *filename) {
const size_t start = strcspn((char *) item, "[") + 1;
if (start) {
const size_t len = strcspn((char *) item, "]");
- strncpy(section, item + start, len - start);
- section[len - start] = '\0';
+ safe_strncpy(section, item + start, len - start);
continue;
}
}
diff --git a/src/lib/core/wheelinfo.c b/src/lib/core/wheelinfo.c
index 9d8a6af..fe426aa 100644
--- a/src/lib/core/wheelinfo.c
+++ b/src/lib/core/wheelinfo.c
@@ -6,8 +6,7 @@ struct WheelInfo *wheelinfo_get(const char *basepath, const char *name, char *to
char package_path[PATH_MAX];
char package_name[NAME_MAX];
- strncpy(package_name, name, sizeof(package_name) - 1);
- package_name[sizeof(package_name) - 1] = '\0';
+ safe_strncpy(package_name, name, sizeof(package_name));
tolower_s(package_name);
snprintf(package_path, sizeof(package_path), "%s/%s", basepath, package_name);
@@ -22,8 +21,7 @@ struct WheelInfo *wheelinfo_get(const char *basepath, const char *name, char *to
}
char filename[NAME_MAX];
- strncpy(filename, rec->d_name, sizeof(filename) - 1);
- filename[sizeof(filename) - 1] = '\0';
+ safe_strncpy(filename, rec->d_name, sizeof(filename));
char *ext = strstr(filename, ".whl");
if (ext) {
diff --git a/src/lib/delivery/delivery_build.c b/src/lib/delivery/delivery_build.c
index 66f9126..d8674e0 100644
--- a/src/lib/delivery/delivery_build.c
+++ b/src/lib/delivery/delivery_build.c
@@ -34,15 +34,12 @@ int delivery_build_recipes(struct Delivery *ctx) {
const int is_long_tag = num_chars(ctx->tests->test[i]->repository_info_tag, '-') > 1;
if (is_long_tag) {
const size_t len = strcspn(ctx->tests->test[i]->repository_info_tag, "-");
- strncpy(tag, ctx->tests->test[i]->repository_info_tag, len);
- tag[len] = '\0';
+ safe_strncpy(tag, ctx->tests->test[i]->repository_info_tag, len);
} else {
- strncpy(tag, ctx->tests->test[i]->repository_info_tag, sizeof(tag) - 1);
- tag[sizeof(tag) - 1] = '\0';
+ safe_strncpy(tag, ctx->tests->test[i]->repository_info_tag, sizeof(tag));
}
} else {
- strncpy(tag, ctx->tests->test[i]->version, sizeof(tag) - 1);
- tag[sizeof(tag) - 1] = '\0';
+ safe_strncpy(tag, ctx->tests->test[i]->version, sizeof(tag));
}
//sprintf(recipe_version, "{%% set version = GIT_DESCRIBE_TAG ~ \".dev\" ~ GIT_DESCRIBE_NUMBER ~ \"+\" ~ GIT_DESCRIBE_HASH %%}");
@@ -55,8 +52,7 @@ int delivery_build_recipes(struct Delivery *ctx) {
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);
- recipe_git_rev[sizeof(recipe_git_rev) - 1] = '\0';
+ safe_strncpy(recipe_git_rev, "", sizeof(recipe_git_rev));
snprintf(recipe_buildno, sizeof(recipe_buildno), " number: 0");
unsigned flags = REPLACE_TRUNCATE_AFTER_MATCH;
@@ -80,22 +76,20 @@ int delivery_build_recipes(struct Delivery *ctx) {
char arch[STASIS_NAME_MAX] = {0};
char platform[STASIS_NAME_MAX] = {0};
- strncpy(platform, ctx->system.platform[DELIVERY_PLATFORM], sizeof(platform) - 1);
+ safe_strncpy(platform, ctx->system.platform[DELIVERY_PLATFORM], sizeof(platform));
if (strstr(platform, "Darwin")) {
memset(platform, 0, sizeof(platform));
- strncpy(platform, "osx", sizeof(platform) - 1);
+ safe_strncpy(platform, "osx", sizeof(platform));
}
- platform[sizeof(platform) - 1] = '\0';
tolower_s(platform);
if (strstr(ctx->system.arch, "arm64")) {
- strncpy(arch, "arm64", sizeof(arch) - 1);
+ safe_strncpy(arch, "arm64", sizeof(arch));
} else if (strstr(ctx->system.arch, "64")) {
- strncpy(arch, "64", sizeof(arch) - 1);
+ safe_strncpy(arch, "64", sizeof(arch));
} else {
- strncat(arch, "32", sizeof(arch) - strlen(arch) - 1); // blind guess
+ safe_strncat(arch, "32", sizeof(arch)); // blind guess
}
- arch[sizeof(arch) - 1] = '\0';
tolower_s(arch);
snprintf(command, sizeof(command), "mambabuild --python=%s -m ../.ci_support/%s_%s_.yaml .",
@@ -393,8 +387,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) {
for (size_t p = 0; p < strlist_count(ctx->conda.pip_packages_defer); p++) {
char name[100] = {0};
char *fullspec = strlist_item(ctx->conda.pip_packages_defer, p);
- strncpy(name, fullspec, sizeof(name) - 1);
- name[sizeof(name) - 1] = '\0';
+ safe_strncpy(name, fullspec, sizeof(name));
remove_extras(name);
char *spec = find_version_spec(name);
if (spec) {
@@ -444,8 +437,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) {
COE_CHECK_ABORT(true, "Unreproducible delivery");
}
- strncpy(dname, ctx->tests->test[i]->name, sizeof(dname) - 1);
- dname[sizeof(dname) - 1] = '\0';
+ safe_strncpy(dname, ctx->tests->test[i]->name, sizeof(dname));
tolower_s(dname);
snprintf(outdir, sizeof(outdir), "%s/%s", ctx->storage.wheel_artifact_dir, dname);
if (mkdirs(outdir, 0755)) {
diff --git a/src/lib/delivery/delivery_docker.c b/src/lib/delivery/delivery_docker.c
index 79e9729..9b2e1f7 100644
--- a/src/lib/delivery/delivery_docker.c
+++ b/src/lib/delivery/delivery_docker.c
@@ -44,8 +44,7 @@ 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);
- strncpy(tag, tag_orig, sizeof(tag) - 1);
- tag[sizeof(tag) - 1] = '\0';
+ safe_strncpy(tag, tag_orig, sizeof(tag));
docker_sanitize_tag(tag);
snprintf(args + strlen(args), sizeof(args) - strlen(args), " -t \"%s\" ", tag);
}
@@ -103,8 +102,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
- strncpy(tag, strlist_item(ctx->deploy.docker.tags, 0), sizeof(tag) - 1);
- tag[sizeof(tag) - 1] = '\0';
+ safe_strncpy(tag, strlist_item(ctx->deploy.docker.tags, 0), sizeof(tag));
docker_sanitize_tag(tag);
msg(STASIS_MSG_L2, "Executing image test script for %s\n", tag);
diff --git a/src/lib/delivery/delivery_init.c b/src/lib/delivery/delivery_init.c
index 5bc326d..7cfb9af 100644
--- a/src/lib/delivery/delivery_init.c
+++ b/src/lib/delivery/delivery_init.c
@@ -217,36 +217,27 @@ int delivery_init_platform(struct Delivery *ctx) {
}
if (!strcmp(ctx->system.arch, "x86_64")) {
- strncpy(archsuffix, "64", sizeof(archsuffix) - 1);
+ safe_strncpy(archsuffix, "64", sizeof(archsuffix));
} else {
- strncpy(archsuffix, ctx->system.arch, sizeof(archsuffix) - 1);
+ safe_strncpy(archsuffix, ctx->system.arch, sizeof(archsuffix));
}
- archsuffix[sizeof(archsuffix) - 1] = '\0';
SYSDEBUG("Setting platform");
- strncpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname, DELIVERY_PLATFORM_MAXLEN - 1);
- ctx->system.platform[DELIVERY_PLATFORM][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname, DELIVERY_PLATFORM_MAXLEN);
if (!strcmp(ctx->system.platform[DELIVERY_PLATFORM], "Darwin")) {
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);
- ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
- strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "macos", DELIVERY_PLATFORM_MAXLEN - 1);
- ctx->system.platform[DELIVERY_PLATFORM_RELEASE][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "MacOSX", DELIVERY_PLATFORM_MAXLEN);
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "macos", DELIVERY_PLATFORM_MAXLEN);
} else if (!strcmp(ctx->system.platform[DELIVERY_PLATFORM], "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);
- ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
- strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "linux", DELIVERY_PLATFORM_MAXLEN - 1);
- ctx->system.platform[DELIVERY_PLATFORM_RELEASE][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "Linux", DELIVERY_PLATFORM_MAXLEN);
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "linux", DELIVERY_PLATFORM_MAXLEN);
} else {
// Not explicitly supported systems
- strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1);
- ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
- strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1);
- ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
- strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1);
- ctx->system.platform[DELIVERY_PLATFORM_RELEASE][DELIVERY_PLATFORM_MAXLEN - 1] = '\0';
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN);
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN);
+ safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN);
tolower_s(ctx->system.platform[DELIVERY_PLATFORM_RELEASE]);
}
diff --git a/src/lib/delivery/delivery_install.c b/src/lib/delivery/delivery_install.c
index efdb819..bb99014 100644
--- a/src/lib/delivery/delivery_install.c
+++ b/src/lib/delivery/delivery_install.c
@@ -34,11 +34,9 @@ static char *have_spec_in_config(const struct Delivery *ctx, const char *name) {
char *op = find_version_spec(config_spec);
char package[255] = {0};
if (op) {
- strncpy(package, config_spec, op - config_spec);
- package[op - config_spec] = '\0';
+ safe_strncpy(package, config_spec, op - config_spec);
} else {
- strncpy(package, config_spec, sizeof(package) - 1);
- package[sizeof(package) - 1] = '\0';
+ safe_strncpy(package, config_spec, sizeof(package));
}
remove_extras(package);
if (strncmp(package, name, strlen(name)) == 0) {
@@ -85,11 +83,9 @@ int delivery_overlay_packages_from_env(struct Delivery *ctx, const char *env_nam
char spec_name[255] = {0};
char *op = find_version_spec(spec);
if (op) {
- strncpy(spec_name, spec, op - spec);
- spec_name[op - spec] = '\0';
+ safe_strncpy(spec_name, spec, op - spec);
} else {
- strncpy(spec_name, spec, sizeof(spec_name) - 1);
- spec_name[sizeof(spec_name) - 1] = '\0';
+ safe_strncpy(spec_name, spec, sizeof(spec_name));
}
struct Test *test_block = requirement_from_test(ctx, spec_name);
@@ -108,11 +104,9 @@ int delivery_overlay_packages_from_env(struct Delivery *ctx, const char *env_nam
char *op = find_version_spec(frozen_spec);
// we only care about packages with specs here. if something else arrives, ignore it
if (op) {
- strncpy(frozen_name, frozen_spec, op - frozen_spec);
- frozen_name[op - frozen_spec] = '\0';
+ safe_strncpy(frozen_name, frozen_spec, op - frozen_spec);
} else {
- strncpy(frozen_name, frozen_spec, sizeof(frozen_name) - 1);
- frozen_name[sizeof(frozen_name) - 1] = '\0';
+ safe_strncpy(frozen_name, frozen_spec, sizeof(frozen_name));
}
struct Test *test = requirement_from_test(ctx, frozen_name);
if (test && strcmp(test->name, frozen_name) == 0) {
@@ -307,20 +301,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;
- strncpy(package_manager, "conda", sizeof(package_manager) - 1);
- package_manager[sizeof(package_manager) - 1] = '\0';
+ safe_strncpy(package_manager, "conda", sizeof(package_manager));
// conda is already configured for "always_yes"
- strncpy(subcommand, "remove", sizeof(subcommand) - 1);
- subcommand[sizeof(subcommand) - 1] = '\0';
+ safe_strncpy(subcommand, "remove", sizeof(subcommand));
break;
case PKG_USE_PIP:
fn = pip_exec;
list = ctx->conda.pip_packages_purge;
- strncpy(package_manager, "pip", sizeof(package_manager) - 1);
- package_manager[sizeof(package_manager) - 1] = '\0';
+ safe_strncpy(package_manager, "pip", sizeof(package_manager));
// avoid user prompt to remove packages
- strncpy(subcommand, "uninstall -y", sizeof(subcommand) - 1);
- subcommand[sizeof(subcommand) - 1] = '\0';
+ safe_strncpy(subcommand, "uninstall -y", sizeof(subcommand));
break;
default:
SYSERROR("Unknown package manager: %d", use_pkg_manager);
@@ -371,7 +361,7 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha
}
memset(command_base, 0, sizeof(command_base));
- strncat(command_base, "install", sizeof(command_base) - strlen(command_base) - 1);
+ safe_strncat(command_base, "install", sizeof(command_base));
typedef int (*Runner)(const char *);
Runner runner = NULL;
@@ -387,15 +377,17 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha
}
if (INSTALL_PKG_CONDA_DEFERRED & type) {
- strncat(command_base, " --use-local", sizeof(command_base) - strlen(command_base) - 1);
- command_base[sizeof(command_base) - 1] = '\0';
+ //if (ctx->conda.capabilities.missing_use_local) {
+ // safe_strncat(command_base, " -c local", sizeof(command_base));
+ //} else {
+ safe_strncat(command_base, " --use-local", sizeof(command_base));
+ //}
} 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) {
- strncat(command_base, " --upgrade", sizeof(command_base) - strlen(command_base) - 1);
- command_base[sizeof(command_base) - 1] = '\0';
+ safe_strncat(command_base, " --upgrade", sizeof(command_base));
}
snprintf(command_base + strlen(command_base), sizeof(command_base) - strlen(command_base), " --extra-index-url 'file://%s'", ctx->storage.wheel_artifact_dir);
}
@@ -470,11 +462,9 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha
char req[255] = {0};
if (!strcmp(name, info->name)) {
- strncpy(req, info->name, sizeof(req) - 1);
- req[sizeof(req) - 1] = '\0';
+ safe_strncpy(req, info->name, sizeof(req));
} else {
- strncpy(req, name, sizeof(req) - 1);
- req[sizeof(req) - 1] = '\0';
+ safe_strncpy(req, name, sizeof(req));
char *spec = find_version_spec(req);
if (spec) {
*spec = 0;
diff --git a/src/lib/delivery/delivery_test.c b/src/lib/delivery/delivery_test.c
index f59a62e..c1ef1ad 100644
--- a/src/lib/delivery/delivery_test.c
+++ b/src/lib/delivery/delivery_test.c
@@ -199,13 +199,11 @@ void delivery_tests_run(struct Delivery *ctx) {
msg(STASIS_MSG_L3, "Queuing task for %s\n", test->name);
memset(&proc, 0, sizeof(proc));
- strncpy(cmd, test->script, strlen(test->script) + STASIS_BUFSIZ - 1);
- cmd[strlen(test->script) + STASIS_BUFSIZ - 1] = '\0';
+ safe_strncpy(cmd, test->script, strlen(test->script) + STASIS_BUFSIZ);
char *cmd_rendered = tpl_render(cmd);
if (cmd_rendered) {
if (strcmp(cmd_rendered, cmd) != 0) {
- strncpy(cmd, cmd_rendered, strlen(test->script) + STASIS_BUFSIZ - 1);
- cmd[strlen(cmd_rendered) ? strlen(cmd_rendered) - 1 : 0] = 0;
+ safe_strncpy(cmd, cmd_rendered, strlen(test->script) + STASIS_BUFSIZ);
}
guard_free(cmd_rendered);
} else {
@@ -229,8 +227,7 @@ void delivery_tests_run(struct Delivery *ctx) {
if (!globals.enable_parallel || !test->parallel) {
selected = SERIAL;
memset(pool_name, 0, sizeof(pool_name));
- strncpy(pool_name, "serial", sizeof(pool_name) - 1);
- pool_name[sizeof(pool_name) - 1] = '\0';
+ safe_strncpy(pool_name, "serial", sizeof(pool_name));
}
if (asprintf(&runner_cmd, runner_cmd_fmt, cmd) < 0) {
@@ -281,14 +278,12 @@ void delivery_tests_run(struct Delivery *ctx) {
exit(1);
}
- strncpy(cmd, test->script_setup, cmd_len - 1);
- cmd[cmd_len - 1] = '\0';
+ safe_strncpy(cmd, test->script_setup, cmd_len);
char *cmd_rendered = tpl_render(cmd);
if (cmd_rendered) {
if (strcmp(cmd_rendered, cmd) != 0) {
- strncpy(cmd, cmd_rendered, cmd_len - 1);
- cmd[strlen(cmd_rendered) ? strlen(cmd_rendered) - 1 : 0] = '\0';
+ safe_strncpy(cmd, cmd_rendered, cmd_len);
}
guard_free(cmd_rendered);
} else {