Здравствуйте, уважаемые форумчане.
Столкнулся с очень странной ошибкой в алгоритме декодирования Base64.Во время работы алгоритма магическим образом на 4-й итерации цикла затирается внутренняя переменная unsigned long outmax. При чем эта ошибка проявляется только на 32-ных реализациях. Скомпилировал код под 64 бита - всё нормально. Подозреваю, что как-то HEAP портится, но не могу понять - как. Прошу помощи. Вот полный код программы с алгоритмом:
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdlib.h>
static int
xmlBase64Decode(const unsigned char *in, unsigned long *inlen,
unsigned char *to, unsigned long *tolen) {
unsigned long incur; /* current index in in[] */
unsigned long inblk; /* last block index in in[] */
unsigned long outcur; /* current index in out[] */
unsigned long inmax; /* size of in[] */
unsigned long outmax; /* size of out[] */
unsigned char cur; /* the current value read from in[] */
unsigned char intmp[3], outtmp[4]; /* temporary buffers for the convert */
int nbintmp; /* number of byte in intmp[] */
int is_ignore; /* cur should be ignored */
int is_end = 0; /* the end of the base64 was found */
int retval = 1;
int i;
if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
return(-1);
incur = 0;
inblk = 0;
outcur = 0;
inmax = *inlen;
outmax = *tolen;
nbintmp = 0;
while (1) {
if (incur >= inmax)
break;
cur = in[incur++];
is_ignore = 0;
if ((cur >= 'A') && (cur <= 'Z'))
cur = cur - 'A';
else if ((cur >= 'a') && (cur <= 'z'))
cur = cur - 'a' + 26;
else if ((cur >= '0') && (cur <= '9'))
cur = cur - '0' + 52;
else if (cur == '+')
cur = 62;
else if (cur == '/')
cur = 63;
else if (cur == '.')
cur = 0;
else if (cur == '=') /*no op , end of the base64 stream */
is_end = 1;
else {
is_ignore = 1;
if (nbintmp == 0)
inblk = incur;
}
if (!is_ignore) {
int nbouttmp = 3;
int is_break = 0;
if (is_end) {
if (nbintmp == 0)
break;
if ((nbintmp == 1) || (nbintmp == 2))
nbouttmp = 1;
else
nbouttmp = 2;
nbintmp = 3;
is_break = 1;
}
intmp[nbintmp++] = cur;
/*
* if intmp is full, push the 4byte sequence as a 3 byte
* sequence out
*/
if (nbintmp == 4) {
nbintmp = 0;
outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);
outtmp[1] =
((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);
outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);
if (outcur + 3 >= outmax) {
retval = 2;
break;
}
for (i = 0; i < nbouttmp; i++)
to[outcur++] = outtmp[i];
inblk = incur;
}
if (is_break) {
retval = 0;
break;
}
}
}
*tolen = outcur;
*inlen = inblk;
return (retval);
}
int main (void){
const unsigned char *in_buf = "ABUACwEAAAYAHQAAAAm0BQMAAAEAAAMA";
unsigned long in_len = strlen(in_buf);
unsigned long out_len = (in_len * 6) / 8;
unsigned char *out_buf = NULL;
out_buf = malloc(out_len);
if (out_buf != NULL){
memset(out_buf, 0, out_len);
xmlBase64Decode((const unsigned char *)in_buf,(unsigned long *) &in_len, (unsigned char *) out_buf,(unsigned long *) &out_len);
}
if (out_len != 0)
{
int i;
char *prn_buf = NULL;
char temp_buf[3];
int prn_buf_len = out_len * 3 + 1;
prn_buf = malloc(prn_buf_len);
if (prn_buf != NULL){
memset(prn_buf, 0, prn_buf_len);
for (i = 0; i < out_len; i++){
sprintf(&temp_buf[0], " %.2X", out_buf[i]);
prn_buf[i * 3] = temp_buf[0];
prn_buf[i * 3 + 1] = temp_buf[1];
prn_buf[i * 3 + 2] = temp_buf[2];
}
prn_buf[out_len * 3] = 0;
printf("Packet = [%s]", prn_buf);
free(prn_buf);
}
}
}