Browse code
Validate base32 codec input size, avoid segfaults
Ed Langley authored on 13/06/2017 22:05:06
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -25,6 +25,17 @@ static const std::vector<char> alphabet = { |
25 | 25 |
|
26 | 26 |
namespace |
27 | 27 |
{ |
28 |
+class invalid_input_size : public std::exception |
|
29 |
+{ |
|
30 |
+private: |
|
31 |
+ using string_size = std::string::size_type; |
|
32 |
+public: |
|
33 |
+ string_size received_size; |
|
34 |
+ invalid_input_size(string_size received_size) : |
|
35 |
+ received_size (received_size) |
|
36 |
+ {} |
|
37 |
+}; |
|
38 |
+ |
|
28 | 39 |
class base32_impl : public base32_ifc |
29 | 40 |
{ |
30 | 41 |
private: |
... | ... |
@@ -165,11 +176,16 @@ private: |
165 | 176 |
std::string::size_type input_size = input.size(); |
166 | 177 |
std::string::size_type first_equals = input.find_first_of ('='); |
167 | 178 |
|
179 |
+ if (input_size == 0 || (input_size % 8 != 0)) { |
|
180 |
+ throw invalid_input_size(input_size); |
|
181 |
+ } |
|
182 |
+ |
|
168 | 183 |
if (first_equals != std::string::npos) { |
169 | 184 |
input_size = first_equals; |
170 | 185 |
} |
171 | 186 |
|
172 | 187 |
return (input_size * 5) / 8; |
188 |
+ |
|
173 | 189 |
} |
174 | 190 |
|
175 | 191 |
public: |
... | ... |
@@ -64,8 +64,13 @@ int decode_validates_input() |
64 | 64 |
// The token for key 76I6WTYEUTNCJUREMGKVM45PMA and time '2017/01/01 00:00:00' is 258675 |
65 | 65 |
base32 codec = base32(); |
66 | 66 |
|
67 |
- std::vector<uint8_t> result = codec.decode("\x00"); |
|
68 |
- check(result.empty(), "invalid input doesn't produce an empty result"); |
|
67 |
+ try { |
|
68 |
+ codec.decode("\x00"); |
|
69 |
+ codec.decode("\x00\x00\x00\x00\x00\x00\x00\x00\x00"); |
|
70 |
+ fail("invalid length should result in an exception"); |
|
71 |
+ } catch (std::exception e) { |
|
72 |
+ succeed(); |
|
73 |
+ } |
|
69 | 74 |
|
70 | 75 |
succeed(); |
71 | 76 |
} |
... | ... |
@@ -122,7 +122,7 @@ int installs_token() |
122 | 122 |
{ |
123 | 123 |
//given |
124 | 124 |
std::string user_name ("user"); |
125 |
- std::string key ("thekey"); |
|
125 |
+ std::string key ("thekeyis"); |
|
126 | 126 |
std::string token ("thetoken"); |
127 | 127 |
auto test_tokens = std::make_shared<mock_tokens> (key); |
128 | 128 |
tokens tokens{test_tokens}; |
... | ... |
@@ -238,4 +238,3 @@ int main (int argc, char *argv[]) |
238 | 238 |
{ |
239 | 239 |
return !run_tests(); |
240 | 240 |
} |
241 |
- |