git.fiddlerwoaroof.com
Browse code

Validate base32 codec input size, avoid segfaults

Ed Langley authored on 13/06/2017 22:05:06
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
-