Coverage Report

Created: 2026-01-21 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/lib/base64.c
Line
Count
Source
1
// SPDX-License-Identifier: NONE
2
/*
3
 * This is part of the libb64 project, and has been placed in the public domain.
4
 * For details, see http://sourceforge.net/projects/libb64
5
 */
6
7
#ifdef HAVE_CONFIG_H
8
#include "config.h"
9
#endif
10
11
#include "base64.h"
12
13
static const int CHARS_PER_LINE = 72;
14
static const char *ENCODING =
15
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
16
17
void base64_init_encodestate(struct base64_encodestate *state_in)
18
0
{
19
0
  state_in->step = step_A;
20
0
  state_in->result = 0;
21
0
  state_in->stepcount = 0;
22
0
}
23
24
char base64_encode_value(char value_in)
25
0
{
26
0
  if (value_in > 63)
27
0
    return '=';
28
0
  return ENCODING[(int)value_in];
29
0
}
30
31
int base64_encode_block(const char *plaintext_in, int length_in, char *code_out,
32
      struct base64_encodestate *state_in)
33
0
{
34
0
  const char *plainchar = plaintext_in;
35
0
  const char *const plaintextend = plaintext_in + length_in;
36
0
  char *codechar = code_out;
37
0
  char result;
38
0
  char fragment;
39
40
0
  result = state_in->result;
41
42
0
  switch (state_in->step) {
43
0
    while (1) {
44
0
      case step_A:
45
0
        if (plainchar == plaintextend) {
46
0
          state_in->result = result;
47
0
          state_in->step = step_A;
48
0
          return codechar - code_out;
49
0
        }
50
0
        fragment = *plainchar++;
51
0
        result = (fragment & 0x0fc) >> 2;
52
0
        *codechar++ = base64_encode_value(result);
53
0
        result = (fragment & 0x003) << 4;
54
        /* fall through */
55
0
      case step_B:
56
0
        if (plainchar == plaintextend) {
57
0
          state_in->result = result;
58
0
          state_in->step = step_B;
59
0
          return codechar - code_out;
60
0
        }
61
0
        fragment = *plainchar++;
62
0
        result |= (fragment & 0x0f0) >> 4;
63
0
        *codechar++ = base64_encode_value(result);
64
0
        result = (fragment & 0x00f) << 2;
65
        /* fall through */
66
0
      case step_C:
67
0
        if (plainchar == plaintextend) {
68
0
          state_in->result = result;
69
0
          state_in->step = step_C;
70
0
          return codechar - code_out;
71
0
        }
72
0
        fragment = *plainchar++;
73
0
        result |= (fragment & 0x0c0) >> 6;
74
0
        *codechar++ = base64_encode_value(result);
75
0
        result  = (fragment & 0x03f) >> 0;
76
0
        *codechar++ = base64_encode_value(result);
77
78
0
        ++(state_in->stepcount);
79
0
        if (state_in->stepcount == CHARS_PER_LINE/4) {
80
0
          *codechar++ = '\n';
81
0
          state_in->stepcount = 0;
82
0
        }
83
0
    }
84
0
  }
85
  /* control should not reach here */
86
0
  return codechar - code_out;
87
0
}
88
89
int base64_encode_blockend(char *code_out, struct base64_encodestate *state_in)
90
0
{
91
0
  char *codechar = code_out;
92
93
0
  switch (state_in->step) {
94
0
  case step_B:
95
0
    *codechar++ = base64_encode_value(state_in->result);
96
0
    *codechar++ = '=';
97
0
    *codechar++ = '=';
98
0
    break;
99
0
  case step_C:
100
0
    *codechar++ = base64_encode_value(state_in->result);
101
0
    *codechar++ = '=';
102
0
    break;
103
0
  case step_A:
104
0
    break;
105
0
  }
106
0
  *codechar++ = '\n';
107
108
0
  return codechar - code_out;
109
0
}
110
111
112
signed char base64_decode_value(signed char value_in)
113
0
{
114
0
  static const signed char decoding[] = {
115
0
    62, -1, -1, -1, 63, 52, 53, 54,
116
0
    55, 56, 57, 58, 59, 60, 61, -1,
117
0
    -1, -1, -2, -1, -1, -1, 0, 1,
118
0
    2,  3, 4, 5, 6, 7, 8, 9,
119
0
    10, 11, 12, 13, 14, 15, 16, 17,
120
0
    18, 19, 20, 21, 22, 23, 24, 25,
121
0
    -1, -1, -1, -1, -1, -1, 26, 27,
122
0
    28, 29, 30, 31, 32, 33, 34, 35,
123
0
    36, 37, 38, 39, 40, 41, 42, 43,
124
0
    44, 45, 46, 47, 48, 49, 50, 51
125
0
  };
126
0
  value_in -= 43;
127
0
  if (value_in < 0 || value_in >= 80)
128
0
    return -1;
129
0
  return decoding[(int)value_in];
130
0
}
131
132
void base64_init_decodestate(struct base64_decodestate *state_in)
133
0
{
134
0
  state_in->step = step_a;
135
0
  state_in->plainchar = 0;
136
0
}
137
138
int base64_decode_block(const char *code_in, int length_in, char *plaintext_out,
139
      struct base64_decodestate *state_in)
140
0
{
141
0
  const char *codec = code_in;
142
0
  char *plainc = plaintext_out;
143
0
  signed char fragmt;
144
145
0
  *plainc = state_in->plainchar;
146
147
0
  switch (state_in->step) {
148
0
    while (1) {
149
0
      case step_a:
150
0
        do {
151
0
          if (codec == code_in+length_in) {
152
0
            state_in->step = step_a;
153
0
            state_in->plainchar = *plainc;
154
0
            return plainc - plaintext_out;
155
0
          }
156
0
          fragmt = base64_decode_value(*codec++);
157
0
        } while (fragmt < 0);
158
0
        *plainc = (fragmt & 0x03f) << 2;
159
        /* fall through */
160
0
      case step_b:
161
0
        do {
162
0
          if (codec == code_in+length_in) {
163
0
            state_in->step = step_b;
164
0
            state_in->plainchar = *plainc;
165
0
            return plainc - plaintext_out;
166
0
          }
167
0
          fragmt = base64_decode_value(*codec++);
168
0
        } while (fragmt < 0);
169
0
        *plainc++ |= (fragmt & 0x030) >> 4;
170
0
        *plainc = (fragmt & 0x00f) << 4;
171
        /* fall through */
172
0
      case step_c:
173
0
        do {
174
0
          if (codec == code_in+length_in) {
175
0
            state_in->step = step_c;
176
0
            state_in->plainchar = *plainc;
177
0
            return plainc - plaintext_out;
178
0
          }
179
0
          fragmt = base64_decode_value(*codec++);
180
0
        } while (fragmt < 0);
181
0
        *plainc++ |= (fragmt & 0x03c) >> 2;
182
0
        *plainc = (fragmt & 0x003) << 6;
183
        /* fall through */
184
0
      case step_d:
185
0
        do {
186
0
          if (codec == code_in+length_in) {
187
0
            state_in->step = step_d;
188
0
            state_in->plainchar = *plainc;
189
0
            return plainc - plaintext_out;
190
0
          }
191
0
          fragmt = base64_decode_value(*codec++);
192
0
        } while (fragmt < 0);
193
0
        *plainc++   |= (fragmt & 0x03f);
194
0
    }
195
0
  }
196
  /* control should not reach here */
197
0
  return plainc - plaintext_out;
198
0
}