Rizin
unix-like reverse engineering framework and cli tools
ubase64.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017-2021 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 /* Original code from:
5  * dmc - dynamic mail client -- author: pancake
6  * See LICENSE file for copyright and license details.
7  */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <rz_util.h>
13 
14 #define SZ 1024
15 static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
16 static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
17 
18 static void local_b64_encode(const ut8 in[3], char out[4], int len) {
19  if (len < 1) {
20  return;
21  }
22  out[0] = cb64[in[0] >> 2];
23  out[1] = cb64[((in[0] & 0x03) << 4) | ((len > 1) ? ((in[1] & 0xf0) >> 4) : 0)];
24  out[2] = (len > 1 ? cb64[((in[1] & 0x0f) << 2) | (len > 2 ? ((in[2] & 0xc0) >> 6) : 0)] : '=');
25  out[3] = (len > 2 ? cb64[in[2] & 0x3f] : '=');
26 }
27 
28 static int local_b64_decode(const char in[4], ut8 out[3]) {
29  int len = 3;
30  ut8 i, v[4] = { 0 };
31  for (i = 0; i < 4; i++) {
32  if (in[i] < 43 || in[i] > 122) {
33  return -1;
34  }
35  v[i] = cd64[in[i] - 43];
36  if (v[i] == '$') {
37  len = i ? i - 1 : -1;
38  break;
39  }
40  v[i] -= 62;
41  }
42  out[0] = v[0] << 2 | v[1] >> 4;
43  out[1] = v[1] << 4 | v[2] >> 2;
44  out[2] = ((v[2] << 6) & 0xc0) | v[3];
45  return len;
46 }
47 
48 RZ_API int rz_base64_decode(ut8 *bout, const char *bin, int len) {
49  int in, out;
50  if (len < 0) {
51  len = strlen(bin);
52  }
53  for (in = out = 0; in + 3 < len; in += 4) {
54  int ret = local_b64_decode(bin + in, bout + out);
55  if (ret < 1) {
56  return -1;
57  }
58  out += ret;
59  }
60  bout[out] = 0;
61  /* XXX this makes no sense, just return out? */
62  return (in != out) ? out : -1;
63 }
64 
65 RZ_API ut8 *rz_base64_decode_dyn(const char *in, int len) {
66  ut8 *bout;
67  if (!in) {
68  return NULL;
69  }
70  if (len < 0) {
71  len = strlen(in) + 1;
72  }
73  bout = calloc(4, len + 1);
74  if (rz_base64_decode(bout, in, len) == -1) {
75  free(bout);
76  return NULL;
77  }
78  return bout;
79 }
80 
81 RZ_API size_t rz_base64_encode(char *bout, const ut8 *bin, size_t sz) {
83  size_t in, out;
84  for (in = out = 0; in < sz; in += 3, out += 4) {
85  local_b64_encode(bin + in, (char *)bout + out,
86  (sz - in) > 3 ? 3 : sz - in);
87  }
88  bout[out] = 0;
89  return out;
90 }
91 
92 RZ_API char *rz_base64_encode_dyn(const ut8 *bin, size_t sz) {
94  if (sz > (SIZE_MAX - 2) / 4) {
95  return NULL;
96  }
97  const size_t osz = (sz * 4) + 2;
98  char *bout = malloc(osz);
99  if (!bout) {
100  return NULL;
101  }
102  rz_base64_encode(bout, bin, sz);
103  return bout;
104 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define RZ_API
#define NULL
Definition: cris-opc.c:27
const char * v
Definition: dsignal.c:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
uint8_t ut8
Definition: lh5801.h:11
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define SIZE_MAX
Definition: malloc.c:26
static const char cd64[]
Definition: ubase64.c:16
static int local_b64_decode(const char in[4], ut8 out[3])
Definition: ubase64.c:28
static const char cb64[]
Definition: ubase64.c:15
RZ_API size_t rz_base64_encode(char *bout, const ut8 *bin, size_t sz)
Definition: ubase64.c:81
RZ_API char * rz_base64_encode_dyn(const ut8 *bin, size_t sz)
Definition: ubase64.c:92
static void local_b64_encode(const ut8 in[3], char out[4], int len)
Definition: ubase64.c:18
RZ_API ut8 * rz_base64_decode_dyn(const char *in, int len)
Definition: ubase64.c:65
RZ_API int rz_base64_decode(ut8 *bout, const char *bin, int len)
Definition: ubase64.c:48