mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-25 23:21:33 +03:00
Disallow invalid UTF-8 configuration
It is best to catch such errors early. If invalid UTF-8 ends up being given to dbus methods, the program will crash: process 20801: arguments to dbus_message_iter_append_basic() were incorrect, assertion "_dbus_check_is_valid_utf8 (*string_p)" failed in file dbus-message.c line 2598.
This commit is contained in:
parent
fe05567c31
commit
335c46b598
@ -23,6 +23,7 @@
|
||||
#include "fileio.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
|
||||
int write_string_to_file(FILE *f, const char *line) {
|
||||
errno = 0;
|
||||
@ -177,13 +178,15 @@ int read_full_file(const char *fn, char **contents, size_t *size) {
|
||||
static int parse_env_file_internal(
|
||||
const char *fname,
|
||||
const char *newline,
|
||||
int (*push) (const char *key, char *value, void *userdata),
|
||||
int (*push) (const char *filename, unsigned line,
|
||||
const char *key, char *value, void *userdata),
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_free_ char *contents = NULL, *key = NULL;
|
||||
size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1;
|
||||
char *p, *value = NULL;
|
||||
int r;
|
||||
unsigned line = 1;
|
||||
|
||||
enum {
|
||||
PRE_KEY,
|
||||
@ -230,6 +233,7 @@ static int parse_env_file_internal(
|
||||
case KEY:
|
||||
if (strchr(newline, c)) {
|
||||
state = PRE_KEY;
|
||||
line ++;
|
||||
n_key = 0;
|
||||
} else if (c == '=') {
|
||||
state = PRE_VALUE;
|
||||
@ -253,6 +257,7 @@ static int parse_env_file_internal(
|
||||
case PRE_VALUE:
|
||||
if (strchr(newline, c)) {
|
||||
state = PRE_KEY;
|
||||
line ++;
|
||||
key[n_key] = 0;
|
||||
|
||||
if (value)
|
||||
@ -262,7 +267,7 @@ static int parse_env_file_internal(
|
||||
if (last_key_whitespace != (size_t) -1)
|
||||
key[last_key_whitespace] = 0;
|
||||
|
||||
r = push(key, value, userdata);
|
||||
r = push(fname, line, key, value, userdata);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -292,6 +297,7 @@ static int parse_env_file_internal(
|
||||
case VALUE:
|
||||
if (strchr(newline, c)) {
|
||||
state = PRE_KEY;
|
||||
line ++;
|
||||
|
||||
key[n_key] = 0;
|
||||
|
||||
@ -306,7 +312,7 @@ static int parse_env_file_internal(
|
||||
if (last_key_whitespace != (size_t) -1)
|
||||
key[last_key_whitespace] = 0;
|
||||
|
||||
r = push(key, value, userdata);
|
||||
r = push(fname, line, key, value, userdata);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -408,8 +414,10 @@ static int parse_env_file_internal(
|
||||
case COMMENT:
|
||||
if (c == '\\')
|
||||
state = COMMENT_ESCAPE;
|
||||
else if (strchr(newline, c))
|
||||
else if (strchr(newline, c)) {
|
||||
state = PRE_KEY;
|
||||
line ++;
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMENT_ESCAPE:
|
||||
@ -439,7 +447,7 @@ static int parse_env_file_internal(
|
||||
if (last_key_whitespace != (size_t) -1)
|
||||
key[last_key_whitespace] = 0;
|
||||
|
||||
r = push(key, value, userdata);
|
||||
r = push(fname, line, key, value, userdata);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
@ -451,27 +459,36 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int parse_env_file_push(const char *key, char *value, void *userdata) {
|
||||
const char *k;
|
||||
va_list* ap = (va_list*) userdata;
|
||||
va_list aq;
|
||||
static int parse_env_file_push(const char *filename, unsigned line,
|
||||
const char *key, char *value, void *userdata) {
|
||||
assert(utf8_is_valid(key));
|
||||
|
||||
va_copy(aq, *ap);
|
||||
if (value && !utf8_is_valid(value))
|
||||
/* FIXME: filter UTF-8 */
|
||||
log_error("%s:%u: invalid UTF-8 for key %s: '%s', ignoring.",
|
||||
filename, line, key, value);
|
||||
else {
|
||||
const char *k;
|
||||
va_list* ap = (va_list*) userdata;
|
||||
va_list aq;
|
||||
|
||||
while ((k = va_arg(aq, const char *))) {
|
||||
char **v;
|
||||
va_copy(aq, *ap);
|
||||
|
||||
v = va_arg(aq, char **);
|
||||
while ((k = va_arg(aq, const char *))) {
|
||||
char **v;
|
||||
|
||||
if (streq(key, k)) {
|
||||
va_end(aq);
|
||||
free(*v);
|
||||
*v = value;
|
||||
return 1;
|
||||
v = va_arg(aq, char **);
|
||||
|
||||
if (streq(key, k)) {
|
||||
va_end(aq);
|
||||
free(*v);
|
||||
*v = value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
va_end(aq);
|
||||
va_end(aq);
|
||||
}
|
||||
|
||||
free(value);
|
||||
return 0;
|
||||
@ -494,19 +511,28 @@ int parse_env_file(
|
||||
return r;
|
||||
}
|
||||
|
||||
static int load_env_file_push(const char *key, char *value, void *userdata) {
|
||||
char ***m = userdata;
|
||||
char *p;
|
||||
int r;
|
||||
static int load_env_file_push(const char *filename, unsigned line,
|
||||
const char *key, char *value, void *userdata) {
|
||||
assert(utf8_is_valid(key));
|
||||
|
||||
p = strjoin(key, "=", strempty(value), NULL);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
if (value && !utf8_is_valid(value))
|
||||
/* FIXME: filter UTF-8 */
|
||||
log_error("%s:%u: invalid UTF-8 for key %s: '%s', ignoring.",
|
||||
filename, line, key, value);
|
||||
else {
|
||||
char ***m = userdata;
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
r = strv_push(m, p);
|
||||
if (r < 0) {
|
||||
free(p);
|
||||
return r;
|
||||
p = strjoin(key, "=", strempty(value), NULL);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_push(m, p);
|
||||
if (r < 0) {
|
||||
free(p);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
free(value);
|
||||
|
Loading…
Reference in New Issue
Block a user