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