From a7e81a1b18c9e9d124a4ea917c8015af62584abb Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
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 <jsorensen@fb.com>
---
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