CATEGORY: Wrong assumption about the size of character literals. REFERENCE: - EXPLANATION: The developer uses the 'sizeof' operator to compute offsets into the bitmap data structure. While using 'sizeof' for such purposes is usually considered good practice, it fails in this case because the developer assumed that the size of a character literal is 1, which is not the case. In C (as opposed to C++) the type of a character constant is 'int' not 'char'. Expecting that character literals are of type 'char' is an easy mistake to make, even for experienced programmers. Consider: assert(sizeof(int) == sizeof(42)); // Holds. assert(sizeof(long) == sizeof(42l)); // dito. assert(sizeof(double) == sizeof(1.23)); // dito. assert(sizeof(float) == sizeof(1.23f)); // dito. assert(sizeof(char) == sizeof('B')); // Fails. CONSEQUENCES: On a typical platform, 'int' is of size 4 and thus the offsets into the bitmap data structure will be too large, resulting in wrong values for the pointer to the pixel data and the size of the pixel data area. Most likely, using the wrong values returned by function 'bmp_pixel_data' will lead to segmentation faults. BUGFIX: The most straightforward fix is to put 1 as the size of the character literals in the macros which compute the offsets: /* Offset of second magic byte. */ #define BMP_MAGIC_BYTE2_OFS (BMP_MAGIC_BYTE1_OFS + 1) /* Offset to 4-byte bitmap file size, little-endian. */ #define BMP_FILE_SIZE_OFS (BMP_MAGIC_BYTE2_OFS + 1) However, since the developer wanted to avoid such hard-coded literals and let the compiler do the computation, another fix is conceivable: /* First magic byte. */ static const char BMP_MAGIC_BYTE1 = 'B'; /* Second magic byte. */ static const char BMP_MAGIC_BYTE2 = 'M'; When the 'sizeof' operator is applied to these constants, it will correctly report a size of 1. REMARKS: * Thankfully, this unexpected behavior was fixed in C++, so the code will work correctly if compiled with a C++ compiler. NOTES: -