diff options
author | Mattias Andrée <maandree@kth.se> | 2023-01-08 16:23:56 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2023-01-08 16:23:56 +0100 |
commit | 627e5b9789c663343c74dac6535724ddc63aae1c (patch) | |
tree | af78890b546b774267ff82520f0756dd159f8d86 | |
parent | Improve libfonts_get_default_font_name and draft implementation of libfonts_get_default_font (diff) | |
download | libfonts-627e5b9789c663343c74dac6535724ddc63aae1c.tar.gz libfonts-627e5b9789c663343c74dac6535724ddc63aae1c.tar.bz2 libfonts-627e5b9789c663343c74dac6535724ddc63aae1c.tar.xz |
Add environment spoofing
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | common.h | 4 | ||||
-rw-r--r-- | config.mk | 3 | ||||
-rw-r--r-- | libfonts.h | 50 | ||||
-rw-r--r-- | libfonts_get_default_font.c | 79 | ||||
-rw-r--r-- | libfonts_getenv__.c | 30 | ||||
-rw-r--r-- | libfonts_gethome__.c | 40 | ||||
-rw-r--r-- | libfonts_used_environs.c | 34 |
8 files changed, 187 insertions, 65 deletions
@@ -16,7 +16,7 @@ LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR) LIB_NAME = fonts -OBJ =\ +PUBLIC_OBJ =\ libfonts_calculate_subpixel_order.o\ libfonts_decode_font_description.o\ libfonts_encode_font_description.o\ @@ -24,14 +24,20 @@ OBJ =\ libfonts_get_default_font_name.o\ libfonts_get_output_dpi.o\ libfonts_get_subpixel_order_class.o\ - libfonts_unget_subpixel_order_class.o + libfonts_unget_subpixel_order_class.o\ + libfonts_used_environs.o + +OBJ =\ + $(PUBLIC_OBJ)\ + libfonts_getenv__.o\ + libfonts_gethome__.o\ HDR =\ common.h\ libfonts.h LOBJ = $(OBJ:.o=.lo) -TESTS = $(OBJ:.o=.test) +TESTS = $(PUBLIC_OBJ:.o=.test) all: libfonts.a libfonts.$(LIBEXT) $(TESTS) @@ -33,6 +33,10 @@ eq(double a, double b) } +const char *libfonts_getenv__(const char *name, struct libfonts_context *ctx); +char *libfonts_gethome__(struct libfonts_context *ctx); + + #ifdef TEST # define ASSERT(ASSERTION)\ @@ -6,3 +6,6 @@ CC = c99 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE CFLAGS = -Wall -g LDFLAGS = + +# Add -DVALIDATE to CPPFLAGS to run extra code checks, +# that are only useful for development, at run time @@ -1571,11 +1571,53 @@ struct libfonts_font_description { char _buf[256]; }; +/** + * Structure that can be used to spoof the + * environment the library is executed in + */ +struct libfonts_context { + /** + * Environment variables to add or override + * + * `libfonts_used_environs` can be used to + * enumerate the environment variables that + * affect the execution of the environment + */ + char **environ; + + /** + * The real user ID of the process + * + * Only used if `.use_context_uid` is non-zero + */ + uid_t uid; + + /** + * Non-zero to remove all environment + * variables that are not included in + * `.environ` + */ + int ignore_process_environ; + + /** + * Whether `.uid` is used + */ + int use_context_uid; +}; + + +/** + * `NULL`-terminated list of environment variables + * that affect the execution of the library + */ +extern const char *const libfonts_used_environs[]; + /** * Get the font a default font name aliases to * * @param font The default font + * @param ctx Optional `struct libfonts_context` * @return The font the default font is an alias for * (shall be deallocated using free(3) when no * longer used), or `NULL` on failure; in the @@ -1584,7 +1626,7 @@ struct libfonts_font_description { * * @throws EINVAL Unrecognised value on `font` */ -char *libfonts_get_default_font(enum libfonts_default_font); +char *libfonts_get_default_font(enum libfonts_default_font, struct libfonts_context *); /** * Get the alias for a default font @@ -1674,11 +1716,12 @@ int libfonts_do_decoded_font_descriptions_match(const struct libfonts_font_descr * @param settings Output parameter for the rendering settings; * `settings->dpi_x` and `settings->dpi_y` will * have a fallback value assigned if configured to 0 + * @param ctx Optional `struct libfonts_context` * @return 1 if rendering settings where found, * 0 otherwise (`*settings` will be filled with fallback values), * -1 on failure */ -int libfonts_get_default_rendering_settings(struct libfonts_rendering_settings *); +int libfonts_get_default_rendering_settings(struct libfonts_rendering_settings *, struct libfonts_context *); /* TODO implement libfonts_get_default_rendering_settings * * /etc/libfonts/default-rendering.conf @@ -1703,11 +1746,12 @@ int libfonts_get_default_rendering_settings(struct libfonts_rendering_settings * * * @param settings Output parameter for the rendering settings * @param name The EDID (or other identifier) of the output + * @param ctx Optional `struct libfonts_context` * @return 1 if rendering settings where found, * 0 otherwise (`*settings` will be unmodified), * -1 on failure */ -int libfonts_get_output_rendering_settings(struct libfonts_rendering_settings *, const char *); +int libfonts_get_output_rendering_settings(struct libfonts_rendering_settings *, const char *, struct libfonts_context *); /* TODO implement libfonts_get_output_rendering_settings * * /etc/libfonts/output-rendering.conf diff --git a/libfonts_get_default_font.c b/libfonts_get_default_font.c index d27e661..7c21b1f 100644 --- a/libfonts_get_default_font.c +++ b/libfonts_get_default_font.c @@ -10,43 +10,6 @@ find(const char *dir_part1, const char *dir_part2, const char *dir_part3) } static char * -gethome(void) -{ - uid_t uid = getuid(); - size_t size = 512; - char *buf = NULL, *new; - char *ret = NULL; - struct passwd pw, *pwp; - int err; - - goto beginning; - - do { - if (size > SIZE_MAX / 2) - goto enomem; - size *= 2; - beginning: - new = realloc(buf, size); - if (!new) { - enomem: - free(buf); - errno = ENOMEM; - return NULL; - } - buf = new; - } while ((err = getpwuid_r(uid, &pw, buf, size, &pwp)) == ERANGE); - if (err) { - free(buf); - return NULL; - } - - if (pwp && pwp->pw_dir) - ret = strdup(pwp->pw_dir); - free(buf); - return ret; -} - -static char * getn(const char *file_part1, size_t file_part1_len, const char *file_part2, const char *name) { size_t file_part2_len = strlen(file_part2); @@ -82,9 +45,9 @@ get(const char *file_part1, const char *file_part2, const char *name) } char * -libfonts_get_default_font(enum libfonts_default_font font) +libfonts_get_default_font(enum libfonts_default_font font, struct libfonts_context *ctx) { - const char *env, *var, *next; + const char *env, *var, *next, *confenv, *homeenv; char *ret, *home = NULL; int saved_errno = errno; size_t len; @@ -103,28 +66,28 @@ libfonts_get_default_font(enum libfonts_default_font font) return NULL; } - ret = getenv(env); - if (ret && *ret) - return strdup(ret); + env = libfonts_getenv__(env, ctx); + if (env && *env) + return strdup(env); - env = getenv("XDG_CONFIG_HOME"); - if (env && *env) { - ret = get(env, "/libfonts/default-fonts.conf", var); + confenv = libfonts_getenv__("XDG_CONFIG_HOME", ctx); + if (confenv && *confenv) { + ret = get(confenv, "/libfonts/default-fonts.conf", var); if (ret) goto out; } - env = getenv("HOME"); - if (env && *env) { - ret = get(env, "/.config/libfonts/default-fonts.conf", var); + homeenv = libfonts_getenv__("HOME", ctx); + if (homeenv && *homeenv) { + ret = get(homeenv, "/.config/libfonts/default-fonts.conf", var); if (ret) goto out; - ret = get(env, "/.libfonts/default-fonts.conf", var); + ret = get(homeenv, "/.libfonts/default-fonts.conf", var); if (ret) goto out; } - home = gethome(); + home = libfonts_gethome__(ctx); if (home && *home) { ret = get(home, "/.config/libfonts/default-fonts.conf", var); if (ret) @@ -134,33 +97,31 @@ libfonts_get_default_font(enum libfonts_default_font font) goto out; } - env = getenv("XDG_CONFIG_HOME"); - if (env && *env) { + if (confenv && *confenv) { ret = find(env, "/libfonts/", var); if (ret) goto out; } - env = getenv("HOME"); - if (env && *env) { - ret = find(env, "/.config/libfonts/", var); + if (homeenv && *homeenv) { + ret = find(homeenv, "/.config/libfonts/", var); if (ret) goto out; - ret = find(env, "/.libfonts/", var); + ret = find(homeenv, "/.libfonts/", var); if (ret) goto out; } if (home && *home) { - ret = find(env, "/.config/libfonts/", var); + ret = find(home, "/.config/libfonts/", var); if (ret) goto out; - ret = find(env, "/.libfonts/", var); + ret = find(home, "/.libfonts/", var); if (ret) goto out; } - env = getenv("XDG_CONFIG_DIRS"); + env = libfonts_getenv__("XDG_CONFIG_DIRS", ctx); if (env && *env) { do { next = strchr(&env[1], ':'); diff --git a/libfonts_getenv__.c b/libfonts_getenv__.c new file mode 100644 index 0000000..d998337 --- /dev/null +++ b/libfonts_getenv__.c @@ -0,0 +1,30 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char * +libfonts_getenv__(const char *name, struct libfonts_context *ctx) +{ + char **envp; + size_t len = strlen(name); + +#ifdef VALIDATE + size_t i; + if (!name) { + fprintf(stderr, "`name` parameter in libfonts_getenv__ is NULL\n"); + abort(); + } + for (i = 0; libfonts_used_environs[i]; i++) + if (!strcmp(name, libfonts_used_environs[i])) + goto ok; + fprintf(stderr, "Value of `name` parameter (\"%s\") in libfonts_getenv__ is not in libfonts_used_environs\n", name); + abort(); +ok: +#endif + + if (ctx && ctx->environ) + for (envp = ctx->environ; *envp; envp++) + if (strncmp(*envp, name, len) && (*envp)[len] == '=') + return *envp; + return ctx->ignore_process_environ ? NULL : getenv(name); +} diff --git a/libfonts_gethome__.c b/libfonts_gethome__.c new file mode 100644 index 0000000..902029f --- /dev/null +++ b/libfonts_gethome__.c @@ -0,0 +1,40 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +char * +libfonts_gethome__(struct libfonts_context *ctx) +{ + uid_t uid = (ctx && ctx->use_context_uid) ? ctx->uid : getuid(); + size_t size = 512; + char *buf = NULL, *new; + char *ret = NULL; + struct passwd pw, *pwp; + int err; + + goto beginning; + + do { + if (size > SIZE_MAX / 2) + goto enomem; + size *= 2; + beginning: + new = realloc(buf, size); + if (!new) { + enomem: + free(buf); + errno = ENOMEM; + return NULL; + } + buf = new; + } while ((err = getpwuid_r(uid, &pw, buf, size, &pwp)) == ERANGE); + if (err) { + free(buf); + return NULL; + } + + if (pwp && pwp->pw_dir) + ret = strdup(pwp->pw_dir); + free(buf); + return ret; +} diff --git a/libfonts_used_environs.c b/libfonts_used_environs.c new file mode 100644 index 0000000..54232b4 --- /dev/null +++ b/libfonts_used_environs.c @@ -0,0 +1,34 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +const char *const libfonts_used_environs[] = { + "LIBFONTS_DEFAULT_SANS_SERIF", + "LIBFONTS_DEFAULT_SERIF", + "LIBFONTS_DEFAULT_MONOSPACE", + "XDG_CONFIG_HOME", + "HOME", + NULL +}; + + +#else + + +int +main(void) +{ + size_t i, j, n; + for (n = 0; n < 100; n++) + if (!libfonts_used_environs[n]) + break; + ASSERT(n < 100); + for (i = 0; i < n; i++) + for (j = i + 1; j < n; j++) + ASSERT(strcmp(libfonts_used_environs[i], libfonts_used_environs[j])); + return 0; +} + + +#endif |