summaryrefslogtreecommitdiffstats
path: root/epan/tvbuff_base64.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/tvbuff_base64.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/tvbuff_base64.c')
-rw-r--r--epan/tvbuff_base64.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/epan/tvbuff_base64.c b/epan/tvbuff_base64.c
new file mode 100644
index 00000000..2b2637c2
--- /dev/null
+++ b/epan/tvbuff_base64.c
@@ -0,0 +1,229 @@
+/* tvbuff_base64.c
+ * Base-64 tvbuff implementation (based on real tvb)
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <epan/tvbuff.h>
+#include "proto.h"
+
+/* Copy of glib function modified for base64uri */
+
+static const unsigned char mime_base64uri_rank[256] = {
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255, 255,255,63,255,255,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255, 63,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+};
+ /**
+ * Copy of glib function modified for base64uri
+ * g_base64uri_decode_step: (skip)
+ * @in: (array length=len) (element-type guint8): binary input data
+ * @len: max length of @in data to decode
+ * @out: (out caller-allocates) (array) (element-type guint8): output buffer
+ * @state: (inout): Saved state between steps, initialize to 0
+ * @save: (inout): Saved state between steps, initialize to 0
+ *
+ * Incrementally decode a sequence of binary data from its Base-64 stringified
+ * representation. By calling this function multiple times you can convert
+ * data in chunks to avoid having to have the full encoded data in memory.
+ *
+ * The output buffer must be large enough to fit all the data that will
+ * be written to it. Since base64 encodes 3 bytes in 4 chars you need
+ * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero
+ * state).
+ *
+ * Returns: The number of bytes of output that was written
+ *
+ * Since: 2.12
+ **/
+static gsize
+g_base64uri_decode_step(const gchar* in,
+ gsize len,
+ guchar* out,
+ gint* state,
+ guint* save)
+{
+ const guchar* inptr;
+ guchar* outptr;
+ const guchar* inend;
+ guchar c, rank;
+ guchar last[2];
+ unsigned int v;
+ int i;
+
+ g_return_val_if_fail(in != NULL || len == 0, 0);
+ g_return_val_if_fail(out != NULL, 0);
+ g_return_val_if_fail(state != NULL, 0);
+ g_return_val_if_fail(save != NULL, 0);
+
+ if (len == 0)
+ return 0;
+
+ inend = (const guchar*)in + len;
+ outptr = out;
+
+ /* convert 4 base64 bytes to 3 normal bytes */
+ v = *save;
+ i = *state;
+
+ last[0] = last[1] = 0;
+
+ /* we use the sign in the state to determine if we got a padding character
+ in the previous sequence */
+ if (i < 0)
+ {
+ i = -i;
+ last[0] = '=';
+ }
+
+ inptr = (const guchar*)in;
+ while (inptr < inend)
+ {
+ c = *inptr++;
+ rank = mime_base64uri_rank[c];
+ if (rank != 0xff)
+ {
+ last[1] = last[0];
+ last[0] = c;
+ v = (v << 6) | rank;
+ i++;
+ if (i == 4)
+ {
+ *outptr++ = v >> 16;
+ if (last[1] != '=')
+ *outptr++ = v >> 8;
+ if (last[0] != '=')
+ *outptr++ = v;
+ i = 0;
+ }
+ }
+ }
+
+ *save = v;
+ *state = last[0] == '=' ? -i : i;
+
+ return outptr - out;
+}
+ /**
+ * Copy of glib function modified for base64uri
+ * g_base64uri_decode:
+ * @text: (not nullable): zero-terminated string with base64 text to decode
+ * @out_len: (out): The length of the decoded data is written here
+ *
+ * Decode a sequence of Base-64 encoded text into binary data. Note
+ * that the returned binary data is not necessarily zero-terminated,
+ * so it should not be used as a character string.
+ *
+ * Returns: (transfer full) (array length=out_len) (element-type guint8):
+ * newly allocated buffer containing the binary data
+ * that @text represents. The returned buffer must
+ * be freed with g_free().
+ *
+ * Since: 2.12
+ */
+static guchar*
+g_base64uri_decode(const gchar* text,
+ gsize* out_len)
+{
+ guchar* ret;
+ gsize input_length;
+ gint state = 0;
+ guint save = 0;
+
+ g_return_val_if_fail(text != NULL, NULL);
+ g_return_val_if_fail(out_len != NULL, NULL);
+
+ input_length = strlen(text);
+
+ /* We can use a smaller limit here, since we know the saved state is 0,
+ +1 used to avoid calling g_malloc0(0), and hence returning NULL */
+ ret = (guchar * )g_malloc0((input_length / 4) * 3 + 1);
+
+ *out_len = g_base64uri_decode_step(text, input_length, ret, &state, &save);
+
+ return ret;
+}
+
+tvbuff_t *
+base64_to_tvb(tvbuff_t *parent, const char *base64)
+{
+ tvbuff_t *tvb;
+ char *data;
+ gsize len;
+
+ data = g_base64_decode(base64, &len);
+ tvb = tvb_new_child_real_data(parent, (const guint8 *)data, (gint)len, (gint)len);
+
+ tvb_set_free_cb(tvb, g_free);
+
+ return tvb;
+}
+
+tvbuff_t*
+base64_tvb_to_new_tvb(tvbuff_t* parent, int offset, int length)
+{
+ tvbuff_t* tvb;
+ char* data, *tmp;
+ gsize len;
+
+ tmp = tvb_get_string_enc(NULL, parent, offset, length, ENC_ASCII);
+ data = g_base64_decode(tmp, &len);
+ wmem_free(NULL, tmp);
+
+ tvb = tvb_new_child_real_data(parent, (const guint8*)data, (gint)len, (gint)len);
+
+ tvb_set_free_cb(tvb, g_free);
+
+ return tvb;
+}
+
+tvbuff_t*
+base64uri_tvb_to_new_tvb(tvbuff_t* parent, int offset, int length)
+{
+ tvbuff_t* tvb;
+ char* data, *tmp;
+ gsize len = 0;
+
+ tmp = tvb_get_string_enc(NULL, parent, offset, length, ENC_ASCII);
+ data = g_base64uri_decode(tmp, &len);
+ wmem_free(NULL, tmp);
+
+ tvb = tvb_new_child_real_data(parent, (const guint8*)data, (gint)len, (gint)len);
+
+ tvb_set_free_cb(tvb, g_free);
+
+ return tvb;
+}
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */