
― Steven Redhead, Life Is Simply A Game
The following routine is from a real-world project. It’s supposed to convert binary data into a printable C-string of hexadecimal digits. Even though the developer diligently wrote some unit tests, he got complaints from his fellow coders a few days later. Can you find what’s wrong with it?
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  | 
						const char* to_hexstring(const void* data, size_t data_len, char* out, size_t out_len) {     if (data == NULL || data_len == 0 || out == NULL || out_len == 0) {         return NULL;     }     //  Only proceed if output buffer is large enough:     //  Two chars per byte + trailing string terminator.     if (out_len < (data_len * 2) + 1) {         return NULL;     }     const char* p = (const char*) data;     for (size_t i = 0; i < data_len; ++i) {         char hexbyte[2 + 1];         snprintf(hexbyte, sizeof(hexbyte), "%02X", *p++);         strcat(out, hexbyte);     }     return out; }  | 
					
Unit tests:
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34  | 
						TEST(to_hexstring, some_tests) {     const unsigned char TEST_DATA[] = { 0x00, 0x11, 0x22, 0x33, 0x1F };     char hexstring[sizeof(TEST_DATA) * 2 + 1];     // Typical case, output buffer large enough.     hexstring[0] = '\0';     EXPECT_STREQ("001122331F", to_hexstring(TEST_DATA, sizeof(TEST_DATA),          hexstring, sizeof(hexstring)));     // Convert just a single byte.     hexstring[0] = '\0';     EXPECT_STREQ("00", to_hexstring(TEST_DATA, 1, hexstring,         sizeof(hexstring)));     // Convert two bytes.     hexstring[0] = '\0';     EXPECT_STREQ("0011", to_hexstring(TEST_DATA, 2, hexstring,         sizeof(hexstring)));     // Error: output buffer too small.     hexstring[0] = '\0';     EXPECT_STREQ(NULL, to_hexstring(TEST_DATA, sizeof(TEST_DATA),         hexstring, 1));     // Error: output buffer too small.     hexstring[0] = '\0';     EXPECT_STREQ(NULL, to_hexstring(TEST_DATA, 1, hexstring, 1));     // Error: output buffer still too small.     hexstring[0] = '\0';     EXPECT_STREQ(NULL, to_hexstring(TEST_DATA, 1, hexstring, 1 + 1)); }  |