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

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

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

89.16
/src/lib/codec/hex/hex.cpp
1
/*
2
* Hex Encoding and Decoding
3
* (C) 2010,2020 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/hex.h>
9

10
#include <botan/exceptn.h>
11
#include <botan/mem_ops.h>
12
#include <botan/internal/charset.h>
13
#include <botan/internal/ct_utils.h>
14
#include <botan/internal/fmt.h>
15

16
namespace Botan {
17

18
namespace {
19

20
char hex_encode_nibble(uint8_t n, bool uppercase) {
1,802,218✔
21
   BOTAN_DEBUG_ASSERT(n <= 15);
1,802,218✔
22

23
   const auto in_09 = CT::Mask<uint8_t>::is_lt(n, 10);
1,802,218✔
24

25
   const char c_09 = n + '0';
1,802,218✔
26
   const char c_af = n + (uppercase ? 'A' : 'a') - 10;
901,109✔
27

28
   return in_09.select(c_09, c_af);
901,109✔
29
}
30

31
}  // namespace
32

33
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase) {
31,492✔
34
   for(size_t i = 0; i != input_length; ++i) {
932,601✔
35
      const uint8_t n0 = (input[i] >> 4) & 0xF;
901,109✔
36
      const uint8_t n1 = (input[i]) & 0xF;
901,109✔
37

38
      output[2 * i] = hex_encode_nibble(n0, uppercase);
901,109✔
39
      output[2 * i + 1] = hex_encode_nibble(n1, uppercase);
901,109✔
40
   }
41
}
31,492✔
42

43
std::string hex_encode(const uint8_t input[], size_t input_length, bool uppercase) {
32,001✔
44
   std::string output(2 * input_length, 0);
32,001✔
45

46
   if(input_length) {
32,001✔
47
      hex_encode(&output.front(), input, input_length, uppercase);
31,452✔
48
   }
49

50
   return output;
32,001✔
51
}
×
52

53
namespace {
54

55
uint8_t hex_char_to_bin(char input) {
33,765,916✔
56
   const uint8_t c = static_cast<uint8_t>(input);
33,765,916✔
57

58
   const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('F'));
33,765,916✔
59
   const auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('f'));
33,765,916✔
60
   const auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, uint8_t('0'), uint8_t('9'));
33,765,916✔
61

62
   const auto is_whitespace =
33,765,916✔
63
      CT::Mask<uint8_t>::is_any_of(c, {uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')});
33,765,916✔
64

65
   const uint8_t c_upper = c - uint8_t('A') + 10;
33,765,916✔
66
   const uint8_t c_lower = c - uint8_t('a') + 10;
33,765,916✔
67
   const uint8_t c_decim = c - uint8_t('0');
33,765,916✔
68

69
   uint8_t ret = 0xFF;  // default value
33,765,916✔
70

71
   ret = is_alpha_upper.select(c_upper, ret);
33,765,916✔
72
   ret = is_alpha_lower.select(c_lower, ret);
33,765,916✔
73
   ret = is_decimal.select(c_decim, ret);
33,765,916✔
74
   ret = is_whitespace.select(0x80, ret);
33,765,916✔
75

76
   return ret;
33,765,916✔
77
}
78

79
}  // namespace
80

81
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t& input_consumed, bool ignore_ws) {
206,445✔
82
   uint8_t* out_ptr = output;
206,445✔
83
   bool top_nibble = true;
206,445✔
84

85
   clear_mem(output, input_length / 2);
206,445✔
86

87
   for(size_t i = 0; i != input_length; ++i) {
33,972,361✔
88
      const uint8_t bin = hex_char_to_bin(input[i]);
33,765,916✔
89

90
      if(bin >= 0x10) {
33,765,916✔
91
         if(bin == 0x80 && ignore_ws) {
9,176✔
92
            continue;
9,176✔
93
         }
94

95
         throw Invalid_Argument(fmt("hex_decode: invalid character '{}'", format_char_for_display(input[i])));
×
96
      }
97

98
      if(top_nibble) {
33,756,740✔
99
         *out_ptr |= bin << 4;
16,878,370✔
100
      } else {
101
         *out_ptr |= bin;
16,878,370✔
102
      }
103

104
      top_nibble = !top_nibble;
33,756,740✔
105
      if(top_nibble) {
33,756,740✔
106
         ++out_ptr;
16,878,370✔
107
      }
108
   }
109

110
   input_consumed = input_length;
206,445✔
111
   size_t written = (out_ptr - output);
206,445✔
112

113
   /*
114
   * We only got half of a uint8_t at the end; zap the half-written
115
   * output and mark it as unread
116
   */
117
   if(!top_nibble) {
206,445✔
118
      *out_ptr = 0;
×
119
      input_consumed -= 1;
×
120
   }
121

122
   return written;
206,445✔
123
}
124

125
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, bool ignore_ws) {
206,399✔
126
   size_t consumed = 0;
206,399✔
127
   size_t written = hex_decode(output, input, input_length, consumed, ignore_ws);
206,399✔
128

129
   if(consumed != input_length) {
206,399✔
130
      throw Invalid_Argument("hex_decode: input did not have full bytes");
×
131
   }
132

133
   return written;
206,399✔
134
}
135

136
size_t hex_decode(uint8_t output[], std::string_view input, bool ignore_ws) {
15,076✔
137
   return hex_decode(output, input.data(), input.length(), ignore_ws);
15,076✔
138
}
139

140
size_t hex_decode(std::span<uint8_t> output, std::string_view input, bool ignore_ws) {
×
141
   return hex_decode(output.data(), input.data(), input.length(), ignore_ws);
×
142
}
143

144
secure_vector<uint8_t> hex_decode_locked(const char input[], size_t input_length, bool ignore_ws) {
42,627✔
145
   secure_vector<uint8_t> bin(1 + input_length / 2);
42,627✔
146

147
   size_t written = hex_decode(bin.data(), input, input_length, ignore_ws);
42,627✔
148

149
   bin.resize(written);
42,627✔
150
   return bin;
42,627✔
151
}
×
152

153
secure_vector<uint8_t> hex_decode_locked(std::string_view input, bool ignore_ws) {
83✔
154
   return hex_decode_locked(input.data(), input.size(), ignore_ws);
83✔
155
}
156

157
std::vector<uint8_t> hex_decode(const char input[], size_t input_length, bool ignore_ws) {
148,696✔
158
   std::vector<uint8_t> bin(1 + input_length / 2);
148,696✔
159

160
   size_t written = hex_decode(bin.data(), input, input_length, ignore_ws);
148,696✔
161

162
   bin.resize(written);
148,696✔
163
   return bin;
148,696✔
164
}
×
165

166
std::vector<uint8_t> hex_decode(std::string_view input, bool ignore_ws) {
148,688✔
167
   return hex_decode(input.data(), input.size(), ignore_ws);
148,688✔
168
}
169

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

© 2025 Coveralls, Inc