This is an automated email from the git hooks/post-receive script. guillem pushed a commit to branch main in repository dpkg.
View the commit online: https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=f382029ba92a2b626acc243f2bba278395df5e03 commit f382029ba92a2b626acc243f2bba278395df5e03 Author: Guillem Jover <guil...@debian.org> AuthorDate: Sat Apr 13 22:39:44 2024 +0200 libdpkg: Add new varbuf prefix and suffix handling functions These add checks for whether a prefix or a suffix is present in a varbuf, and functions to trim varbuf or repeated character prefixes. --- lib/dpkg/libdpkg.map | 4 ++++ lib/dpkg/t/t-varbuf.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++- lib/dpkg/varbuf.c | 46 ++++++++++++++++++++++++++++++++++++ lib/dpkg/varbuf.h | 5 ++++ 4 files changed, 119 insertions(+), 1 deletion(-) diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map index b1c998381..db6271114 100644 --- a/lib/dpkg/libdpkg.map +++ b/lib/dpkg/libdpkg.map @@ -123,6 +123,10 @@ LIBDPKG_PRIVATE { varbuf_map_char; varbuf_add_buf; varbuf_add_dir; + varbuf_has_prefix; + varbuf_has_suffix; + varbuf_trim_varbuf_prefix; + varbuf_trim_char_prefix; varbuf_printf; varbuf_vprintf; varbuf_detach; diff --git a/lib/dpkg/t/t-varbuf.c b/lib/dpkg/t/t-varbuf.c index 8ad3bbc7e..1b9a23bd6 100644 --- a/lib/dpkg/t/t-varbuf.c +++ b/lib/dpkg/t/t-varbuf.c @@ -403,6 +403,67 @@ test_varbuf_str(void) varbuf_destroy(&vb); } +static void +test_varbuf_has(void) +{ + struct varbuf vb = VARBUF_OBJECT; + struct varbuf vb_prefix = VARBUF_OBJECT; + struct varbuf vb_suffix = VARBUF_OBJECT; + + varbuf_set_str(&vb_prefix, "prefix"); + varbuf_set_str(&vb_suffix, "suffix"); + + varbuf_set_str(&vb, "prefix and some text"); + test_pass(varbuf_has_prefix(&vb, &vb_prefix)); + test_fail(varbuf_has_prefix(&vb, &vb_suffix)); + test_fail(varbuf_has_suffix(&vb, &vb_prefix)); + test_fail(varbuf_has_suffix(&vb, &vb_suffix)); + + varbuf_set_str(&vb, "some text with suffix"); + test_fail(varbuf_has_prefix(&vb, &vb_prefix)); + test_fail(varbuf_has_prefix(&vb, &vb_suffix)); + test_fail(varbuf_has_suffix(&vb, &vb_prefix)); + test_pass(varbuf_has_suffix(&vb, &vb_suffix)); + + varbuf_set_str(&vb, "prefix and some text with suffix"); + test_pass(varbuf_has_prefix(&vb, &vb_prefix)); + test_fail(varbuf_has_prefix(&vb, &vb_suffix)); + test_fail(varbuf_has_suffix(&vb, &vb_prefix)); + test_pass(varbuf_has_suffix(&vb, &vb_suffix)); + + varbuf_destroy(&vb_prefix); + varbuf_destroy(&vb_suffix); + varbuf_destroy(&vb); +} + +static void +test_varbuf_trim(void) +{ + struct varbuf vb = VARBUF_OBJECT; + struct varbuf vb_prefix = VARBUF_OBJECT; + struct varbuf vb_suffix = VARBUF_OBJECT; + + varbuf_set_str(&vb_prefix, "prefix"); + varbuf_set_str(&vb_suffix, "suffix"); + + varbuf_set_str(&vb, "some text"); + varbuf_trim_varbuf_prefix(&vb, &vb_prefix); + varbuf_trim_char_prefix(&vb, 'a'); + test_str(vb.buf, ==, "some text"); + + varbuf_set_str(&vb, "prefix and some text"); + varbuf_trim_varbuf_prefix(&vb, &vb_prefix); + test_str(vb.buf, ==, " and some text"); + + varbuf_set_str(&vb, " and some text"); + varbuf_trim_char_prefix(&vb, ' '); + test_str(vb.buf, ==, "and some text"); + + varbuf_destroy(&vb_prefix); + varbuf_destroy(&vb_suffix); + varbuf_destroy(&vb); +} + static void test_varbuf_printf(void) { @@ -516,7 +577,7 @@ test_varbuf_detach(void) TEST_ENTRY(test) { - test_plan(172); + test_plan(187); test_varbuf_init(); test_varbuf_prealloc(); @@ -533,6 +594,8 @@ TEST_ENTRY(test) test_varbuf_add_dir(); test_varbuf_end_str(); test_varbuf_str(); + test_varbuf_has(); + test_varbuf_trim(); test_varbuf_printf(); test_varbuf_reset(); test_varbuf_snapshot(); diff --git a/lib/dpkg/varbuf.c b/lib/dpkg/varbuf.c index f41f495c9..3fbc10344 100644 --- a/lib/dpkg/varbuf.c +++ b/lib/dpkg/varbuf.c @@ -176,6 +176,52 @@ varbuf_add_buf(struct varbuf *v, const void *s, size_t size) v->buf[v->used] = '\0'; } +bool +varbuf_has_prefix(struct varbuf *v, struct varbuf *prefix) +{ + if (prefix->used > v->used) + return false; + + return strncmp(v->buf, prefix->buf, prefix->used) == 0; +} + +bool +varbuf_has_suffix(struct varbuf *v, struct varbuf *suffix) +{ + const char *slice = v->buf + v->used - suffix->used; + + if (suffix->used > v->used) + return false; + + return strcmp(slice, suffix->buf) == 0; +} + +void +varbuf_trim_varbuf_prefix(struct varbuf *v, struct varbuf *prefix) +{ + if (!varbuf_has_prefix(v, prefix)) + return; + + memmove(v->buf, v->buf + prefix->used, v->used - prefix->used); + varbuf_trunc(v, v->used - prefix->used); +} + +void +varbuf_trim_char_prefix(struct varbuf *v, int prefix) +{ + const char *str = v->buf; + size_t len = v->used; + + while (str[0] == prefix && len > 0) { + str++; + len--; + } + if (str != v->buf) { + memmove(v->buf, str, len); + varbuf_trunc(v, len); + } +} + int varbuf_vprintf(struct varbuf *v, const char *fmt, va_list args) { diff --git a/lib/dpkg/varbuf.h b/lib/dpkg/varbuf.h index 52e748bed..99d9f0691 100644 --- a/lib/dpkg/varbuf.h +++ b/lib/dpkg/varbuf.h @@ -99,6 +99,11 @@ void varbuf_map_char(struct varbuf *v, int c_src, int c_dst); void varbuf_add_dir(struct varbuf *v, const char *dirname); void varbuf_add_buf(struct varbuf *v, const void *s, size_t size); +bool varbuf_has_prefix(struct varbuf *v, struct varbuf *prefix); +bool varbuf_has_suffix(struct varbuf *v, struct varbuf *suffix); +void varbuf_trim_varbuf_prefix(struct varbuf *v, struct varbuf *prefix); +void varbuf_trim_char_prefix(struct varbuf *v, int prefix); + int varbuf_printf(struct varbuf *v, const char *fmt, ...) DPKG_ATTR_PRINTF(2); int varbuf_vprintf(struct varbuf *v, const char *fmt, va_list va) DPKG_ATTR_VPRINTF(2); -- Dpkg.Org's dpkg