XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
/**
* Don't take RMLVO names from the environment.
+ *
* @since 0.3.0
*/
- XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1)
+ XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1),
+ /**
+ * Disable the use of secure_getenv for this context, so that privileged
+ * processes can use environment variables. Client uses at their own risk.
+ *
+ * @since 1.5.0
+ */
+ XKB_CONTEXT_NO_SECURE_GETENV = (1 << 2)
};
/**
* on the lookup behavior.
*/
RXKB_CONTEXT_LOAD_EXOTIC_RULES = (1 << 1),
+ /**
+ * Disable the use of secure_getenv for this context, so that privileged
+ * processes can use environment variables. Client uses at their own risk.
+ *
+ * @since 1.5.0
+ */
+ RXKB_CONTEXT_NO_SECURE_GETENV = (1 << 2)
};
/**
scanner_buf_append(s, '%');
}
else if (scanner_chr(s, 'H')) {
- const char *home = secure_getenv("HOME");
+ const char *home = xkb_context_getenv(table->ctx, "HOME");
if (!home) {
scanner_err(s, "%%H was used in an include statement, but the HOME environment variable is not set");
return TOK_ERROR;
}
}
else if (scanner_chr(s, 'L')) {
- char *path = get_locale_compose_file_path(table->locale);
+ char *path = get_locale_compose_file_path(table->ctx, table->locale);
if (!path) {
scanner_err(s, "failed to expand %%L to the locale Compose file");
return TOK_ERROR;
free(path);
}
else if (scanner_chr(s, 'S')) {
- const char *xlocaledir = get_xlocaledir_path();
+ const char *xlocaledir = get_xlocaledir_path(table->ctx);
if (!scanner_buf_appends(s, xlocaledir)) {
scanner_err(s, "include path after expanding %%S is too long");
return TOK_ERROR;
#include "config.h"
+#include "xkbcommon/xkbcommon.h"
#include "utils.h"
+#include "context.h"
#include "paths.h"
-#include "utils.h"
enum resolve_name_direction {
LEFT_TO_RIGHT,
};
const char *
-get_xlocaledir_path(void)
+get_xlocaledir_path(struct xkb_context *ctx)
{
- const char *dir = secure_getenv("XLOCALEDIR");
+ const char *dir = xkb_context_getenv(ctx, "XLOCALEDIR");
if (!dir)
dir = XLOCALEDIR;
return dir;
* @filename is relative to the xlocaledir.
*/
static char *
-resolve_name(const char *filename, enum resolve_name_direction direction,
- const char *name)
+resolve_name(struct xkb_context *ctx, const char *filename,
+ enum resolve_name_direction direction, const char *name)
{
int ret;
bool ok;
char *match;
size_t left_len, right_len, name_len;
- xlocaledir = get_xlocaledir_path();
+ xlocaledir = get_xlocaledir_path(ctx);
ret = snprintf(path, sizeof(path), "%s/%s", xlocaledir, filename);
if (ret < 0 || (size_t) ret >= sizeof(path))
}
char *
-resolve_locale(const char *locale)
+resolve_locale(struct xkb_context *ctx, const char *locale)
{
- char *alias = resolve_name("locale.alias", LEFT_TO_RIGHT, locale);
+ char *alias = resolve_name(ctx, "locale.alias", LEFT_TO_RIGHT, locale);
return alias ? alias : strdup(locale);
}
char *
-get_xcomposefile_path(void)
+get_xcomposefile_path(struct xkb_context *ctx)
{
- return strdup_safe(secure_getenv("XCOMPOSEFILE"));
+ return strdup_safe(xkb_context_getenv(ctx, "XCOMPOSEFILE"));
}
char *
-get_xdg_xcompose_file_path(void)
+get_xdg_xcompose_file_path(struct xkb_context *ctx)
{
const char *xdg_config_home;
const char *home;
- xdg_config_home = secure_getenv("XDG_CONFIG_HOME");
+ xdg_config_home = xkb_context_getenv(ctx, "XDG_CONFIG_HOME");
if (!xdg_config_home || xdg_config_home[0] != '/') {
- home = secure_getenv("HOME");
+ home = xkb_context_getenv(ctx, "HOME");
if (!home)
return NULL;
return asprintf_safe("%s/.config/XCompose", home);
}
char *
-get_home_xcompose_file_path(void)
+get_home_xcompose_file_path(struct xkb_context *ctx)
{
const char *home;
- home = secure_getenv("HOME");
+ home = xkb_context_getenv(ctx, "HOME");
if (!home)
return NULL;
}
char *
-get_locale_compose_file_path(const char *locale)
+get_locale_compose_file_path(struct xkb_context *ctx, const char *locale)
{
char *resolved;
char *path;
if (streq(locale, "C"))
locale = "en_US.UTF-8";
- resolved = resolve_name("compose.dir", RIGHT_TO_LEFT, locale);
+ resolved = resolve_name(ctx, "compose.dir", RIGHT_TO_LEFT, locale);
if (!resolved)
return NULL;
path = resolved;
}
else {
- const char *xlocaledir = get_xlocaledir_path();
+ const char *xlocaledir = get_xlocaledir_path(ctx);
path = asprintf_safe("%s/%s", xlocaledir, resolved);
free(resolved);
}
#define COMPOSE_RESOLVE_H
char *
-resolve_locale(const char *locale);
+resolve_locale(struct xkb_context *ctx, const char *locale);
const char *
-get_xlocaledir_path(void);
+get_xlocaledir_path(struct xkb_context *ctx);
char *
-get_xcomposefile_path(void);
+get_xcomposefile_path(struct xkb_context *ctx);
char *
-get_xdg_xcompose_file_path(void);
+get_xdg_xcompose_file_path(struct xkb_context *ctx);
char *
-get_home_xcompose_file_path(void);
+get_home_xcompose_file_path(struct xkb_context *ctx);
char *
-get_locale_compose_file_path(const char *locale);
+get_locale_compose_file_path(struct xkb_context *ctx, const char *locale);
#endif
struct xkb_compose_table *table;
struct compose_node dummy;
- resolved_locale = resolve_locale(locale);
+ resolved_locale = resolve_locale(ctx, locale);
if (!resolved_locale)
return NULL;
if (!table)
return NULL;
- path = get_xcomposefile_path();
+ path = get_xcomposefile_path(ctx);
if (path) {
file = fopen(path, "rb");
if (file)
}
free(path);
- path = get_xdg_xcompose_file_path();
+ path = get_xdg_xcompose_file_path(ctx);
if (path) {
file = fopen(path, "rb");
if (file)
}
free(path);
- path = get_home_xcompose_file_path();
+ path = get_home_xcompose_file_path(ctx);
if (path) {
file = fopen(path, "rb");
if (file)
}
free(path);
- path = get_locale_compose_file_path(table->locale);
+ path = get_locale_compose_file_path(ctx, table->locale);
if (path) {
file = fopen(path, "rb");
if (file)
#include "utils.h"
#include "context.h"
+char *
+xkb_context_getenv(struct xkb_context *ctx, const char *name)
+{
+ if (ctx->use_secure_getenv) {
+ return secure_getenv(name);
+ } else {
+ return getenv(name);
+ }
+}
+
unsigned int
xkb_context_num_failed_include_paths(struct xkb_context *ctx)
{
const char *env = NULL;
if (ctx->use_environment_names)
- env = secure_getenv("XKB_DEFAULT_RULES");
+ env = xkb_context_getenv(ctx, "XKB_DEFAULT_RULES");
return env ? env : DEFAULT_XKB_RULES;
}
const char *env = NULL;
if (ctx->use_environment_names)
- env = secure_getenv("XKB_DEFAULT_MODEL");
+ env = xkb_context_getenv(ctx, "XKB_DEFAULT_MODEL");
return env ? env : DEFAULT_XKB_MODEL;
}
const char *env = NULL;
if (ctx->use_environment_names)
- env = secure_getenv("XKB_DEFAULT_LAYOUT");
+ env = xkb_context_getenv(ctx, "XKB_DEFAULT_LAYOUT");
return env ? env : DEFAULT_XKB_LAYOUT;
}
xkb_context_get_default_variant(struct xkb_context *ctx)
{
const char *env = NULL;
- const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT");
+ const char *layout = xkb_context_getenv(ctx, "XKB_DEFAULT_LAYOUT");
/* We don't want to inherit the variant if they haven't also set a
* layout, since they're so closely paired. */
if (layout && ctx->use_environment_names)
- env = secure_getenv("XKB_DEFAULT_VARIANT");
+ env = xkb_context_getenv(ctx, "XKB_DEFAULT_VARIANT");
return env ? env : DEFAULT_XKB_VARIANT;
}
const char *env = NULL;
if (ctx->use_environment_names)
- env = secure_getenv("XKB_DEFAULT_OPTIONS");
+ env = xkb_context_getenv(ctx, "XKB_DEFAULT_OPTIONS");
return env ? env : DEFAULT_XKB_OPTIONS;
}
#include "utils.h"
#include "context.h"
+
/**
* Append one directory to the context's include path.
*/
const char *
xkb_context_include_path_get_extra_path(struct xkb_context *ctx)
{
- const char *extra = secure_getenv("XKB_CONFIG_EXTRA_PATH");
+ const char *extra = xkb_context_getenv(ctx, "XKB_CONFIG_EXTRA_PATH");
return extra ? extra : DFLT_XKB_CONFIG_EXTRA_PATH;
}
const char *
xkb_context_include_path_get_system_path(struct xkb_context *ctx)
{
- const char *root = secure_getenv("XKB_CONFIG_ROOT");
+ const char *root = xkb_context_getenv(ctx, "XKB_CONFIG_ROOT");
return root ? root : DFLT_XKB_CONFIG_ROOT;
}
char *user_path;
int ret = 0;
- home = secure_getenv("HOME");
+ home = xkb_context_getenv(ctx, "HOME");
- xdg = secure_getenv("XDG_CONFIG_HOME");
+ xdg = xkb_context_getenv(ctx, "XDG_CONFIG_HOME");
if (xdg != NULL) {
user_path = asprintf_safe("%s/xkb", xdg);
if (user_path) {
ctx->log_fn = default_log_fn;
ctx->log_level = XKB_LOG_LEVEL_ERROR;
ctx->log_verbosity = 0;
+ ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
+ ctx->use_secure_getenv = !(flags & XKB_CONTEXT_NO_SECURE_GETENV);
/* Environment overwrites defaults. */
- env = secure_getenv("XKB_LOG_LEVEL");
+ env = xkb_context_getenv(ctx, "XKB_LOG_LEVEL");
if (env)
xkb_context_set_log_level(ctx, log_level(env));
- env = secure_getenv("XKB_LOG_VERBOSITY");
+ env = xkb_context_getenv(ctx, "XKB_LOG_VERBOSITY");
if (env)
xkb_context_set_log_verbosity(ctx, log_verbosity(env));
return NULL;
}
- ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
-
ctx->atom_table = atom_table_new();
if (!ctx->atom_table) {
xkb_context_unref(ctx);
size_t text_next;
unsigned int use_environment_names : 1;
+ unsigned int use_secure_getenv : 1;
};
+char *
+xkb_context_getenv(struct xkb_context *ctx, const char *name);
+
unsigned int
xkb_context_num_failed_include_paths(struct xkb_context *ctx);
enum context_state context_state;
bool load_extra_rules_files;
+ bool use_secure_getenv;
struct list models; /* list of struct rxkb_models */
struct list layouts; /* list of struct rxkb_layouts */
DECLARE_CREATE_FOR_TYPE(rxkb_context);
DECLARE_TYPED_GETTER_FOR_TYPE(rxkb_context, log_level, enum rxkb_log_level);
+static char *
+rxkb_context_getenv(struct rxkb_context *ctx, const char *name)
+{
+ if (ctx->use_secure_getenv) {
+ return secure_getenv(name);
+ } else {
+ return getenv(name);
+ }
+}
+
+
XKB_EXPORT void
rxkb_context_set_log_level(struct rxkb_context *ctx,
enum rxkb_log_level level)
ctx->context_state = CONTEXT_NEW;
ctx->load_extra_rules_files = flags & RXKB_CONTEXT_LOAD_EXOTIC_RULES;
+ ctx->use_secure_getenv = !(flags & RXKB_CONTEXT_NO_SECURE_GETENV);
ctx->log_fn = default_log_fn;
ctx->log_level = RXKB_LOG_LEVEL_ERROR;
/* Environment overwrites defaults. */
- env = secure_getenv("RXKB_LOG_LEVEL");
+ env = rxkb_context_getenv(ctx, "RXKB_LOG_LEVEL");
if (env)
rxkb_context_set_log_level(ctx, log_level(env));
return false;
}
- home = secure_getenv("HOME");
+ home = rxkb_context_getenv(ctx, "HOME");
- xdg = secure_getenv("XDG_CONFIG_HOME");
+ xdg = rxkb_context_getenv(ctx, "XDG_CONFIG_HOME");
if (xdg != NULL) {
user_path = asprintf_safe("%s/xkb", xdg);
if (user_path) {
}
}
- extra = secure_getenv("XKB_CONFIG_EXTRA_PATH");
+ extra = rxkb_context_getenv(ctx, "XKB_CONFIG_EXTRA_PATH");
if (extra != NULL)
ret |= rxkb_context_include_path_append(ctx, extra);
else
ret |= rxkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_EXTRA_PATH);
- root = secure_getenv("XKB_CONFIG_ROOT");
+ root = rxkb_context_getenv(ctx, "XKB_CONFIG_ROOT");
if (root != NULL)
ret |= rxkb_context_include_path_append(ctx, root);
else
scanner_buf_append(&s, '%');
}
else if (scanner_chr(&s, 'H')) {
- const char *home = secure_getenv("HOME");
+ const char *home = xkb_context_getenv(m->ctx, "HOME");
if (!home) {
scanner_err(&s, "%%H was used in an include statement, but the HOME environment variable is not set");
return;