mhstore and co. write files of the correct length but which consist
only of \0s.
The culprit is uip/mhparse.c, which contains a pretty ugly base64
decoder (in two places). that thing allocates a "long int" as a
container for the 24 bits that you get from four base-64 chars. the
container is then accessed both as a single entity and as a byte
array, which naturally depends on how wide the long int is and in what
order things end up in there.
The code distinguishes between big- and little-endian systems but
wrongly assumes that sizeof(long int) == 4, which isn't universally
true (quel surprise...).
The attached patch fixes the issue, but in the long run we should
insist on posix and use a64l().
CE ce;
MD5_CTX mdContext;
CE ce;
MD5_CTX mdContext;
+ /* the decoder works on the least-significant three bytes of the bits integer,
+ but their position in memory depend on both endian-ness and size of
+ long int... for little-endian architectures the size is irrelevant, for
+ big-endian archs it's crucial... ideally we'd adopt posix and use a64l instead
+ of this mess. */
b = (unsigned char *) &bits;
b = (unsigned char *) &bits;
- b1 = &b[endian > 0 ? 1 : 2];
- b2 = &b[endian > 0 ? 2 : 1];
- b3 = &b[endian > 0 ? 3 : 0];
+ b1 = &b[endian > 0 ? sizeof(bits)==8?5:1 : 2];
+ b2 = &b[endian > 0 ? sizeof(bits)==8?6:2 : 1];
+ b3 = &b[endian > 0 ? sizeof(bits)==8?7:3 : 0];
ce = ct->c_cefile;
if (ce->ce_fp) {
ce = ct->c_cefile;
if (ce->ce_fp) {
unsigned char *dp, value, *ep;
unsigned char *b, *b1, *b2, *b3;
unsigned char *dp, value, *ep;
unsigned char *b, *b1, *b2, *b3;
- b = (unsigned char *) &bits,
- b1 = &b[endian > 0 ? 1 : 2],
- b2 = &b[endian > 0 ? 2 : 1],
- b3 = &b[endian > 0 ? 3 : 0];
+ /* the decoder works on the least-significant three bytes of the bits integer,
+ but their position in memory depend on both endian-ness and size of
+ long int... for little-endian architectures the size is irrelevant, for
+ big-endian archs it's crucial... ideally we'd adopt posix and use a64l instead
+ of this mess. */
+ b = (unsigned char *) &bits;
+ b1 = &b[endian > 0 ? sizeof(bits)==8?5:1 : 2];
+ b2 = &b[endian > 0 ? sizeof(bits)==8?6:2 : 1];
+ b3 = &b[endian > 0 ? sizeof(bits)==8?7:3 : 0];
+
bitno = 18;
bits = 0L;
skip = 0;
bitno = 18;
bits = 0L;
skip = 0;