compose: Ensure we mmap only regular files
Currently we do not check that the Compose files we try successively are *regular* files. This may result in an error, while we should just really just skip the corresponding path. Fixed by adding the new utily function `open_file`.master
parent
54f073ce17
commit
1731c6b3ef
|
@ -176,35 +176,27 @@ xkb_compose_table_new_from_locale(struct xkb_context *ctx,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
path = get_xcomposefile_path(ctx);
|
path = get_xcomposefile_path(ctx);
|
||||||
if (path) {
|
file = open_file(path);
|
||||||
file = fopen(path, "rb");
|
|
||||||
if (file)
|
if (file)
|
||||||
goto found_path;
|
goto found_path;
|
||||||
}
|
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
path = get_xdg_xcompose_file_path(ctx);
|
path = get_xdg_xcompose_file_path(ctx);
|
||||||
if (path) {
|
file = open_file(path);
|
||||||
file = fopen(path, "rb");
|
|
||||||
if (file)
|
if (file)
|
||||||
goto found_path;
|
goto found_path;
|
||||||
}
|
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
path = get_home_xcompose_file_path(ctx);
|
path = get_home_xcompose_file_path(ctx);
|
||||||
if (path) {
|
file = open_file(path);
|
||||||
file = fopen(path, "rb");
|
|
||||||
if (file)
|
if (file)
|
||||||
goto found_path;
|
goto found_path;
|
||||||
}
|
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
path = get_locale_compose_file_path(ctx, table->locale);
|
path = get_locale_compose_file_path(ctx, table->locale);
|
||||||
if (path) {
|
file = open_file(path);
|
||||||
file = fopen(path, "rb");
|
|
||||||
if (file)
|
if (file)
|
||||||
goto found_path;
|
goto found_path;
|
||||||
}
|
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
log_err(ctx, XKB_LOG_MESSAGE_NO_ID,
|
log_err(ctx, XKB_LOG_MESSAGE_NO_ID,
|
||||||
|
|
36
src/utils.c
36
src/utils.c
|
@ -23,14 +23,14 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -111,6 +111,38 @@ unmap_file(char *str, size_t size)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Open a file and ensure it is a regular file.
|
||||||
|
* Returns NULL in case of error. */
|
||||||
|
FILE*
|
||||||
|
open_file(const char *path)
|
||||||
|
{
|
||||||
|
if (!path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int fd = open(path, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct stat stat_buf;
|
||||||
|
int err = fstat(fd, &stat_buf);
|
||||||
|
|
||||||
|
if (err != 0 || !S_ISREG(stat_buf.st_mode)) {
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* While unlikely to happen, if `fp` is NULL then we must close the file
|
||||||
|
* descriptor. This is poorly documented and missing from the man page; see instead:
|
||||||
|
* https://www.ibm.com/docs/en/i/7.3?topic=functions-fdopen-associates-stream-file-descriptor)
|
||||||
|
* Confirmed by Peter to be necessary in glibc. */
|
||||||
|
FILE *fp = fdopen(fd, "rb");
|
||||||
|
if (fp == NULL) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
// ASCII lower-case map.
|
// ASCII lower-case map.
|
||||||
static const unsigned char lower_map[] = {
|
static const unsigned char lower_map[] = {
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||||
|
|
|
@ -47,6 +47,9 @@
|
||||||
# ifndef S_ISDIR
|
# ifndef S_ISDIR
|
||||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||||
# endif
|
# endif
|
||||||
|
# ifndef S_ISREG
|
||||||
|
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||||
|
# endif
|
||||||
typedef SSIZE_T ssize_t;
|
typedef SSIZE_T ssize_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -263,6 +266,9 @@ check_eaccess(const char *path, int mode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE*
|
||||||
|
open_file(const char *path);
|
||||||
|
|
||||||
#if defined(HAVE_SECURE_GETENV)
|
#if defined(HAVE_SECURE_GETENV)
|
||||||
# define secure_getenv secure_getenv
|
# define secure_getenv secure_getenv
|
||||||
#elif defined(HAVE___SECURE_GETENV)
|
#elif defined(HAVE___SECURE_GETENV)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "xkbcommon/xkbcommon-compose.h"
|
#include "xkbcommon/xkbcommon-compose.h"
|
||||||
|
|
||||||
|
@ -499,6 +500,18 @@ test_XCOMPOSEFILE(struct xkb_context *ctx)
|
||||||
struct xkb_compose_table *table;
|
struct xkb_compose_table *table;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
|
/* Error: directory */
|
||||||
|
path = test_get_path("locale/en_US.UTF-8");
|
||||||
|
setenv("XCOMPOSEFILE", path, 1);
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
table = xkb_compose_table_new_from_locale(ctx, "blabla",
|
||||||
|
XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||||
|
assert_printf(errno != ENODEV && errno != EISDIR,
|
||||||
|
"Should not be an error from `map_file`\n");
|
||||||
|
assert(!table);
|
||||||
|
|
||||||
|
/* OK: regular file */
|
||||||
path = test_get_path("locale/en_US.UTF-8/Compose");
|
path = test_get_path("locale/en_US.UTF-8/Compose");
|
||||||
setenv("XCOMPOSEFILE", path, 1);
|
setenv("XCOMPOSEFILE", path, 1);
|
||||||
free(path);
|
free(path);
|
||||||
|
|
Loading…
Reference in New Issue