From f09e36acfe2db50e0452ba1e19b13f4395a8d704 Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Tue, 23 Apr 2019 22:41:31 +0200 Subject: make: do not follow symlinks when resolving blogcfile path --- src/blogc-make/ctx.c | 21 +++++++++++---------- src/blogc-make/utils.c | 35 +++++++++++++++++++++++++++++++++++ src/blogc-make/utils.h | 3 +++ src/common/error.c | 6 ++++++ src/common/error.h | 1 + 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/blogc-make/ctx.c b/src/blogc-make/ctx.c index b8b7bb6..423b334 100644 --- a/src/blogc-make/ctx.c +++ b/src/blogc-make/ctx.c @@ -172,22 +172,21 @@ bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0, if (settings_file == NULL || err == NULL || *err != NULL) return NULL; - char real_filename[PATH_MAX]; - if (NULL == realpath(settings_file, real_filename)) { - *err = bc_error_new_printf(BLOGC_MAKE_ERROR_SETTINGS, - "Failed to resolve settings file (%s): %s", settings_file, - strerror(errno)); + char *abs_filename = bm_abspath(settings_file, err); + if (*err != NULL) return NULL; - } size_t content_len; - char *content = bc_file_get_contents(real_filename, true, &content_len, + char *content = bc_file_get_contents(abs_filename, true, &content_len, err); - if (*err != NULL) + if (*err != NULL) { + free(abs_filename); return NULL; + } bm_settings_t *settings = bm_settings_parse(content, content_len, err); if (settings == NULL || *err != NULL) { + free(abs_filename); free(content); return NULL; } @@ -208,6 +207,7 @@ bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0, atom_template = bm_atom_deploy(settings, err); atom_template_tmp = true; if (*err != NULL) { + free(abs_filename); bm_settings_free(settings); return NULL; } @@ -228,8 +228,9 @@ bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0, } rv->settings = settings; - rv->settings_fctx = bm_filectx_new(rv, real_filename, NULL, NULL); - rv->root_dir = bc_strdup(dirname(real_filename)); + rv->settings_fctx = bm_filectx_new(rv, abs_filename, NULL, NULL); + rv->root_dir = bc_strdup(dirname(abs_filename)); + free(abs_filename); const char *output_dir = getenv("OUTPUT_DIR"); rv->short_output_dir = bc_strdup(output_dir != NULL ? output_dir : "_build"); diff --git a/src/blogc-make/utils.c b/src/blogc-make/utils.c index 0c984f6..91b7b53 100644 --- a/src/blogc-make/utils.c +++ b/src/blogc-make/utils.c @@ -6,10 +6,18 @@ * See the file LICENSE. */ +#include +#include #include #include +#include +#include "../common/error.h" #include "../common/utils.h" +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + char* bm_generate_filename(const char *dir, const char *prefix, const char *fname, @@ -59,3 +67,30 @@ bm_generate_filename(const char *dir, const char *prefix, const char *fname, return bc_string_free(rv, false); } + + +char* +bm_abspath(const char *path, bc_error_t **err) +{ + if (err == NULL || *err != NULL) + return NULL; + + if (path[0] == '/') { + return bc_strdup(path); + } + + char cwd[PATH_MAX]; + if (NULL == getcwd(cwd, sizeof(cwd))) { + *err = bc_error_new_printf(BLOGC_MAKE_ERROR_UTILS, + "Failed to detect absolute path (%s): %s", path, strerror(errno)); + return NULL; + } + + if (cwd[0] != '/') { + *err = bc_error_new_printf(BLOGC_MAKE_ERROR_UTILS, + "Failed to get current working directory: %s", cwd); + return NULL; + } + + return bc_strdup_printf("%s/%s", cwd, path); +} diff --git a/src/blogc-make/utils.h b/src/blogc-make/utils.h index a3dfea0..5353c01 100644 --- a/src/blogc-make/utils.h +++ b/src/blogc-make/utils.h @@ -9,7 +9,10 @@ #ifndef _MAKE_UTILS_H #define _MAKE_UTILS_H +#include "../common/error.h" + char* bm_generate_filename(const char *dir, const char *prefix, const char *fname, const char *ext); +char* bm_abspath(const char *path, bc_error_t **err); #endif /* _MAKE_UTILS_H */ diff --git a/src/common/error.c b/src/common/error.c index 0b41ba7..03695e7 100644 --- a/src/common/error.c +++ b/src/common/error.c @@ -136,6 +136,12 @@ bc_error_print(bc_error_t *err, const char *prefix) case BLOGC_MAKE_ERROR_EXEC: fprintf(stderr, "error: exec: %s\n", err->msg); break; + case BLOGC_MAKE_ERROR_ATOM: + fprintf(stderr, "error: atom: %s\n", err->msg); + break; + case BLOGC_MAKE_ERROR_UTILS: + fprintf(stderr, "error: utils: %s\n", err->msg); + break; default: fprintf(stderr, "error: %s\n", err->msg); } diff --git a/src/common/error.h b/src/common/error.h index d8dd859..b85f006 100644 --- a/src/common/error.h +++ b/src/common/error.h @@ -28,6 +28,7 @@ typedef enum { BLOGC_MAKE_ERROR_SETTINGS = 300, BLOGC_MAKE_ERROR_EXEC, BLOGC_MAKE_ERROR_ATOM, + BLOGC_MAKE_ERROR_UTILS, } bc_error_type_t; -- cgit v1.2.3-18-g5258