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

randombit / botan / 25457312714

06 May 2026 07:43PM UTC coverage: 89.331% (-2.3%) from 91.667%
25457312714

push

github

randombit
In TLS 1.3 verification of client certs, check the correct extension for OCSP

This was checking if the client asked us (the server) for OCSP, instead of
checking if we asked the client for OCSP when we sent the CertificateRequest.

107574 of 120422 relevant lines covered (89.33%)

11482758.98 hits per line

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

99.3
/src/lib/utils/charset.cpp
1
/*
2
* Character Set Handling
3
* (C) 1999-2007,2021 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/internal/charset.h>
9

10
#include <botan/exceptn.h>
11
#include <botan/internal/loadstor.h>
12
#include <sstream>
13

14
namespace Botan {
15

16
namespace {
17

18
void append_utf8_for(std::string& s, uint32_t c) {
28,077✔
19
   if(c >= 0xD800 && c < 0xE000) {
28,077✔
20
      throw Decoding_Error("Invalid Unicode character");
2✔
21
   }
22

23
   if(c <= 0x7F) {
28,075✔
24
      const uint8_t b0 = static_cast<uint8_t>(c);
27,563✔
25
      s.push_back(static_cast<char>(b0));
27,563✔
26
   } else if(c <= 0x7FF) {
512✔
27
      const uint8_t b0 = 0xC0 | static_cast<uint8_t>(c >> 6);
198✔
28
      const uint8_t b1 = 0x80 | static_cast<uint8_t>(c & 0x3F);
198✔
29
      s.push_back(static_cast<char>(b0));
198✔
30
      s.push_back(static_cast<char>(b1));
198✔
31
   } else if(c <= 0xFFFF) {
314✔
32
      const uint8_t b0 = 0xE0 | static_cast<uint8_t>(c >> 12);
292✔
33
      const uint8_t b1 = 0x80 | static_cast<uint8_t>((c >> 6) & 0x3F);
292✔
34
      const uint8_t b2 = 0x80 | static_cast<uint8_t>(c & 0x3F);
292✔
35
      s.push_back(static_cast<char>(b0));
292✔
36
      s.push_back(static_cast<char>(b1));
292✔
37
      s.push_back(static_cast<char>(b2));
292✔
38
   } else if(c <= 0x10FFFF) {
22✔
39
      const uint8_t b0 = 0xF0 | static_cast<uint8_t>(c >> 18);
1✔
40
      const uint8_t b1 = 0x80 | static_cast<uint8_t>((c >> 12) & 0x3F);
1✔
41
      const uint8_t b2 = 0x80 | static_cast<uint8_t>((c >> 6) & 0x3F);
1✔
42
      const uint8_t b3 = 0x80 | static_cast<uint8_t>(c & 0x3F);
1✔
43
      s.push_back(static_cast<char>(b0));
1✔
44
      s.push_back(static_cast<char>(b1));
1✔
45
      s.push_back(static_cast<char>(b2));
1✔
46
      s.push_back(static_cast<char>(b3));
1✔
47
   } else {
48
      throw Decoding_Error("Invalid Unicode character");
21✔
49
   }
50
}
28,054✔
51

52
uint32_t next_utf8_codepoint(const std::string& utf8, size_t& pos) {
551,610✔
53
   auto read_continuation = [&]() -> uint32_t {
554,386✔
54
      if(pos >= utf8.size()) {
2,776✔
55
         throw Decoding_Error("Invalid UTF-8 sequence");
5✔
56
      }
57
      const uint8_t b = static_cast<uint8_t>(utf8[pos++]);
2,771✔
58
      if((b & 0xC0) != 0x80) {
2,771✔
59
         throw Decoding_Error("Invalid UTF-8 sequence");
8✔
60
      }
61
      return b & 0x3F;
2,763✔
62
   };
551,610✔
63

64
   const uint8_t lead = static_cast<uint8_t>(utf8[pos++]);
551,610✔
65
   uint32_t c = 0;
551,610✔
66

67
   if(lead <= 0x7F) {
551,610✔
68
      c = lead;
548,902✔
69
   } else if((lead & 0xE0) == 0xC0) {
2,708✔
70
      c = (lead & 0x1F) << 6;
2,631✔
71
      c |= read_continuation();
2,631✔
72
      if(c < 0x80) {
2,625✔
73
         throw Decoding_Error("Overlong UTF-8 sequence");
1✔
74
      }
75
   } else if((lead & 0xF0) == 0xE0) {
77✔
76
      c = (lead & 0x0F) << 12;
53✔
77
      c |= read_continuation() << 6;
53✔
78
      c |= read_continuation();
53✔
79
      if(c < 0x800) {
50✔
80
         throw Decoding_Error("Overlong UTF-8 sequence");
3✔
81
      }
82
   } else if((lead & 0xF8) == 0xF0) {
24✔
83
      c = (lead & 0x07) << 18;
14✔
84
      c |= read_continuation() << 12;
14✔
85
      c |= read_continuation() << 6;
13✔
86
      c |= read_continuation();
12✔
87
      if(c < 0x10000) {
10✔
88
         throw Decoding_Error("Overlong UTF-8 sequence");
3✔
89
      }
90
   } else {
91
      throw Decoding_Error("Invalid UTF-8 sequence");
10✔
92
   }
93

94
   if(c > 0x10FFFF) {
551,580✔
95
      throw Decoding_Error("UTF-8 sequence encodes value outside Unicode range");
3✔
96
   }
97
   if(c >= 0xD800 && c < 0xE000) {
551,577✔
98
      throw Decoding_Error("UTF-8 sequence encodes surrogate code point");
3✔
99
   }
100

101
   return c;
551,574✔
102
}
103

104
}  // namespace
105

106
bool is_valid_utf8(const std::string& utf8) {
33,543✔
107
   try {
33,543✔
108
      size_t pos = 0;
33,543✔
109
      while(pos < utf8.size()) {
585,015✔
110
         const uint32_t c = next_utf8_codepoint(utf8, pos);
551,486✔
111
         BOTAN_UNUSED(c);
112
      }
113
   } catch(Decoding_Error&) {
14✔
114
      return false;
14✔
115
   }
14✔
116
   return true;
33,529✔
117
}
118

119
std::string ucs2_to_utf8(const uint8_t ucs2[], size_t len) {
950✔
120
   if(len % 2 != 0) {
950✔
121
      throw Decoding_Error("Invalid length for UCS-2 string");
8✔
122
   }
123

124
   const size_t chars = len / 2;
942✔
125

126
   std::string s;
942✔
127
   for(size_t i = 0; i != chars; ++i) {
2,437✔
128
      const uint32_t c = load_be<uint16_t>(ucs2, i);
1,496✔
129
      append_utf8_for(s, c);
1,496✔
130
   }
131

132
   return s;
941✔
133
}
1✔
134

135
std::vector<uint8_t> utf8_to_ucs2(const std::string& utf8) {
24✔
136
   std::vector<uint8_t> out;
24✔
137
   out.reserve(utf8.size() * 2);
24✔
138

139
   size_t pos = 0;
24✔
140
   while(pos < utf8.size()) {
92✔
141
      const uint32_t c = next_utf8_codepoint(utf8, pos);
81✔
142
      if(c > 0xFFFF) {
69✔
143
         throw Decoding_Error("Cannot encode character in UCS-2");
1✔
144
      }
145
      const uint16_t val = static_cast<uint16_t>(c);
68✔
146
      out.push_back(get_byte<0>(val));
68✔
147
      out.push_back(get_byte<1>(val));
68✔
148
   }
149

150
   return out;
11✔
151
}
13✔
152

153
std::string ucs4_to_utf8(const uint8_t ucs4[], size_t len) {
69✔
154
   if(len % 4 != 0) {
69✔
155
      throw Decoding_Error("Invalid length for UCS-4 string");
5✔
156
   }
157

158
   const size_t chars = len / 4;
64✔
159

160
   std::string s;
64✔
161
   for(size_t i = 0; i != chars; ++i) {
107✔
162
      const uint32_t c = load_be<uint32_t>(ucs4, i);
65✔
163
      append_utf8_for(s, c);
65✔
164
   }
165

166
   return s;
42✔
167
}
22✔
168

169
std::vector<uint8_t> utf8_to_ucs4(const std::string& utf8) {
21✔
170
   std::vector<uint8_t> out;
21✔
171
   out.reserve(utf8.size() * 4);
21✔
172

173
   size_t pos = 0;
21✔
174
   while(pos < utf8.size()) {
54✔
175
      const uint32_t val = next_utf8_codepoint(utf8, pos);
43✔
176
      out.push_back(get_byte<0>(val));
33✔
177
      out.push_back(get_byte<1>(val));
33✔
178
      out.push_back(get_byte<2>(val));
33✔
179
      out.push_back(get_byte<3>(val));
33✔
180
   }
181

182
   return out;
11✔
183
}
10✔
184

185
/*
186
* Convert from ISO 8859-1 to UTF-8
187
*/
188
std::string latin1_to_utf8(const uint8_t chars[], size_t len) {
1,196✔
189
   std::string s;
1,196✔
190
   for(size_t i = 0; i != len; ++i) {
27,712✔
191
      const uint32_t c = static_cast<uint8_t>(chars[i]);
26,516✔
192
      append_utf8_for(s, c);
26,516✔
193
   }
194
   return s;
1,196✔
195
}
×
196

197
std::string format_char_for_display(char c) {
77✔
198
   std::ostringstream oss;
77✔
199

200
   oss << "'";
77✔
201

202
   if(c == '\t') {
77✔
203
      oss << "\\t";
14✔
204
   } else if(c == '\n') {
63✔
205
      oss << "\\n";
14✔
206
   } else if(c == '\r') {
49✔
207
      oss << "\\r";
14✔
208
   } else if(static_cast<unsigned char>(c) >= 128) {
35✔
209
      const unsigned char z = static_cast<unsigned char>(c);
6✔
210
      oss << "\\x" << std::hex << std::uppercase << static_cast<int>(z);
6✔
211
   } else {
212
      oss << c;
29✔
213
   }
214

215
   oss << "'";
77✔
216

217
   return oss.str();
154✔
218
}
77✔
219

220
}  // 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