# HG changeset patch # User Carl Byington # Date 1220983916 25200 # Node ID 997cf1373f9e5954a568f7b49c291e8bda7cde7d # Parent cb14583c119a6cbbc39e5ad8550cbd378fe22b14 fix base64 encoding that could create long lines diff -r cb14583c119a -r 997cf1373f9e regression/regression-tests.bash --- a/regression/regression-tests.bash Thu Aug 28 15:25:53 2008 -0700 +++ b/regression/regression-tests.bash Tue Sep 09 11:11:56 2008 -0700 @@ -28,10 +28,13 @@ fi $val ../src/pst2ldif -b 'o=ams-cc.com, c=US' -c 'newPerson' ams.pst >ams.err 2>&1 -$val ../src/readpst -cv -o output1 ams.pst >out1.err 2>&1 + +$val ../src/readpst -cv -o output1 -d dumper ams.pst >out1.err 2>&1 + ../src/readpstlog -f I dumper >ams1.log + $val ../src/readpst -cl -r -o output2 ams.pst >out2.err 2>&1 $val ../src/readpst -S -o output3 ams.pst >out3.err 2>&1 -$val ../src/readpst -M -o output4 -d dumper ams.pst >out4.err 2>&1 +$val ../src/readpst -M -o output4 -d dumper ams.pst >out4.err 2>&1 ../src/readpstlog -f I dumper >ams.log $val ../src/readpst -o output5 -d dumper mbmg.archive.pst >out5.err 2>&1 @@ -43,8 +46,8 @@ $val ../src/readpst -cv -o output7 -d dumper sample_64.pst >out7.err 2>&1 ../src/readpstlog -f I dumper >sample_64.log -$val ../src/readpst -cv -o output8 -d dumper big_mail.pst >out8.err 2>&1 - ../src/readpstlog -f I dumper >big_mail.log +#$val ../src/readpst -cv -o output8 -d dumper big_mail.pst >out8.err 2>&1 +# ../src/readpstlog -f I dumper >big_mail.log $val ../src/readpst -cv -o output9 -d dumper Single2003-read.pst >out9.err 2>&1 ../src/readpstlog -f I dumper >Single2003-read.log diff -r cb14583c119a -r 997cf1373f9e src/libpst.c --- a/src/libpst.c Thu Aug 28 15:25:53 2008 -0700 +++ b/src/libpst.c Tue Sep 09 11:11:56 2008 -0700 @@ -268,7 +268,7 @@ size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b){ size_t size=0; pst_index_ll *ptr; - pst_holder h = {b, NULL, 0, "", 0}; + pst_holder h = {b, NULL, 0}; DEBUG_ENT("pst_attach_to_mem"); if (attach->id_val != (uint64_t)-1) { ptr = pst_getID(pf, attach->id_val); @@ -289,7 +289,7 @@ size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { pst_index_ll *ptr; - pst_holder h = {NULL, fp, 0, "", 0}; + pst_holder h = {NULL, fp, 0}; size_t size = 0; int32_t x; DEBUG_ENT("pst_attach_to_file"); @@ -319,7 +319,7 @@ size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { pst_index_ll *ptr; - pst_holder h = {NULL, fp, 1, "", 0}; + pst_holder h = {NULL, fp, 1}; size_t size = 0; int32_t x; char *c; @@ -338,12 +338,6 @@ // } // } size = pst_ff_getID2data(pf, ptr, &h); - // will need to encode any bytes left over - c = base64_encode(h.base64_extra_chars, (size_t)h.base64_extra); - if (c) { - (void)pst_fwrite(c, (size_t)1, strlen(c), fp); - free(c); // caught by valgrind - } } else { DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); } @@ -1241,36 +1235,39 @@ // each attachment attach = item->attach; while (attach) { - if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) { - // id_ptr is a record describing the attachment - // we pass NULL instead of id2_head cause we don't want it to - // load all the extra stuff here. - if ((list = pst_parse_block(pf, id_ptr->id, NULL, NULL)) == NULL) { - DEBUG_WARN(("ERROR error processing an attachment record\n")); - attach = attach->next; - continue; - } - if (pst_process(list, item, attach)) { - DEBUG_WARN(("ERROR pst_process() failed with an attachment\n")); - if (list) pst_free_list(list); - list = NULL; - attach = attach->next; - continue; - } - if (list) pst_free_list(list); - list = NULL; - id_ptr = pst_getID2(id2_head, attach->id2_val); - if (id_ptr) { - // id2_val has been updated to the ID2 value of the datablock containing the - // attachment data - attach->id_val = id_ptr->id; - } else { - DEBUG_WARN(("have not located the correct value for the attachment [%#"PRIx64"]\n", attach->id2_val)); - } - } else { - DEBUG_WARN(("ERROR cannot locate id2 value %#"PRIx64"\n", attach->id2_val)); - } - attach = attach->next; + DEBUG_WARN(("initial attachment id2 %#"PRIx64"\n", attach->id2_val)); + if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) { + DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id_ptr->id)); + // id_ptr is a record describing the attachment + // we pass NULL instead of id2_head cause we don't want it to + // load all the extra stuff here. + if ((list = pst_parse_block(pf, id_ptr->id, NULL, NULL)) == NULL) { + DEBUG_WARN(("ERROR error processing an attachment record\n")); + attach = attach->next; + continue; + } + if (pst_process(list, item, attach)) { + DEBUG_WARN(("ERROR pst_process() failed with an attachment\n")); + if (list) pst_free_list(list); + list = NULL; + attach = attach->next; + continue; + } + if (list) pst_free_list(list); + list = NULL; + id_ptr = pst_getID2(id2_head, attach->id2_val); + if (id_ptr) { + DEBUG_WARN(("second pass attachment updating id2 found id %#"PRIx64"\n", id_ptr->id)); + // id2_val has been updated to the ID2 value of the datablock containing the + // attachment data + attach->id_val = id_ptr->id; + } else { + DEBUG_WARN(("have not located the correct value for the attachment [%#"PRIx64"]\n", attach->id2_val)); + } + } else { + DEBUG_WARN(("ERROR cannot locate id2 value %#"PRIx64"\n", attach->id2_val)); + } + attach = attach->next; } } } @@ -1620,6 +1617,7 @@ na_ptr->items[x]->extra = mapptr->data; } else { + DEBUG_WARN(("Missing assertion failure\n")); // nothing, should be assertion failure here } } else { @@ -2184,7 +2182,6 @@ MALLOC_EMAIL(item); LIST_COPY(item->email->header, (char*)); DEBUG_EMAIL(("%s\n", item->email->header)); - DEBUG_EMAIL(("NOT PRINTED\n")); break; case 0x0C17: // PR_REPLY_REQUESTED DEBUG_EMAIL(("Reply Requested - ")); @@ -4406,7 +4403,7 @@ size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, char** buf) { size_t ret; pst_index_ll* ptr; - pst_holder h = {buf, NULL, 0, "", 0}; + pst_holder h = {buf, NULL, 0}; DEBUG_ENT("pst_ff_getID2block"); ptr = pst_getID2(id2_head, id2); @@ -4458,6 +4455,9 @@ uint16_t count, y; char *buf3 = NULL, *buf2 = NULL, *t; char *b_ptr; + int line_count = 0; + char base64_extra_chars[3]; + uint32_t base64_extra = 0; pst_block_hdr block_hdr; pst_table3_rec table3_rec; //for type 3 (0x0101) blocks @@ -4498,6 +4498,7 @@ } count = block_hdr.type; b_ptr = buf3 + 8; + line_count = 0; for (y=0; ybuf))[size]), buf2, z); } else if ((h->base64 == 1) && h->fp) { - // include any byte left over from the last one encoding - buf2 = (char*)realloc(buf2, z+h->base64_extra); - memmove(buf2+h->base64_extra, buf2, z); - memcpy(buf2, h->base64_extra_chars, h->base64_extra); - z += h->base64_extra; - - b = z % 3; // find out how many bytes will be left over after the encoding. - // and save them - memcpy(h->base64_extra_chars, &(buf2[z-b]), b); - h->base64_extra = b; - t = base64_encode(buf2, z-b); + if (base64_extra) { + // include any bytes left over from the last encoding + buf2 = (char*)realloc(buf2, z+base64_extra); + memmove(buf2+base64_extra, buf2, z); + memcpy(buf2, base64_extra_chars, base64_extra); + z += base64_extra; + } + + // find out how many bytes will be left over after this encoding and save them + base64_extra = z % 3; + if (base64_extra) { + z -= base64_extra; + memcpy(base64_extra_chars, buf2+z, base64_extra); + } + + // encode this chunk + t = base64_encode_multiple(buf2, z, &line_count); if (t) { DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); @@ -4537,6 +4544,14 @@ } size += z; } + if ((h->base64 == 1) && h->fp && base64_extra) { + // need to encode any bytes left over + t = base64_encode_multiple(base64_extra_chars, (size_t)base64_extra, &line_count); + if (t) { + (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); + free(t); // caught by valgrind + } + } free(buf3); if (buf2) free(buf2); DEBUG_RET(); diff -r cb14583c119a -r 997cf1373f9e src/libpst.h --- a/src/libpst.h Thu Aug 28 15:25:53 2008 -0700 +++ b/src/libpst.h Tue Sep 09 11:11:56 2008 -0700 @@ -537,11 +537,9 @@ typedef struct pst_holder { - char **buf; - FILE * fp; - int base64; - char base64_extra_chars[3]; - uint32_t base64_extra; + char **buf; + FILE *fp; + int base64; } pst_holder; diff -r cb14583c119a -r 997cf1373f9e src/libstrfunc.c --- a/src/libstrfunc.c Thu Aug 28 15:25:53 2008 -0700 +++ b/src/libstrfunc.c Tue Sep 09 11:11:56 2008 -0700 @@ -7,47 +7,61 @@ #include "libstrfunc.h" -static unsigned char _sf_uc_ib[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=="; +static char base64_code_chars[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=="; -char *base64_encode(void *data, size_t size) { +void base64_append(char **ou, int *line_count, char data) +{ + if (*line_count == 76) { + *(*ou)++ = '\n'; + *line_count = 0; + } + *(*ou)++ = data; + (*line_count)++; +} + + +char *base64_encode(void *data, size_t size) +{ + int line_count = 0; + return base64_encode_multiple(data, size, &line_count); +} + + +char *base64_encode_multiple(void *data, size_t size, int *line_count) +{ char *output; - register char *ou; - register unsigned char *p=(unsigned char *)data; - register void * dte = (void*)((char*)data + size); - register int nc=0; + char *ou; + unsigned char *p = (unsigned char *)data; + unsigned char *dte = p + size; - if ( data == NULL || size == 0 ) return NULL; + if (data == NULL || size == 0) return NULL; ou = output = (char *)malloc(size / 3 * 4 + (size / 57) + 5); - if(!output) return NULL; + if (!output) return NULL; - while((char *)dte - (char *)p >= 3) { + while((dte-p) >= 3) { unsigned char x = p[0]; unsigned char y = p[1]; unsigned char z = p[2]; - ou[0] = _sf_uc_ib[ x >> 2 ]; - ou[1] = _sf_uc_ib[ ((x & 0x03) << 4) | (y >> 4) ]; - ou[2] = _sf_uc_ib[ ((y & 0x0F) << 2) | (z >> 6) ]; - ou[3] = _sf_uc_ib[ z & 0x3F ]; + base64_append(&ou, line_count, base64_code_chars[ x >> 2 ]); + base64_append(&ou, line_count, base64_code_chars[ ((x & 0x03) << 4) | (y >> 4) ]); + base64_append(&ou, line_count, base64_code_chars[ ((y & 0x0F) << 2) | (z >> 6) ]); + base64_append(&ou, line_count, base64_code_chars[ z & 0x3F ]); p+=3; - ou+=4; - nc+=4; - if(!(nc % 76)) *ou++='\n'; }; - if ((char *)dte - (char *)p == 2) { - *ou++ = _sf_uc_ib[ *p >> 2 ]; - *ou++ = _sf_uc_ib[ ((*p & 0x03) << 4) | (p[1] >> 4) ]; - *ou++ = _sf_uc_ib[ ((p[1] & 0x0F) << 2) ]; - *ou++ = '='; - } else if((char *)dte - (char *)p == 1) { - *ou++ = _sf_uc_ib[ *p >> 2 ]; - *ou++ = _sf_uc_ib[ ((*p & 0x03) << 4) ]; - *ou++ = '='; - *ou++ = '='; + if ((dte-p) == 2) { + base64_append(&ou, line_count, base64_code_chars[ *p >> 2 ]); + base64_append(&ou, line_count, base64_code_chars[ ((*p & 0x03) << 4) | (p[1] >> 4) ]); + base64_append(&ou, line_count, base64_code_chars[ ((p[1] & 0x0F) << 2) ]); + base64_append(&ou, line_count, '='); + } else if ((dte-p) == 1) { + base64_append(&ou, line_count, base64_code_chars[ *p >> 2 ]); + base64_append(&ou, line_count, base64_code_chars[ ((*p & 0x03) << 4) ]); + base64_append(&ou, line_count, '='); + base64_append(&ou, line_count, '='); }; *ou=0; - return output; }; diff -r cb14583c119a -r 997cf1373f9e src/libstrfunc.h --- a/src/libstrfunc.h Thu Aug 28 15:25:53 2008 -0700 +++ b/src/libstrfunc.h Tue Sep 09 11:11:56 2008 -0700 @@ -1,3 +1,4 @@ char * base64_encode(void *data, size_t size); +char * base64_encode_multiple(void *data, size_t size, int *line_count); void hexdump(char *hbuf, int start, int stop, int ascii);