CVSROOT: /cvs Module name: src Changes by: t...@cvs.openbsd.org 2025/07/16 23:30:41
Modified files: bin/md5 : md5.c Log message: md5(1): avoid incompatible function pointer casts This is a bit of a stupid change with lots of boilerplate. The problem is undefined behavior due to the second sentence of C99 6.3.2.3, 8: A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined. The notion of compatibility for the functions here boils down to compatible return type and compatible argument list, which in particular means the same number of arguments. See 6.7.5.3, 15 for the gory details. There's also a version understandable to a human being lacking the brain damage necessary for successfully deciphering the C99 standard's language: https://en.cppreference.com/w/c/language/type.html So calling 'void CKSUM_Final(CKSUM_CTX *);' through the final member of struct hash_function is clearly UB since the numbers of parameters don't match. If that was all, the fix would be trivial. But the same goes for void MD5Final(MD5_CTX *, char *); because MD5_CTX * and void * aren't compatible in this sense: by definition, two pointer types are compatible if they point to compatible types. Or, if you prefer: void * has looser alignment requirements than MD5_CTX *, so they aren't compatible. The below avoids this by adding wrapper functions that have the correct types that then propagate their parameters by using the appropriate union member. with/ok millert