1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

Merge pull request #2660 from keszybz/memleaks-and-ubsan

Memleaks and ubsan
This commit is contained in:
Daniel Mack 2016-02-19 12:23:43 +01:00
commit dfec18925e
5 changed files with 75 additions and 64 deletions

View File

@ -156,6 +156,10 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
return off;
}
/* bsearch is not allowed on a NULL sequence */
if (node->children_count == 0)
break;
/* lookup child node */
c = s[len - 1 - depth];
search.c = c;

View File

@ -705,8 +705,7 @@ finish:
return 0;
}
int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
static char* extract_multiplier(char *p, usec_t *multiplier) {
static const struct {
const char *suffix;
usec_t usec;
@ -740,7 +739,22 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
{ "usec", 1ULL },
{ "us", 1ULL },
};
unsigned i;
for (i = 0; i < ELEMENTSOF(table); i++) {
char *e;
e = startswith(p, table[i].suffix);
if (e) {
*multiplier = table[i].usec;
return e;
}
}
return p;
}
int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
const char *p, *s;
usec_t r = 0;
bool something = false;
@ -765,8 +779,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
for (;;) {
long long l, z = 0;
char *e;
unsigned i, n = 0;
usec_t multiplier, k;
unsigned n = 0;
usec_t multiplier = default_unit, k;
p += strspn(p, WHITESPACE);
@ -779,10 +793,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
errno = 0;
l = strtoll(p, &e, 10);
if (errno > 0)
return -errno;
if (l < 0)
return -ERANGE;
@ -806,18 +818,7 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
return -EINVAL;
e += strspn(e, WHITESPACE);
for (i = 0; i < ELEMENTSOF(table); i++)
if (startswith(e, table[i].suffix)) {
multiplier = table[i].usec;
p = e + strlen(table[i].suffix);
break;
}
if (i >= ELEMENTSOF(table)) {
multiplier = default_unit;
p = e;
}
p = extract_multiplier(e, &multiplier);
something = true;

View File

@ -164,14 +164,14 @@ static int finish_item(
Hashmap *h,
sd_id128_t id,
const char *language,
char *payload) {
char *payload, size_t payload_size) {
_cleanup_free_ CatalogItem *i = NULL;
_cleanup_free_ char *combined = NULL, *prev = NULL;
int r;
_cleanup_free_ char *prev = NULL, *combined = NULL;
assert(h);
assert(payload);
assert(payload_size > 0);
i = new0(CatalogItem, 1);
if (!i)
@ -184,23 +184,25 @@ static int finish_item(
}
prev = hashmap_get(h, i);
/* Already have such an item, combine them */
if (prev) {
/* Already have such an item, combine them */
combined = combine_entries(payload, prev);
if (!combined)
return log_oom();
r = hashmap_update(h, i, combined);
if (r < 0)
return r;
combined = NULL;
/* A new item */
if (hashmap_update(h, i, combined) < 0)
return log_oom();
combined = NULL;
} else {
r = hashmap_put(h, i, payload);
if (r < 0)
return r;
/* A new item */
combined = memdup(payload, payload_size + 1);
if (!combined)
return log_oom();
if (hashmap_put(h, i, combined) < 0)
return log_oom();
i = NULL;
combined = NULL;
}
return 0;
@ -262,6 +264,7 @@ static int catalog_entry_lang(const char* filename, int line,
int catalog_import_file(Hashmap *h, const char *path) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *payload = NULL;
size_t payload_size = 0, payload_allocated = 0;
unsigned n = 0;
sd_id128_t id;
_cleanup_free_ char *deflang = NULL, *lang = NULL;
@ -283,8 +286,7 @@ int catalog_import_file(Hashmap *h, const char *path) {
for (;;) {
char line[LINE_MAX];
size_t a, b, c;
char *t;
size_t line_len;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
@ -323,17 +325,23 @@ int catalog_import_file(Hashmap *h, const char *path) {
if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) {
if (got_id) {
r = finish_item(h, id, lang ?: deflang, payload);
if (payload_size == 0) {
log_error("[%s:%u] No payload text.", path, n);
return -EINVAL;
}
r = finish_item(h, id, lang ?: deflang, payload, payload_size);
if (r < 0)
return r;
payload = NULL;
lang = mfree(lang);
payload_size = 0;
}
if (with_language) {
t = strstrip(line + 2 + 1 + 32 + 1);
char *t;
t = strstrip(line + 2 + 1 + 32 + 1);
r = catalog_entry_lang(path, n, t, deflang, &lang);
if (r < 0)
return r;
@ -343,9 +351,6 @@ int catalog_import_file(Hashmap *h, const char *path) {
empty_line = false;
id = jd;
if (payload)
payload[0] = '\0';
continue;
}
}
@ -356,34 +361,30 @@ int catalog_import_file(Hashmap *h, const char *path) {
return -EINVAL;
}
a = payload ? strlen(payload) : 0;
b = strlen(line);
c = a + (empty_line ? 1 : 0) + b + 1 + 1;
t = realloc(payload, c);
if (!t)
line_len = strlen(line);
if (!GREEDY_REALLOC(payload, payload_allocated,
payload_size + (empty_line ? 1 : 0) + line_len + 1 + 1))
return log_oom();
if (empty_line) {
t[a] = '\n';
memcpy(t + a + 1, line, b);
t[a+b+1] = '\n';
t[a+b+2] = 0;
} else {
memcpy(t + a, line, b);
t[a+b] = '\n';
t[a+b+1] = 0;
}
if (empty_line)
payload[payload_size++] = '\n';
memcpy(payload + payload_size, line, line_len);
payload_size += line_len;
payload[payload_size++] = '\n';
payload[payload_size] = '\0';
payload = t;
empty_line = false;
}
if (got_id) {
r = finish_item(h, id, lang ?: deflang, payload);
if (payload_size == 0) {
log_error("[%s:%u] No payload text.", path, n);
return -EINVAL;
}
r = finish_item(h, id, lang ?: deflang, payload, payload_size);
if (r < 0)
return r;
payload = NULL;
}
return 0;

View File

@ -103,6 +103,8 @@ static void test_catalog_import_one(void) {
assert_se(hashmap_size(h) == 1);
HASHMAP_FOREACH(payload, h, j) {
printf("expect: %s\n", expect);
printf("actual: %s\n", payload);
assert_se(streq(expect, payload));
}
}

View File

@ -323,26 +323,29 @@ static void test_hashmap_remove_value(void) {
_cleanup_hashmap_free_ Hashmap *m = NULL;
char *r;
r = hashmap_remove_value(NULL, "key 1", (void*) "val 1");
char val1[] = "val 1";
char val2[] = "val 2";
r = hashmap_remove_value(NULL, "key 1", val1);
assert_se(r == NULL);
m = hashmap_new(&string_hash_ops);
assert_se(m);
r = hashmap_remove_value(m, "key 1", (void*) "val 1");
r = hashmap_remove_value(m, "key 1", val1);
assert_se(r == NULL);
hashmap_put(m, "key 1", (void*) "val 1");
hashmap_put(m, "key 2", (void*) "val 2");
hashmap_put(m, "key 1", val1);
hashmap_put(m, "key 2", val2);
r = hashmap_remove_value(m, "key 1", (void*) "val 1");
r = hashmap_remove_value(m, "key 1", val1);
assert_se(streq(r, "val 1"));
r = hashmap_get(m, "key 2");
assert_se(streq(r, "val 2"));
assert_se(!hashmap_get(m, "key 1"));
r = hashmap_remove_value(m, "key 2", (void*) "val 1");
r = hashmap_remove_value(m, "key 2", val1);
assert_se(r == NULL);
r = hashmap_get(m, "key 2");