• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.73
/src/lib/utils/codec_base.h
1
/*
2
* Base Encoding and Decoding
3
* (C) 2018 Erwan Chaussy
4
* (C) 2018 Jack Lloyd
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#ifndef BOTAN_BASE_CODEC_H_
10
#define BOTAN_BASE_CODEC_H_
11

12
#include <botan/exceptn.h>
13
#include <botan/secmem.h>
14
#include <string>
15
#include <vector>
16

17
namespace Botan {
18

19
/**
20
* Perform encoding using the base provided
21
* @param base object giving access to the encodings specifications
22
* @param output an array of at least base.encode_max_output bytes
23
* @param input is some binary data
24
* @param input_length length of input in bytes
25
* @param input_consumed is an output parameter which says how many
26
*        bytes of input were actually consumed. If less than
27
*        input_length, then the range input[consumed:length]
28
*        should be passed in later along with more input.
29
* @param final_inputs true iff this is the last input, in which case
30
         padding chars will be applied if needed
31
* @return number of bytes written to output
32
*/
33
template <class Base>
34
size_t base_encode(
2,162✔
35
   Base&& base, char output[], const uint8_t input[], size_t input_length, size_t& input_consumed, bool final_inputs) {
36
   input_consumed = 0;
2,162✔
37

38
   const size_t encoding_bytes_in = base.encoding_bytes_in();
2,162✔
39
   const size_t encoding_bytes_out = base.encoding_bytes_out();
2,162✔
40

41
   size_t input_remaining = input_length;
2,162✔
42
   size_t output_produced = 0;
2,162✔
43

44
   while(input_remaining >= encoding_bytes_in) {
581,426✔
45
      base.encode(output + output_produced, input + input_consumed);
579,264✔
46

47
      input_consumed += encoding_bytes_in;
579,264✔
48
      output_produced += encoding_bytes_out;
579,264✔
49
      input_remaining -= encoding_bytes_in;
579,264✔
50
   }
51

52
   if(final_inputs && input_remaining) {
2,162✔
53
      std::vector<uint8_t> remainder(encoding_bytes_in, 0);
1,875✔
54
      for(size_t i = 0; i != input_remaining; ++i) {
4,719✔
55
         remainder[i] = input[input_consumed + i];
2,844✔
56
      }
57

58
      base.encode(output + output_produced, remainder.data());
1,875✔
59

60
      const size_t bits_consumed = base.bits_consumed();
1,875✔
61
      const size_t remaining_bits_before_padding = base.remaining_bits_before_padding();
1,875✔
62

63
      size_t empty_bits = 8 * (encoding_bytes_in - input_remaining);
1,875✔
64
      size_t index = output_produced + encoding_bytes_out - 1;
1,875✔
65
      while(empty_bits >= remaining_bits_before_padding) {
4,713✔
66
         output[index--] = '=';
2,838✔
67
         empty_bits -= bits_consumed;
2,838✔
68
      }
69

70
      input_consumed += input_remaining;
1,875✔
71
      output_produced += encoding_bytes_out;
1,875✔
72
   }
1,875✔
73

74
   return output_produced;
2,162✔
75
}
76

77
template <typename Base>
78
std::string base_encode_to_string(Base&& base, const uint8_t input[], size_t input_length) {
2,156✔
79
   const size_t output_length = base.encode_max_output(input_length);
2,156✔
80
   std::string output(output_length, 0);
2,156✔
81

82
   size_t consumed = 0;
2,156✔
83
   size_t produced = 0;
2,156✔
84

85
   if(output_length > 0) {
2,156✔
86
      produced = base_encode(base, &output.front(), input, input_length, consumed, true);
2,154✔
87
   }
88

89
   BOTAN_ASSERT_EQUAL(consumed, input_length, "Consumed the entire input");
2,156✔
90
   BOTAN_ASSERT_EQUAL(produced, output.size(), "Produced expected size");
2,156✔
91

92
   return output;
2,156✔
93
}
×
94

