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