Browse code
CJPM-5223: base32::decode validates input
Ed Langley authored on 14/06/2017 18:23:35
Showing 4 changed files
Showing 4 changed files
... | ... |
@@ -128,8 +128,10 @@ public: |
128 | 128 |
} |
129 | 129 |
|
130 | 130 |
private: |
131 |
+ using reverse_map = std::unordered_map <char, unsigned char>; |
|
132 |
+ using character_type = std::string::value_type; |
|
131 | 133 |
|
132 |
- std::unordered_map <char, unsigned char> construct_lookup_table() const |
|
134 |
+ reverse_map construct_lookup_table() const |
|
133 | 135 |
{ |
134 | 136 |
std::unordered_map<char, unsigned char> lookup_table; |
135 | 137 |
|
... | ... |
@@ -188,6 +190,16 @@ private: |
188 | 190 |
|
189 | 191 |
} |
190 | 192 |
|
193 |
+ uint8_t get_next_input(reverse_map &lookup_table, std::string &input, std::string::size_type idx) const { |
|
194 |
+ character_type character = input[idx]; |
|
195 |
+ |
|
196 |
+ if (character != '=' && lookup_table.find(character) == lookup_table.end()) { |
|
197 |
+ throw invalid_data_exception (); |
|
198 |
+ } |
|
199 |
+ |
|
200 |
+ return lookup_table[input[idx]]; |
|
201 |
+ } |
|
202 |
+ |
|
191 | 203 |
public: |
192 | 204 |
|
193 | 205 |
std::vector<uint8_t> decode (std::string input) const override |
... | ... |
@@ -200,12 +212,10 @@ public: |
200 | 212 |
unsigned long long bits_written = 0; |
201 | 213 |
|
202 | 214 |
for (std::string::size_type idx = 0; idx < input.size(); idx++) { |
203 |
- // TODO: fail on invalid input |
|
204 |
- uint8_t val = lookup_table[input[idx]]; |
|
205 |
- |
|
206 | 215 |
uint8_t start_bit = bits_written % 8; |
207 | 216 |
std::vector<unsigned char>::size_type current_byte = bits_written/8; |
208 | 217 |
|
218 |
+ uint8_t val = get_next_input(lookup_table, input, idx); |
|
209 | 219 |
set_vector_at_bit (result, val, current_byte, start_bit, 5); |
210 | 220 |
|
211 | 221 |
bits_written += 5; |
... | ... |
@@ -221,4 +231,3 @@ template class std::vector<unsigned char>; |
221 | 231 |
base32::base32 (): |
222 | 232 |
delegate_ (std::make_shared<base32_impl> ()) |
223 | 233 |
{} |
224 |
- |
... | ... |
@@ -64,14 +64,24 @@ 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 |
+ int num_exceptions = 0; |
|
67 | 68 |
try { |
68 |
- codec.decode ("\x00"); |
|
69 |
- codec.decode ("\x00\x00\x00\x00\x00\x00\x00\x00\x00"); |
|
69 |
+ codec.decode ("A"); |
|
70 |
+ codec.decode ("AAAAAAAAA"); |
|
70 | 71 |
fail ("invalid length should result in an exception"); |
71 | 72 |
} catch (std::exception e) { |
72 |
- succeed(); |
|
73 |
+ num_exceptions++; |
|
73 | 74 |
} |
74 | 75 |
|
76 |
+ try { |
|
77 |
+ codec.decode ("--------"); |
|
78 |
+ fail ("invalid input characters should result in an exception"); |
|
79 |
+ } catch (invalid_data_exception) { |
|
80 |
+ num_exceptions++; |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ check(num_exceptions == 2, "base32.decode should validate input data"); |
|
84 |
+ |
|
75 | 85 |
succeed(); |
76 | 86 |
} |
77 | 87 |
|
... | ... |
@@ -107,4 +117,3 @@ int main (int argc, char *argv[]) |
107 | 117 |
{ |
108 | 118 |
return !run_tests(); |
109 | 119 |
} |
110 |
- |
... | ... |
@@ -123,7 +123,7 @@ int installs_token() |
123 | 123 |
{ |
124 | 124 |
//given |
125 | 125 |
std::string user_name ("user"); |
126 |
- std::string key ("thekeyis"); |
|
126 |
+ std::string key ("THEKEYIS"); |
|
127 | 127 |
std::string token ("thetoken"); |
128 | 128 |
auto test_tokens = std::make_shared<mock_tokens> (key); |
129 | 129 |
tokens tokens{test_tokens}; |
... | ... |
@@ -236,4 +236,3 @@ int main (int argc, char *argv[]) |
236 | 236 |
{ |
237 | 237 |
return !run_tests(); |
238 | 238 |
} |
239 |
- |