95
/**
96
* Perform decoding using the base provided
97
* @param base object giving access to the encodings specifications
98
* @param output an array of at least Base::decode_max_output bytes
99
* @param input some base input
100
* @param input_length length of input in bytes
101
* @param input_consumed is an output parameter which says how many
102
*        bytes of input were actually consumed. If less than
103
*        input_length, then the range input[consumed:length]
104
*        should be passed in later along with more input.
105
* @param final_inputs true iff this is the last input, in which case
106
         padding is allowed
107
* @param ignore_ws ignore whitespace on input; if false, throw an
108
                   exception if whitespace is encountered
109
* @return number of bytes written to output
110
*/
111
template <typename Base>
112
size_t base_decode(Base&& base,
11,555✔
113
                   uint8_t output[],
114
                   const char input[],
115
                   size_t input_length,
116
                   size_t& input_consumed,
117
                   bool final_inputs,
118
                   bool ignore_ws = true) {
119
   const size_t decoding_bytes_in = base.decoding_bytes_in();
11,555✔
120
   const size_t decoding_bytes_out = base.decoding_bytes_out();
11,555✔
121

122
   uint8_t* out_ptr = output;
11,555✔
123
   std::vector<uint8_t> decode_buf(decoding_bytes_in, 0);
11,555✔
124
   size_t decode_buf_pos = 0;
11,555✔
125
   size_t final_truncate = 0;
11,555✔
126

127
   clear_mem(output, base.decode_max_output(input_length));
11,555✔
128

129
   for(size_t i = 0; i != input_length; ++i) {
15,702,917✔
130
      const uint8_t bin = base.lookup_binary_value(input[i]);
15,691,438✔
131

132
      if(base.check_bad_char(bin, input[i], ignore_ws))  // May throw Invalid_Argument
15,691,438✔
133
      {
134
         decode_buf[decode_buf_pos] = bin;
15,422,187✔
135
         ++decode_buf_pos;
15,422,187✔
136
      }
137

138
      /*
139
      * If we're at the end of the input, pad with 0s and truncate
140
      */
141
      if(final_inputs && (i == input_length - 1)) {
15,691,362✔
142
         if(decode_buf_pos) {
11,464✔
143
            for(size_t j = decode_buf_pos; j < decoding_bytes_in; ++j) {
16,249✔
144
               decode_buf[j] = 0;
9,827✔
145
            }
146

147
            final_truncate = decoding_bytes_in - decode_buf_pos;
6,422✔
148
            decode_buf_pos = decoding_bytes_in;
149
         }
150
      }
151

152
      if(decode_buf_pos == decoding_bytes_in) {
15,684,940✔
153
         base.decode(out_ptr, decode_buf.data());
3,857,892✔
154

155
         out_ptr += decoding_bytes_out;
3,857,892✔
156
         decode_buf_pos = 0;
3,857,892✔
157
         input_consumed = i + 1;
3,857,892✔
158
      }
159
   }
160

161
   while(input_consumed < input_length && base.lookup_binary_value(input[input_consumed]) == 0x80) {
17,471✔
162
      ++input_consumed;
5,992✔
163
   }
164

165
   size_t written = (out_ptr - output) - base.bytes_to_remove(final_truncate);
11,479✔
166

167
   return written;
11,479✔
168
}
11,479✔
169

170
template <typename Base>
171
size_t base_decode_full(Base&& base, uint8_t output[], const char input[], size_t input_length, bool ignore_ws) {
11,553✔
172
   size_t consumed = 0;
11,553✔
173
   const size_t written = base_decode(base, output, input, input_length, consumed, true, ignore_ws);
11,553✔
174

175
   if(consumed != input_length) {
11,477✔
176
      throw Invalid_Argument(base.name() + " decoding failed, input did not have full bytes");
42✔
177
   }
178

179
   return written;
11,463✔
180
}
181

182
template <typename Vector, typename Base>
183
Vector base_decode_to_vec(Base&& base, const char input[], size_t input_length, bool ignore_ws) {
11,536✔
184
   const size_t output_length = base.decode_max_output(input_length);
11,536✔
185
   Vector bin(output_length);
11,536✔
186

187
   const size_t written = base_decode_full(base, bin.data(), input, input_length, ignore_ws);
11,536✔
188

189
   bin.resize(written);
11,446✔
190
   return bin;
11,446✔
191
}
90✔
192

193
}
194

195
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc