nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

commit f47d74f471b69da70d9c10b6b2856a3d051e3720
parent f243083f9231139da7708d0e1359a98e18e0e5bb
Author: William Casarin <jb55@jb55.com>
Date:   Fri,  9 Feb 2024 14:07:43 -0800

filter: add ndb_filter_clone

Clone filters when moving them into subscriptions. This will allow us to
fix the double free issue on the rust side.

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Msrc/nostrdb.c | 31++++++++++++++++++++++++++++++-
Msrc/nostrdb.h | 1+
2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/nostrdb.c b/src/nostrdb.c @@ -514,6 +514,35 @@ static inline int ndb_filter_elem_is_ptr(struct ndb_filter_field *field) { return field->elem_type == NDB_ELEMENT_STRING || field->elem_type == NDB_ELEMENT_ID; } +// Copy the filter +int ndb_filter_clone(struct ndb_filter *dst, struct ndb_filter *src) +{ + size_t src_size, elem_size, data_size; + + elem_size = src->elem_buf.end - src->elem_buf.start; + data_size = src->data_buf.end - src->data_buf.start; + src_size = data_size + elem_size; + + // let's only allow finalized filters to be cloned + if (!src || !src->finalized) + return 0; + + dst->elem_buf.start = malloc(src_size); + dst->elem_buf.end = dst->elem_buf.start + elem_size; + dst->elem_buf.p = dst->elem_buf.end; + + dst->data_buf.start = dst->elem_buf.start + elem_size; + dst->data_buf.end = dst->data_buf.start + data_size; + dst->data_buf.p = dst->data_buf.end; + + if (dst->elem_buf.start == NULL) + return 0; + + memcpy(dst->elem_buf.start, src->elem_buf.start, src_size); + + return 1; +} + // "Finalize" the filter. This resizes the allocated heap buffers so that they // are as small as possible. This also prevents new fields from being added int ndb_filter_end(struct ndb_filter *filter) @@ -1127,7 +1156,7 @@ static int ndb_filter_group_add(struct ndb_filter_group *group, if (group->num_filters + 1 > MAX_FILTERS) return 0; - memcpy(&group->filters[group->num_filters++], filter, sizeof(*filter)); + ndb_filter_clone(&group->filters[group->num_filters++], filter); return 1; } diff --git a/src/nostrdb.h b/src/nostrdb.h @@ -484,6 +484,7 @@ struct ndb_filter_elements *ndb_filter_current_element(struct ndb_filter *); int ndb_filter_start_field(struct ndb_filter *, enum ndb_filter_fieldtype); int ndb_filter_start_tag_field(struct ndb_filter *, char tag); int ndb_filter_matches(struct ndb_filter *, struct ndb_note *); +int ndb_filter_clone(struct ndb_filter *dst, struct ndb_filter *src); int ndb_filter_end(struct ndb_filter *); void ndb_filter_end_field(struct ndb_filter *); void ndb_filter_destroy(struct ndb_filter *);