From a7e81a1b18c9e9d124a4ea917c8015af62584abb Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 28 May 2020 17:48:23 -0400 Subject: [PATCH 20/33] Introduce base2bin() - a helper to convert tag array of base64 strings This will convert a tag of base64 strings to a binary array, similar to how hex2bin() works. It supports variable sized strings, and will determine the maximum string length and build the output array based on that. Signed-off-by: Jes Sorensen --- lib/rpmfi.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/lib/rpmfi.c b/lib/rpmfi.c index 689ead2c5..8c69d3e40 100644 --- a/lib/rpmfi.c +++ b/lib/rpmfi.c @@ -19,6 +19,7 @@ #include "lib/fsm.h" /* rpmpsm stuff for now */ #include "lib/rpmug.h" #include "rpmio/rpmio_internal.h" /* fdInit/FiniDigest */ +#include "rpmio/rpmbase64.h" #include "debug.h" @@ -1520,6 +1521,63 @@ static uint8_t *hex2bin(Header h, rpmTagVal tag, rpm_count_t num, size_t len) return bin; } +/* + * Convert a tag of base64 strings to binary presentation. + * This handles variable length strings by finding the longest string + * before building the output array. Dummy strings in the tag should be + * added as '\0' + */ +static uint8_t *base2bin(Header h, rpmTagVal tag, rpm_count_t num, int *len) +{ + struct rpmtd_s td; + uint8_t *bin = NULL, *t = NULL; + size_t maxlen = 0; + int status, i= 0; + void **arr = xmalloc(num * sizeof(void *)); + size_t *lengths = xcalloc(num, sizeof(size_t)); + const char *s; + + if (headerGet(h, tag, &td, HEADERGET_MINMEM) && rpmtdCount(&td) != num) + goto out; + + while ((s = rpmtdNextString(&td))) { + /* Insert a dummy entry for empty strings */ + if (*s == '\0') { + arr[i++] = NULL; + continue; + } + status = rpmBase64Decode(s, &arr[i], &lengths[i]); + if (lengths[i] > maxlen) + maxlen = lengths[i]; + if (status) { + rpmlog(RPMLOG_DEBUG, _("%s: base64 decode failed, len %li\n"), + __func__, lengths[i]); + goto out; + } + i++; + } + + if (maxlen) { + rpmlog(RPMLOG_DEBUG, _("%s: base64 decode success, len %li\n"), + __func__, maxlen); + + t = bin = xcalloc(num, maxlen); + + for (i = 0; i < num; i++) { + memcpy(t, arr[i], lengths[i]); + free(arr[i]); + t += maxlen; + } + *len = maxlen; + } + out: + free(arr); + free(lengths); + rpmtdFreeData(&td); + + return bin; +} + static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags) { headerGetFlags scareFlags = (flags & RPMFI_KEEPHEADER) ? -- 2.27.0