Merge pull request #9246 from keszybz/ellipsize-invalid-mem-ref

Fix invalid memory reference in ellipsize_mem()
This commit is contained in:
Lennart Poettering 2018-06-11 12:52:38 +02:00 committed by GitHub
commit c602fd0f19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 9 deletions

View file

@ -882,8 +882,8 @@ static int table_data_requested_width(TableData *d, size_t *ret) {
return 0;
}
static char *align_string_mem(const char *str, size_t old_length, size_t new_length, unsigned percent) {
size_t w = 0, space, lspace;
static char *align_string_mem(const char *str, size_t new_length, unsigned percent) {
size_t w = 0, space, lspace, old_length;
const char *p;
char *ret;
size_t i;
@ -893,8 +893,7 @@ static char *align_string_mem(const char *str, size_t old_length, size_t new_len
assert(str);
assert(percent <= 100);
if (old_length == (size_t) -1)
old_length = strlen(str);
old_length = strlen(str);
/* Determine current width on screen */
p = str;
@ -1174,7 +1173,7 @@ int table_print(Table *t, FILE *f) {
if (l > width[j]) {
/* Field is wider than allocated space. Let's ellipsize */
buffer = ellipsize_mem(field, (size_t) -1, width[j], d->ellipsize_percent);
buffer = ellipsize(field, width[j], d->ellipsize_percent);
if (!buffer)
return -ENOMEM;
@ -1183,7 +1182,7 @@ int table_print(Table *t, FILE *f) {
} else if (l < width[j]) {
/* Field is shorter than allocated space. Let's align with spaces */
buffer = align_string_mem(field, (size_t) -1, width[j], d->align_percent);
buffer = align_string_mem(field, width[j], d->align_percent);
if (!buffer)
return -ENOMEM;

View file

@ -541,7 +541,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
return strdup("");
/* If no multibyte characters use ascii_ellipsize_mem for speed */
if (ascii_is_valid(s))
if (ascii_is_valid_n(s, old_length))
return ascii_ellipsize_mem(s, old_length, new_length, percent);
x = ((new_length - 1) * percent) / 100;

View file

@ -247,6 +247,9 @@ char *utf8_escape_non_printable(const char *str) {
char *ascii_is_valid(const char *str) {
const char *p;
/* Check whether the string consists of valid ASCII bytes,
* i.e values between 0 and 127, inclusive. */
assert(str);
for (p = str; *p; p++)
@ -256,6 +259,21 @@ char *ascii_is_valid(const char *str) {
return (char*) str;
}
char *ascii_is_valid_n(const char *str, size_t len) {
size_t i;
/* Very similar to ascii_is_valid(), but checks exactly len
* bytes and rejects any NULs in that range. */
assert(str);
for (i = 0; i < len; i++)
if ((unsigned char) str[i] >= 128 || str[i] == 0)
return NULL;
return (char*) str;
}
/**
* utf8_encode_unichar() - Encode single UCS-4 character as UTF-8
* @out_utf8: output buffer of at least 4 bytes or NULL

View file

@ -22,6 +22,7 @@ bool unichar_is_valid(char32_t c);
const char *utf8_is_valid(const char *s) _pure_;
char *ascii_is_valid(const char *s) _pure_;
char *ascii_is_valid_n(const char *str, size_t len);
bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_;
#define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true)

View file

@ -24,11 +24,21 @@ static void test_utf8_is_valid(void) {
}
static void test_ascii_is_valid(void) {
assert_se(ascii_is_valid("alsdjf\t\vbarr\nba z"));
assert_se( ascii_is_valid("alsdjf\t\vbarr\nba z"));
assert_se(!ascii_is_valid("\342\204\242"));
assert_se(!ascii_is_valid("\341\204"));
}
static void test_ascii_is_valid_n(void) {
assert_se( ascii_is_valid_n("alsdjf\t\vbarr\nba z", 17));
assert_se( ascii_is_valid_n("alsdjf\t\vbarr\nba z", 16));
assert_se(!ascii_is_valid_n("alsdjf\t\vbarr\nba z", 18));
assert_se(!ascii_is_valid_n("\342\204\242", 3));
assert_se(!ascii_is_valid_n("\342\204\242", 2));
assert_se(!ascii_is_valid_n("\342\204\242", 1));
assert_se( ascii_is_valid_n("\342\204\242", 0));
}
static void test_utf8_encoded_valid_unichar(void) {
assert_se(utf8_encoded_valid_unichar("\342\204\242") == 3);
assert_se(utf8_encoded_valid_unichar("\302\256") == 2);
@ -115,6 +125,7 @@ int main(int argc, char *argv[]) {
test_utf8_is_valid();
test_utf8_is_printable();
test_ascii_is_valid();
test_ascii_is_valid_n();
test_utf8_encoded_valid_unichar();
test_utf8_escaping();
test_utf8_escaping_printable();

File diff suppressed because one or more lines are too long

View file

@ -14,8 +14,12 @@ sanitize_address = custom_target(
sanitizers = [['address', sanitize_address]]
fuzz_regression_tests = '''
fuzz-dns-packet/oss-fuzz-5465
fuzz-dns-packet/issue-7888
fuzz-dns-packet/oss-fuzz-5465
fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76
fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45
fuzz-journal-remote/oss-fuzz-8659
fuzz-journal-remote/oss-fuzz-8686
fuzz-unit-file/oss-fuzz-6884
fuzz-unit-file/oss-fuzz-6885
fuzz-unit-file/oss-fuzz-6886
@ -25,6 +29,7 @@ fuzz_regression_tests = '''
fuzz-unit-file/oss-fuzz-6908
fuzz-unit-file/oss-fuzz-6917
fuzz-unit-file/oss-fuzz-6977
fuzz-unit-file/oss-fuzz-6977-unminimized
fuzz-unit-file/oss-fuzz-7004
fuzz-unit-file/oss-fuzz-8064
fuzz-unit-file/oss-fuzz-8827