diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2022-02-25 20:25:13 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2022-02-25 20:25:13 +0000 |
commit | baa4044ea53d50271af375dbe97ce6226b865781 (patch) | |
tree | 49610483871c3d1d388ef46b8dc20759c864a774 /src/libenvexec/envdir_clamp.c | |
parent | 336d9fedb35e577ce3aef12e633fcdeae04fe96d (diff) | |
download | skalibs-baa4044ea53d50271af375dbe97ce6226b865781.tar.xz |
Bloat envdir with a noclamp option
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libenvexec/envdir_clamp.c')
-rw-r--r-- | src/libenvexec/envdir_clamp.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/libenvexec/envdir_clamp.c b/src/libenvexec/envdir_clamp.c new file mode 100644 index 0000000..b63ed97 --- /dev/null +++ b/src/libenvexec/envdir_clamp.c @@ -0,0 +1,85 @@ +/* ISC license. */ + +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <skalibs/bytestr.h> +#include <skalibs/env.h> +#include <skalibs/direntry.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include "envdir-internal.h" + +#define MAXVARSIZE 4095 + +int envdir_internal_clamp (char const *path, stralloc *modifs, unsigned int options, char nullis) +{ + char buf[MAXVARSIZE + 1] ; + unsigned int n = 0 ; + size_t pathlen = strlen(path) ; + size_t modifbase = modifs->len ; + int wasnull = !modifs->s ; + DIR *dir = opendir(path) ; + if (!dir) return -1 ; + for (;;) + { + direntry *d ; + size_t len ; + ssize_t r ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + if (str_chr(d->d_name, '=') < len) continue ; + { + char tmp[pathlen + len + 2] ; + memcpy(tmp, path, pathlen) ; + tmp[pathlen] = '/' ; + memcpy(tmp + pathlen + 1, d->d_name, len + 1) ; + r = openreadnclose(tmp, buf, MAXVARSIZE) ; + } + if (r < 0) + { + if (errno == ENOENT) errno = EIDRM ; + goto err ; + } + else if (r > 0) + { + if (options & SKALIBS_ENVDIR_VERBATIM) + { + if (!(options & SKALIBS_ENVDIR_NOCHOMP) && (buf[r-1] == '\n')) r-- ; + } + else + { + r = byte_chr(buf, r, '\n') ; + if (!(options & SKALIBS_ENVDIR_NOCHOMP)) + { + while (r--) if ((buf[r] != ' ') && (buf[r] != '\t') && (buf[r] != '\r')) break ; + r++ ; + } + } + { + size_t i = 0 ; + for (; i < (size_t)r ; i++) if (!buf[i]) buf[i] = nullis ; + } + buf[r++] = 0 ; + if (!env_addmodif(modifs, d->d_name, buf)) goto err ; + } + else if (!env_addmodif(modifs, d->d_name, 0)) goto err ; + n++ ; + } + if (errno) goto err ; + dir_close(dir) ; + return n ; + + err: + { + int e = errno ; + dir_close(dir) ; + if (wasnull) stralloc_free(modifs) ; else modifs->len = modifbase ; + errno = e ; + return -1 ; + } +} |