Coverage Report

Created: 2026-09-14 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libplist/src/base64.c
Line
Count
Source
1
/*
2
 * base64.c
3
 * base64 encode/decode implementation
4
 *
5
 * Copyright (c) 2011 Nikias Bassen, All Rights Reserved.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
 */
21
#include <string.h>
22
#include "base64.h"
23
24
static const char base64_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
25
static const char base64_pad = '=';
26
27
static const signed char base64_table[256] = {
28
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
29
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
30
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
31
  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
32
  -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
33
  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
34
  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
35
  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
36
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
44
};
45
46
size_t base64encode(char *outbuf, const unsigned char *buf, size_t size)
47
0
{
48
0
  if (!outbuf || !buf || (size <= 0)) {
49
0
    return 0;
50
0
  }
51
52
0
  size_t n = 0;
53
0
  size_t m = 0;
54
0
  unsigned char input[3];
55
0
  unsigned int output[4];
56
0
  while (n < size) {
57
0
    input[0] = buf[n];
58
0
    input[1] = (n+1 < size) ? buf[n+1] : 0;
59
0
    input[2] = (n+2 < size) ? buf[n+2] : 0;
60
0
    output[0] = input[0] >> 2;
61
0
    output[1] = ((input[0] & 3) << 4) + (input[1] >> 4);
62
0
    output[2] = ((input[1] & 15) << 2) + (input[2] >> 6);
63
0
    output[3] = input[2] & 63;
64
0
    outbuf[m++] = base64_str[(int)output[0]];
65
0
    outbuf[m++] = base64_str[(int)output[1]];
66
0
    outbuf[m++] = (n+1 < size) ? base64_str[(int)output[2]] : base64_pad;
67
0
    outbuf[m++] = (n+2 < size) ? base64_str[(int)output[3]] : base64_pad;
68
0
    n+=3;
69
0
  }
70
0
  outbuf[m] = 0; // 0-termination!
71
0
  return m;
72
0
}
73
74
unsigned char *base64decode(const char *buf, size_t *size)
75
0
{
76
0
  if (!buf || !size) return NULL;
77
0
  size_t len = (*size > 0) ? *size : strlen(buf);
78
0
  if (len <= 0) return NULL;
79
0
  unsigned char *outbuf = (unsigned char*)malloc((len/4)*3+3);
80
0
  if (!outbuf) return NULL;
81
0
  const char *ptr = buf;
82
0
  size_t p = 0;
83
0
  int wv, w1, w2, w3, w4;
84
0
  int tmpval[4];
85
0
  int tmpcnt = 0;
86
87
0
  do {
88
0
    while (ptr < buf+len && (*ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '\r')) {
89
0
      ptr++;
90
0
    }
91
0
    if (*ptr == '\0' || ptr >= buf+len) {
92
0
      break;
93
0
    }
94
0
    if ((wv = base64_table[(int)(unsigned char)*ptr++]) == -1) {
95
0
      continue;
96
0
    }
97
0
    tmpval[tmpcnt++] = wv;
98
0
    if (tmpcnt == 4) {
99
0
      tmpcnt = 0;
100
0
      w1 = tmpval[0];
101
0
      w2 = tmpval[1];
102
0
      w3 = tmpval[2];
103
0
      w4 = tmpval[3];
104
105
0
      if (w1 >= 0 && w2 >= 0) {
106
0
        outbuf[p++] = (unsigned char)(((w1 << 2) + (w2 >> 4)) & 0xFF);
107
0
      }
108
0
      if (w2 >= 0 && w3 >= 0) {
109
0
        outbuf[p++] = (unsigned char)(((w2 << 4) + (w3 >> 2)) & 0xFF);
110
0
      }
111
0
      if (w3 >= 0 && w4 >= 0) {
112
0
        outbuf[p++] = (unsigned char)(((w3 << 6) + w4) & 0xFF);
113
0
      }
114
0
    }
115
0
  } while (1);
116
117
0
  outbuf[p] = 0;
118
0
  *size = p;
119
0
  return outbuf;
120
0
}