Initial rework on TLV to avoid mem leaks

This commit is contained in:
Jean-Michel Picod 2023-01-06 13:03:10 +01:00
parent e3aa67fe5e
commit 80a4698a7f
2 changed files with 78 additions and 14 deletions

View file

@ -44,19 +44,6 @@
// const typeof( ((type *)0)->member ) *__mptr = (ptr);
// (type *)( (char *)__mptr - offsetof(type,member) );})
struct tlvdb {
struct tlv tag;
struct tlvdb *next;
struct tlvdb *parent;
struct tlvdb *children;
};
struct tlvdb_root {
struct tlvdb db;
size_t len;
unsigned char buf[0];
};
static tlv_tag_t tlv_parse_tag(const unsigned char **buf, size_t *len) {
tlv_tag_t tag;
@ -212,6 +199,7 @@ struct tlvdb *tlvdb_parse(const unsigned char *buf, size_t len) {
err:
tlvdb_free(&root->db);
free(root);
return NULL;
}
@ -248,9 +236,53 @@ struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len) {
err:
tlvdb_free(&root->db);
free(root);
return NULL;
}
bool tlvdb_parse_root(struct tlvdb_root *root) {
if (root == NULL || root->len == 0) {
return false;
}
const uint8_t *tmp;
size_t left;
tmp = root->buf;
left = root->len;
if (tlvdb_parse_one(&root->db, NULL, &tmp, &left) == true) {
if (left == 0) {
return true;
}
}
return false;
}
bool tlvdb_parse_root_multi(struct tlvdb_root *root) {
if (root == NULL || root->len == 0) {
return false;
}
const uint8_t *tmp;
size_t left;
tmp = root->buf;
left = root->len;
if (tlvdb_parse_one(&root->db, NULL, &tmp, &left) == true) {
while (left > 0) {
struct tlvdb *db = calloc(1, sizeof(*db));
if (tlvdb_parse_one(db, NULL, &tmp, &left) == true) {
tlvdb_add(&root->db, db);
} else {
free(db);
return false;
}
}
return true;
}
return false;
}
struct tlvdb *tlvdb_fixed(tlv_tag_t tag, size_t len, const unsigned char *value) {
struct tlvdb_root *root = calloc(1, sizeof(*root) + len);
@ -291,6 +323,21 @@ void tlvdb_free(struct tlvdb *tlvdb) {
}
}
void tlvdb_root_free(struct tlvdb_root *root) {
if (root == NULL) {
return;
}
if (root->db.children) {
tlvdb_free(root->db.children);
root->db.children = NULL;
}
if (root->db.next) {
tlvdb_free(root->db.next);
root->db.next = NULL;
}
free(root);
}
struct tlvdb *tlvdb_find_next(struct tlvdb *tlvdb, tlv_tag_t tag) {
if (!tlvdb)
return NULL;

View file

@ -31,14 +31,31 @@ struct tlv {
const unsigned char *value;
};
struct tlvdb;
struct tlvdb {
struct tlv tag;
struct tlvdb *next;
struct tlvdb *parent;
struct tlvdb *children;
};
struct tlvdb_root {
struct tlvdb db;
size_t len;
unsigned char buf[0];
};
typedef void (*tlv_cb)(void *data, const struct tlv *tlv, int level, bool is_leaf);
struct tlvdb *tlvdb_fixed(tlv_tag_t tag, size_t len, const unsigned char *value);
struct tlvdb *tlvdb_external(tlv_tag_t tag, size_t len, const unsigned char *value);
struct tlvdb *tlvdb_parse(const unsigned char *buf, size_t len);
struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len);
bool tlvdb_parse_root(struct tlvdb_root *root);
bool tlvdb_parse_root_multi(struct tlvdb_root *root);
void tlvdb_free(struct tlvdb *tlvdb);
void tlvdb_root_free(struct tlvdb_root *root);
struct tlvdb *tlvdb_elm_get_next(struct tlvdb *tlvdb);
struct tlvdb *tlvdb_elm_get_children(struct tlvdb *tlvdb);