Created
December 28, 2023 22:11
-
-
Save charlesnicholson/b895097b09e8a83df4a349e98b0ceb49 to your computer and use it in GitHub Desktop.
Demonstrate bugs in Wikipedia's cobsDecode C sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#define USE_WIKIPEDIA_COBS_DECODE 1 | |
#if USE_WIKIPEDIA_COBS_DECODE | |
size_t cobsDecode(const uint8_t *buffer, size_t length, void *data) { | |
assert(buffer && data); | |
const uint8_t *byte = buffer; // Encoded input byte pointer | |
uint8_t *decode = (uint8_t *)data; // Decoded output byte pointer | |
for (uint8_t code = 0xff, block = 0; byte < buffer + length; --block) { | |
if (block) // Decode block byte | |
*decode++ = *byte++; | |
else { | |
if (code != 0xff) // Encoded zero, write it | |
*decode++ = 0; | |
block = code = *byte++; // Next block length | |
if (!code) // Delimiter code found | |
break; | |
} | |
} | |
return (size_t)(decode - (uint8_t *)data); | |
} | |
#else | |
size_t cobsDecode(const uint8_t *buffer, size_t length, void *data) { | |
assert(buffer && data); | |
const uint8_t *byte = buffer; // Encoded input byte pointer | |
uint8_t *decode = (uint8_t *)data; // Decoded output byte pointer | |
for (uint8_t code = 0xff, block = 0; byte < buffer + length; --block) { | |
if (block) // Decode block byte | |
*decode++ = *byte++; | |
else { | |
block = *byte++; // Fetch the next block length | |
if (block && (code != 0xff)) // Encoded zero, write it unless it's final. | |
*decode++ = 0; | |
code = block; | |
if (!code) // Delimiter code found | |
break; | |
} | |
} | |
return (size_t)(decode - (uint8_t *)data); | |
} | |
#endif | |
unsigned char s_decoded[1024]; | |
void wikipedia_example(unsigned index, unsigned char const *encoded, | |
size_t encoded_len, unsigned char const *expected, | |
unsigned expected_len) { | |
size_t const len = cobsDecode(encoded, encoded_len, s_decoded); | |
printf("Example %u: Expected (%u)", index, expected_len); | |
for (size_t i = 0; i < expected_len; ++i) { | |
printf(" 0x%02X", expected[i]); | |
} | |
printf(", Actual (%u)", (unsigned)len); | |
for (size_t i = 0; i < len; ++i) { | |
printf(" 0x%02X", s_decoded[i]); | |
} | |
printf("\n"); | |
} | |
void wikipedia_example_1(void) { | |
unsigned char const encoded[] = {0x01, 0x01, 0x00}; | |
unsigned char const expected[] = {0x00}; | |
wikipedia_example(1, encoded, sizeof(encoded), expected, sizeof(expected)); | |
} | |
void wikipedia_example_2(void) { | |
unsigned char const encoded[] = {0x01, 0x01, 0x00, 0x00}; | |
unsigned char const expected[] = {0x00, 0x00}; | |
wikipedia_example(2, encoded, sizeof(encoded), expected, sizeof(expected)); | |
} | |
void wikipedia_example_3(void) { | |
unsigned char const encoded[] = {0x01, 0x02, 0x11, 0x01, 0x00}; | |
unsigned char const expected[] = {0x00, 0x11, 0x00}; | |
wikipedia_example(3, encoded, sizeof(encoded), expected, sizeof(expected)); | |
} | |
void wikipedia_example_4(void) { | |
unsigned char const encoded[] = {0x03, 0x11, 0x22, 0x02, 0x33, 0x00}; | |
unsigned char const expected[] = {0x11, 0x22, 0x00, 0x33}; | |
wikipedia_example(4, encoded, sizeof(encoded), expected, sizeof(expected)); | |
} | |
void wikipedia_example_5(void) { | |
unsigned char const encoded[] = {0x05, 0x11, 0x22, 0x33, 0x44, 0x00}; | |
unsigned char const expected[] = {0x11, 0x22, 0x33, 0x44}; | |
wikipedia_example(5, encoded, sizeof(encoded), expected, sizeof(expected)); | |
} | |
void wikipedia_example_6(void) { | |
unsigned char const encoded[] = {0x02, 0x11, 0x01, 0x01, 0x01, 0x00}; | |
unsigned char const expected[] = {0x11, 0x00, 0x00, 0x00}; | |
wikipedia_example(6, encoded, sizeof(encoded), expected, sizeof(expected)); | |
} | |
int main(int argc, char const *argv[]) { | |
(void)argc; | |
(void)argv; | |
wikipedia_example_1(); | |
wikipedia_example_2(); | |
wikipedia_example_3(); | |
wikipedia_example_4(); | |
wikipedia_example_5(); | |
wikipedia_example_6(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Wikipedia folks- I don't have an account over there but am happy to discuss over here if that's interesting / helpful. I hope this example displays the bug well enough.