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

randombit / botan / 13262741994

11 Feb 2025 12:19PM UTC coverage: 91.656% (-0.003%) from 91.659%
13262741994

Pull #4647

github

web-flow
Merge 0b8e56724 into f372b5a9e
Pull Request #4647: Avoid using mem_ops.h or assert.h in public headers

94864 of 103500 relevant lines covered (91.66%)

11330304.66 hits per line

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

82.72
/src/lib/filters/b64_filt.cpp
1
/*
2
* Base64 Encoder/Decoder
3
* (C) 1999-2010 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/filters.h>
9

10
#include <botan/base64.h>
11
#include <botan/exceptn.h>
12
#include <botan/mem_ops.h>
13
#include <algorithm>
14

15
namespace Botan {
16

17
/*
18
* Base64_Encoder Constructor
19
*/
20
Base64_Encoder::Base64_Encoder(bool line_breaks, size_t line_length, bool trailing_newline) :
5✔
21
      m_line_length(line_breaks ? line_length : 0),
10✔
22
      m_trailing_newline(trailing_newline && line_breaks),
5✔
23
      m_in(48),
5✔
24
      m_out(64),
5✔
25
      m_position(0),
5✔
26
      m_out_position(0) {}
10✔
27

28
/*
29
* Encode and send a block
30
*/
31
void Base64_Encoder::encode_and_send(const uint8_t input[], size_t length, bool final_inputs) {
8✔
32
   while(length) {
16✔
33
      const size_t proc = std::min(length, m_in.size());
8✔
34

35
      size_t consumed = 0;
8✔
36
      size_t produced = base64_encode(cast_uint8_ptr_to_char(m_out.data()), input, proc, consumed, final_inputs);
8✔
37

38
      do_output(m_out.data(), produced);
8✔
39

40
      // FIXME: s/proc/consumed/?
41
      input += proc;
8✔
42
      length -= proc;
8✔
43
   }
44
}
8✔
45

46
/*
47
* Handle the output
48
*/
49
void Base64_Encoder::do_output(const uint8_t input[], size_t length) {
8✔
50
   if(m_line_length == 0) {
8✔
51
      send(input, length);
6✔
52
   } else {
53
      size_t remaining = length, offset = 0;
2✔
54
      while(remaining) {
8✔
55
         size_t sent = std::min(m_line_length - m_out_position, remaining);
6✔
56
         send(input + offset, sent);
6✔
57
         m_out_position += sent;
6✔
58
         remaining -= sent;
6✔
59
         offset += sent;
6✔
60
         if(m_out_position == m_line_length) {
6✔
61
            send('\n');
5✔
62
            m_out_position = 0;
5✔
63
         }
64
      }
65
   }
66
}
8✔
67

68
/*
69
* Convert some data into Base64
70
*/
71
void Base64_Encoder::write(const uint8_t input[], size_t length) {
8✔
72
   const size_t initial_fill = std::min(m_in.size() - m_position, length);
8✔
73
   copy_mem(&m_in[m_position], input, initial_fill);
8✔
74

75
   if(m_position + length >= m_in.size()) {
8✔
76
      encode_and_send(m_in.data(), m_in.size());
×
77
      input += (m_in.size() - m_position);
×
78
      length -= (m_in.size() - m_position);
×
79
      while(length >= m_in.size()) {
×
80
         encode_and_send(input, m_in.size());
×
81
         input += m_in.size();
×
82
         length -= m_in.size();
×
83
      }
84
      copy_mem(m_in.data(), input, length);
×
85
      m_position = 0;
×
86
   }
87
   m_position += length;
8✔
88
}
8✔
89

90
/*
91
* Flush buffers
92
*/
93
void Base64_Encoder::end_msg() {
8✔
94
   encode_and_send(m_in.data(), m_position, true);
8✔
95

96
   if(m_trailing_newline || (m_out_position && m_line_length)) {
8✔
97
      send('\n');
2✔
98
   }
99

100
   m_out_position = m_position = 0;
8✔
101
}
8✔
102

103
/*
104
* Base64_Decoder Constructor
105
*/
106
Base64_Decoder::Base64_Decoder(Decoder_Checking c) : m_checking(c), m_in(64), m_out(48), m_position(0) {}
1✔
107

108
/*
109
* Convert some data from Base64
110
*/
111
void Base64_Decoder::write(const uint8_t input[], size_t length) {
1✔
112
   while(length) {
2✔
113
      size_t to_copy = std::min<size_t>(length, m_in.size() - m_position);
1✔
114
      if(to_copy == 0) {
1✔
115
         m_in.resize(m_in.size() * 2);
×
116
         m_out.resize(m_out.size() * 2);
×
117
      }
118
      copy_mem(&m_in[m_position], input, to_copy);
1✔
119
      m_position += to_copy;
1✔
120

121
      size_t consumed = 0;
1✔
122
      size_t written = base64_decode(
2✔
123
         m_out.data(), cast_uint8_ptr_to_char(m_in.data()), m_position, consumed, false, m_checking != FULL_CHECK);
1✔
124

125
      send(m_out, written);
1✔
126

127
      if(consumed != m_position) {
1✔
128
         copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed);
×
129
         m_position = m_position - consumed;
×
130
      } else {
131
         m_position = 0;
1✔
132
      }
133

134
      length -= to_copy;
1✔
135
      input += to_copy;
1✔
136
   }
137
}
1✔
138

139
/*
140
* Flush buffers
141
*/
142
void Base64_Decoder::end_msg() {
1✔
143
   size_t consumed = 0;
1✔
144
   size_t written = base64_decode(
2✔
145
      m_out.data(), cast_uint8_ptr_to_char(m_in.data()), m_position, consumed, true, m_checking != FULL_CHECK);
1✔
146

147
   send(m_out, written);
1✔
148

149
   const bool not_full_bytes = consumed != m_position;
1✔
150

151
   m_position = 0;
1✔
152

153
   if(not_full_bytes) {
1✔
154
      throw Invalid_Argument("Base64_Decoder: Input not full bytes");
×
155
   }
156
}
1✔
157

158
}  // namespace Botan
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