# HG changeset patch # User Carl Byington # Date 1237253499 25200 # Node ID ab384fed78c5ed78c925cb8eb614ba0b7837a091 # Parent 03fbb0269f3cd59ce91c8df5c0a064e85c2e36da Compensate for iconv conversion to utf-7 that produces strings that are not null terminated. Don't produce empty attachment files in separate mode. diff -r 03fbb0269f3c -r ab384fed78c5 ChangeLog --- a/ChangeLog Mon Mar 16 12:43:31 2009 -0700 +++ b/ChangeLog Mon Mar 16 18:31:39 2009 -0700 @@ -4,6 +4,9 @@ * fix fedora 11 type mismatch warning (actually an error in this case). * fix large file support, some sytems require config.h to be included earlier in the compilation. + * compensate for iconv conversion to utf-7 that produces strings that + are not null terminated. + * don't produce empty attachment files in separate mode. LibPST 0.6.32 (2009-03-14) =============================== diff -r 03fbb0269f3c -r ab384fed78c5 regression/regression-tests.bash --- a/regression/regression-tests.bash Mon Mar 16 12:43:31 2009 -0700 +++ b/regression/regression-tests.bash Mon Mar 16 18:31:39 2009 -0700 @@ -38,7 +38,7 @@ mkdir output$n # ../src/readpst -cv -o output$n $fn >$ba.err 2>&1 # readpst -cv -o output$n -d dumper $fn >$ba.err 2>&1 - $val ../src/readpst -r -cv -o output$n -d dumper $fn >$ba.err 2>&1 + $val ../src/readpst -S -cv -o output$n -d dumper $fn >$ba.err 2>&1 ../src/readpstlog -f I dumper >$ba.log #../src/getidblock -d -p $fn 0 >$ba.fulldump @@ -50,12 +50,14 @@ val="valgrind --leak-check=full" -#val='' +val='' pushd .. make || exit popd +rm -rf output* *.err *.log + if [ "$1" == "dii" ]; then dodii 1 ams.pst dodii 2 sample_64.pst @@ -82,8 +84,9 @@ #doldif 18 test-mac.pst #doldif 19 harris.pst else + dopst 20 spam.pst + exit dopst 1 ams.pst - exit dopst 2 sample_64.pst dopst 3 test.pst dopst 4 big_mail.pst diff -r 03fbb0269f3c -r ab384fed78c5 src/dumpblocks.c --- a/src/dumpblocks.c Mon Mar 16 12:43:31 2009 -0700 +++ b/src/dumpblocks.c Mon Mar 16 18:31:39 2009 -0700 @@ -56,16 +56,16 @@ printf("Saving blocks\n"); while (ptr != NULL) { /* if (pstfile.encryption == PST_ENC) { - c = pst_ff_getIDblock_dec(&pstfile, ptr->id, buf); + c = pst_ff_getIDblock_dec(&pstfile, ptr->i_id, buf); } else { */ - if ((ptr->id & 0x02) == 0 && pstfile.encryption == PST_ENC) { - c = pst_ff_getIDblock_dec(&pstfile, ptr->id, &buf); + if ((ptr->i_id & 0x02) == 0 && pstfile.encryption == PST_ENC) { + c = pst_ff_getIDblock_dec(&pstfile, ptr->i_id, &buf); } else { - c = pst_ff_getIDblock(&pstfile, ptr->id, &buf); + c = pst_ff_getIDblock(&pstfile, ptr->i_id, &buf); } if (c > 0) { - snprintf(outname, OUT_BUF, "%#"PRIx64, ptr->id); + snprintf(outname, OUT_BUF, "%#"PRIx64, ptr->i_id); if ((fp = fopen(outname, "wb")) == NULL) { printf("Failed to open file %s\n", outname); continue; @@ -73,7 +73,7 @@ pst_fwrite(buf, 1, c, fp); fclose(fp); } else { - printf("Failed to read block id %#"PRIx64"\n", ptr->id); + printf("Failed to read block i_id %#"PRIx64"\n", ptr->i_id); } ptr = ptr->next; } diff -r 03fbb0269f3c -r ab384fed78c5 src/getidblock.c --- a/src/getidblock.c Mon Mar 16 12:43:31 2009 -0700 +++ b/src/getidblock.c Mon Mar 16 18:31:39 2009 -0700 @@ -17,44 +17,44 @@ } -void dumper(uint64_t id); -void dumper(uint64_t id) +void dumper(uint64_t i_id); +void dumper(uint64_t i_id) { char *buf = NULL; size_t readSize; pst_desc_ll *ptr; - DEBUG_MAIN(("\n\n\nLooking at block index1 id %#"PRIx64"\n", id)); + DEBUG_MAIN(("\n\n\nLooking at block index1 id %#"PRIx64"\n", i_id)); - if ((readSize = pst_ff_getIDblock_dec(&pstfile, id, &buf)) <= 0 || buf == 0) { + if ((readSize = pst_ff_getIDblock_dec(&pstfile, i_id, &buf)) <= 0 || buf == 0) { DIE(("Error loading block\n")); } - DEBUG_MAIN(("Printing block id %#"PRIx64", size %#"PRIx64"\n", id, (uint64_t)readSize)); + DEBUG_MAIN(("Printing block id %#"PRIx64", size %#"PRIx64"\n", i_id, (uint64_t)readSize)); if (binary) { if (fwrite(buf, 1, readSize, stdout) != 0) { DIE(("Error occured during writing of buf to stdout\n")); } } else { - printf("Block id %#"PRIx64", size %#"PRIx64"\n", id, (uint64_t)readSize); + printf("Block id %#"PRIx64", size %#"PRIx64"\n", i_id, (uint64_t)readSize); pst_debug_hexdumper(stdout, buf, readSize, 0x10, 0); } if (buf) free(buf); if (process) { - DEBUG_MAIN(("Parsing block id %#"PRIx64"\n", id)); + DEBUG_MAIN(("Parsing block id %#"PRIx64"\n", i_id)); ptr = pstfile.d_head; while (ptr) { - if (ptr->assoc_tree && ptr->assoc_tree->id == id) + if (ptr->assoc_tree && ptr->assoc_tree->i_id == i_id) break; - if (ptr->desc && ptr->desc->id == id) + if (ptr->desc && ptr->desc->i_id == i_id) break; ptr = pst_getNextDptr(ptr); } if (!ptr) { ptr = (pst_desc_ll *) xmalloc(sizeof(pst_desc_ll)); memset(ptr, 0, sizeof(pst_desc_ll)); - ptr->desc = pst_getID(&pstfile, id); + ptr->desc = pst_getID(&pstfile, i_id); } pst_item *item = pst_parse_item(&pstfile, ptr, NULL); if (item) pst_freeItem(item); @@ -67,8 +67,8 @@ { while (ptr) { DEBUG_MAIN(("\n\n\nLooking at block desc id %#"PRIx64"\n", ptr->d_id)); - if (ptr->desc && ptr->desc->id) dumper(ptr->desc->id); - if (ptr->assoc_tree && ptr->assoc_tree->id) dumper(ptr->assoc_tree->id); + if (ptr->desc && ptr->desc->i_id) dumper(ptr->desc->i_id); + if (ptr->assoc_tree && ptr->assoc_tree->i_id) dumper(ptr->assoc_tree->i_id); if (ptr->child) dump_desc(ptr->child); ptr = ptr->next; } @@ -79,7 +79,7 @@ { // pass the id number to display on the command line char *fname, *sid; - uint64_t id; + uint64_t i_id; int c; DEBUG_INIT("getidblock.log"); @@ -109,7 +109,7 @@ } fname = argv[optind]; sid = argv[optind + 1]; - id = (uint64_t)strtoll(sid, NULL, 0); + i_id = (uint64_t)strtoll(sid, NULL, 0); DEBUG_MAIN(("Opening file\n")); memset(&pstfile, 0, sizeof(pstfile)); @@ -122,13 +122,13 @@ DIE(("Error loading file index\n")); } - if (id) { - dumper(id); + if (i_id) { + dumper(i_id); } else { pst_index_ll *ptr = pstfile.i_head; while (ptr) { - dumper(ptr->id); + dumper(ptr->i_id); ptr = ptr->next; } dump_desc(pstfile.d_head); diff -r 03fbb0269f3c -r ab384fed78c5 src/libpst.c --- a/src/libpst.c Mon Mar 16 12:43:31 2009 -0700 +++ b/src/libpst.c Mon Mar 16 18:31:39 2009 -0700 @@ -409,8 +409,8 @@ pst_index_ll *ptr; 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); + if (attach->i_id != (uint64_t)-1) { + ptr = pst_getID(pf, attach->i_id); if (ptr) { size = pst_ff_getID2data(pf, ptr, &h); } else { @@ -431,8 +431,8 @@ pst_holder h = {NULL, fp, 0}; size_t size = 0; DEBUG_ENT("pst_attach_to_file"); - if (attach->id_val != (uint64_t)-1) { - ptr = pst_getID(pf, attach->id_val); + if (attach->i_id != (uint64_t)-1) { + ptr = pst_getID(pf, attach->i_id); if (ptr) { size = pst_ff_getID2data(pf, ptr, &h); } else { @@ -454,8 +454,8 @@ pst_holder h = {NULL, fp, 1}; size_t size = 0; DEBUG_ENT("pst_attach_to_file_base64"); - if (attach->id_val != (uint64_t)-1) { - ptr = pst_getID(pf, attach->id_val); + if (attach->i_id != (uint64_t)-1) { + ptr = pst_getID(pf, attach->i_id); if (ptr) { size = pst_ff_getID2data(pf, ptr, &h); } else { @@ -550,7 +550,7 @@ DEBUG_WARN(("Have not been able to fetch any id2 values for item 0x61. Brace yourself!\n")); } - na = pst_parse_block(pf, p->desc->id, id2_head); + na = pst_parse_block(pf, p->desc->i_id, id2_head); if (!na) { DEBUG_WARN(("Cannot process desc block for item 0x61. Not loading extended Attributes\n")); pst_free_id2(id2_head); @@ -894,7 +894,7 @@ } } i_ptr = (pst_index_ll*) xmalloc(sizeof(pst_index_ll)); - i_ptr->id = index.id; + i_ptr->i_id = index.id; i_ptr->offset = index.offset; i_ptr->u1 = index.u1; i_ptr->size = index.size; @@ -1092,9 +1092,9 @@ } pst_printID2ptr(id2_head); - list = pst_parse_block(pf, d_ptr->desc->id, id2_head); + list = pst_parse_block(pf, d_ptr->desc->i_id, id2_head); if (!list) { - DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->id [%#"PRIx64"]\n", d_ptr->desc->id)); + DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->i_id [%#"PRIx64"]\n", d_ptr->desc->i_id)); if (!m_head) pst_free_id2(id2_head); DEBUG_RET(); return NULL; @@ -1116,7 +1116,7 @@ if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x692))) { // DSN/MDN reports? DEBUG_EMAIL(("DSN/MDN processing\n")); - list = pst_parse_block(pf, id2_ptr->id->id, id2_head); + list = pst_parse_block(pf, id2_ptr->id->i_id, id2_head); if (!list) { DEBUG_WARN(("ERROR error processing main DSN/MDN record\n")); if (!m_head) pst_free_id2(id2_head); @@ -1142,7 +1142,7 @@ if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x671))) { DEBUG_EMAIL(("ATTACHMENT processing attachment\n")); - list = pst_parse_block(pf, id2_ptr->id->id, id2_head); + list = pst_parse_block(pf, id2_ptr->id->i_id, id2_head); if (!list) { DEBUG_WARN(("ERROR error processing main attachment record\n")); if (!m_head) pst_free_id2(id2_head); @@ -1172,11 +1172,11 @@ while (attach) { DEBUG_WARN(("initial attachment id2 %#"PRIx64"\n", attach->id2_val)); if ((id2_ptr = pst_getID2(id2_head, attach->id2_val))) { - DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id2_ptr->id->id)); + DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id2_ptr->id->i_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. - list = pst_parse_block(pf, id2_ptr->id->id, NULL); + list = pst_parse_block(pf, id2_ptr->id->i_id, NULL); if (!list) { DEBUG_WARN(("ERROR error processing an attachment record\n")); attach = attach->next; @@ -1194,10 +1194,10 @@ pst_free_list(list); id2_ptr = pst_getID2(id2_head, attach->id2_val); if (id2_ptr) { - DEBUG_WARN(("second pass attachment updating id2 found id %#"PRIx64"\n", id2_ptr->id->id)); + DEBUG_WARN(("second pass attachment updating id2 found i_id %#"PRIx64"\n", id2_ptr->id->i_id)); // id2_val has been updated to the ID2 value of the datablock containing the // attachment data - attach->id_val = id2_ptr->id->id; + attach->i_id = id2_ptr->id->i_id; attach->id2_head = deep_copy(id2_ptr->child); } else { DEBUG_WARN(("have not located the correct value for the attachment [%#"PRIx64"]\n", attach->id2_val)); @@ -1662,30 +1662,29 @@ if (table_rec.ref_type == (uint16_t)0x1f) { // there is more to do for the type 0x1f unicode strings size_t rc; - static vbuf *strbuf = NULL; - static vbuf *unibuf = NULL; - if (!strbuf) strbuf=vballoc((size_t)1024); - if (!unibuf) unibuf=vballoc((size_t)1024); + static vbuf *utf16buf = NULL; + static vbuf *utf8buf = NULL; + if (!utf16buf) utf16buf = vballoc((size_t)1024); + if (!utf8buf) utf8buf = vballoc((size_t)1024); // splint barfed on the following lines - //VBUF_STATIC(strbuf, 1024); - //VBUF_STATIC(unibuf, 1024); + //VBUF_STATIC(utf16buf, 1024); + //VBUF_STATIC(utf8buf, 1024); //need UTF-16 zero-termination - vbset(strbuf, mo_ptr->elements[x]->data, mo_ptr->elements[x]->size); - vbappend(strbuf, "\0\0", (size_t)2); + vbset(utf16buf, mo_ptr->elements[x]->data, mo_ptr->elements[x]->size); + vbappend(utf16buf, "\0\0", (size_t)2); DEBUG_INDEX(("Iconv in:\n")); - DEBUG_HEXDUMPC(strbuf->b, strbuf->dlen, 0x10); - rc = vb_utf16to8(unibuf, strbuf->b, strbuf->dlen); + DEBUG_HEXDUMPC(utf16buf->b, utf16buf->dlen, 0x10); + rc = vb_utf16to8(utf8buf, utf16buf->b, utf16buf->dlen); if (rc == (size_t)-1) { - free(unibuf->b); DEBUG_EMAIL(("Failed to convert utf-16 to utf-8\n")); } else { free(mo_ptr->elements[x]->data); - mo_ptr->elements[x]->size = unibuf->dlen; - mo_ptr->elements[x]->data = xmalloc(unibuf->dlen); - memcpy(mo_ptr->elements[x]->data, unibuf->b, unibuf->dlen); + mo_ptr->elements[x]->size = utf8buf->dlen; + mo_ptr->elements[x]->data = xmalloc(utf8buf->dlen); + memcpy(mo_ptr->elements[x]->data, utf8buf->b, utf8buf->dlen); } DEBUG_INDEX(("Iconv out:\n")); DEBUG_HEXDUMPC(mo_ptr->elements[x]->data, mo_ptr->elements[x]->size, 0x10); @@ -3061,7 +3060,7 @@ } DEBUG_INDEX(("ID %#"PRIx64" is likely to be a description record. Count is %i (offset %#"PRIx64")\n", - list->id, block_head.count, list->offset)); + list->i_id, block_head.count, list->offset)); x = 0; b_ptr = buf + ((pf->do_read64) ? 0x08 : 0x04); while (x < block_head.count) { @@ -3071,7 +3070,7 @@ DEBUG_WARN(("%#"PRIx64" - Not Found\n", id2_rec.id)); } else { DEBUG_INDEX(("%#"PRIx64" - Offset %#"PRIx64", u1 %#"PRIx64", Size %"PRIi64"(%#"PRIx64")\n", - i_ptr->id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); + i_ptr->i_id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); // add it to the tree i2_ptr = (pst_id2_ll*) xmalloc(sizeof(pst_id2_ll)); i2_ptr->id2 = id2_rec.id2; @@ -3393,25 +3392,25 @@ } -pst_index_ll* pst_getID(pst_file* pf, uint64_t id) { +pst_index_ll* pst_getID(pst_file* pf, uint64_t i_id) { pst_index_ll *ptr; DEBUG_ENT("pst_getID"); - if (id == 0) { + if (i_id == 0) { DEBUG_RET(); return NULL; } - //if (id & 1) DEBUG_INDEX(("have odd id bit %#"PRIx64"\n", id)); - //if (id & 2) DEBUG_INDEX(("have two id bit %#"PRIx64"\n", id)); - id -= (id & 1); - - DEBUG_INDEX(("Trying to find %#"PRIx64"\n", id)); + //if (i_id & 1) DEBUG_INDEX(("have odd id bit %#"PRIx64"\n", i_id)); + //if (i_id & 2) DEBUG_INDEX(("have two id bit %#"PRIx64"\n", i_id)); + i_id -= (i_id & 1); + + DEBUG_INDEX(("Trying to find %#"PRIx64"\n", i_id)); ptr = pf->i_head; - while (ptr && (ptr->id != id)) { + while (ptr && (ptr->i_id != i_id)) { ptr = ptr->next; } - if (ptr) {DEBUG_INDEX(("Found Value %#"PRIx64"\n", id)); } - else {DEBUG_INDEX(("ERROR: Value %#"PRIx64" not found\n", id)); } + if (ptr) {DEBUG_INDEX(("Found Value %#"PRIx64"\n", i_id)); } + else {DEBUG_INDEX(("ERROR: Value %#"PRIx64" not found\n", i_id)); } DEBUG_RET(); return ptr; } @@ -3433,7 +3432,7 @@ ptr = ptr->next; } if (ptr && ptr->id) { - DEBUG_INDEX(("Found value %#"PRIx64"\n", ptr->id->id)); + DEBUG_INDEX(("Found value %#"PRIx64"\n", ptr->id->i_id)); DEBUG_RET(); return ptr; } @@ -3474,8 +3473,8 @@ DEBUG_ENT("pst_printDptr"); while (ptr) { DEBUG_INDEX(("%#"PRIx64" [%i] desc=%#"PRIx64", assoc tree=%#"PRIx64"\n", ptr->d_id, ptr->no_child, - (ptr->desc ? ptr->desc->id : (uint64_t)0), - (ptr->assoc_tree ? ptr->assoc_tree->id : (uint64_t)0))); + (ptr->desc ? ptr->desc->i_id : (uint64_t)0), + (ptr->assoc_tree ? ptr->assoc_tree->i_id : (uint64_t)0))); if (ptr->child) { pst_printDptr(pf, ptr->child); } @@ -3489,7 +3488,7 @@ pst_index_ll *ptr = pf->i_head; DEBUG_ENT("pst_printIDptr"); while (ptr) { - DEBUG_INDEX(("%#"PRIx64" offset=%#"PRIx64" size=%#"PRIx64"\n", ptr->id, ptr->offset, ptr->size)); + DEBUG_INDEX(("%#"PRIx64" offset=%#"PRIx64" size=%#"PRIx64"\n", ptr->i_id, ptr->offset, ptr->size)); ptr = ptr->next; } DEBUG_RET(); @@ -3499,7 +3498,7 @@ void pst_printID2ptr(pst_id2_ll *ptr) { DEBUG_ENT("pst_printID2ptr"); while (ptr) { - DEBUG_INDEX(("%#"PRIx64" id=%#"PRIx64"\n", ptr->id2, (ptr->id ? ptr->id->id : (uint64_t)0))); + DEBUG_INDEX(("%#"PRIx64" id=%#"PRIx64"\n", ptr->id2, (ptr->id ? ptr->id->i_id : (uint64_t)0))); if (ptr->child) pst_printID2ptr(ptr->child); ptr = ptr->next; } @@ -3739,8 +3738,8 @@ size_t ret; char *b = NULL, *t; DEBUG_ENT("pst_ff_getID2data"); - if (!(ptr->id & 0x02)) { - ret = pst_ff_getIDblock_dec(pf, ptr->id, &b); + if (!(ptr->i_id & 0x02)) { + ret = pst_ff_getIDblock_dec(pf, ptr->i_id, &b); if (h->buf) { *(h->buf) = b; } else if ((h->base64 == 1) && h->fp) { @@ -3760,7 +3759,7 @@ } else { // here we will assume it is a block that points to others DEBUG_READ(("Assuming it is a multi-block record because of it's id\n")); - ret = pst_ff_compile_ID(pf, ptr->id, h, (size_t)0); + ret = pst_ff_compile_ID(pf, ptr->i_id, h, (size_t)0); } DEBUG_RET(); return ret; diff -r 03fbb0269f3c -r ab384fed78c5 src/libpst.h --- a/src/libpst.h Mon Mar 16 12:43:31 2009 -0700 +++ b/src/libpst.h Mon Mar 16 18:31:39 2009 -0700 @@ -127,7 +127,7 @@ typedef struct pst_index_tree32 { - uint32_t id; + uint32_t i_id; uint32_t offset; uint32_t size; int32_t u1; @@ -136,7 +136,7 @@ typedef struct pst_index_tree { - uint64_t id; + uint64_t i_id; uint64_t offset; uint64_t size; int64_t u1; @@ -405,7 +405,7 @@ size_t size; uint64_t id2_val; /** calculated from id2_val during creation of record */ - uint64_t id_val; + uint64_t i_id; /** deep copy from child */ pst_id2_ll *id2_head; /** 0=no attachment, 1=attach by value, 2=attach by reference, 3=attach by reference resolve, 4=attach by reference only, 5=embedded message, 6=OLE */ @@ -630,9 +630,9 @@ int pst_getBlockOffsetPointer(pst_file *pf, pst_id2_ll *i2_head, pst_subblocks *subblocks, uint32_t offset, pst_block_offset_pointer *p); int pst_getBlockOffset(char *buf, size_t read_size, uint32_t i_offset, uint32_t offset, pst_block_offset *p); pst_id2_ll* pst_build_id2(pst_file *pf, pst_index_ll* list); -pst_index_ll* pst_getID(pst_file* pf, uint64_t id); +pst_index_ll* pst_getID(pst_file* pf, uint64_t i_id); pst_id2_ll* pst_getID2(pst_id2_ll * ptr, uint64_t id); -pst_desc_ll* pst_getDptr(pst_file *pf, uint64_t id); +pst_desc_ll* pst_getDptr(pst_file *pf, uint64_t d_id); size_t pst_read_block_size(pst_file *pf, int64_t offset, size_t size, char **buf); int pst_decrypt(uint64_t id, char *buf, size_t size, unsigned char type); uint64_t pst_getIntAt(pst_file *pf, char *buf); diff -r 03fbb0269f3c -r ab384fed78c5 src/lspst.c --- a/src/lspst.c Mon Mar 16 12:43:31 2009 -0700 +++ b/src/lspst.c Mon Mar 16 18:31:39 2009 -0700 @@ -59,7 +59,7 @@ ff.skip_count++; } else { - DEBUG_MAIN(("main: Desc Email ID %"PRIx64" [d_ptr->d_id = %"PRIx64"]\n", d_ptr->desc->id, d_ptr->d_id)); + DEBUG_MAIN(("main: Desc Email ID %"PRIx64" [d_ptr->d_id = %"PRIx64"]\n", d_ptr->desc->i_id, d_ptr->d_id)); item = pst_parse_item(&pstfile, d_ptr, NULL); DEBUG_MAIN(("main: About to process item @ %p.\n", item)); diff -r 03fbb0269f3c -r ab384fed78c5 src/readpst.c --- a/src/readpst.c Mon Mar 16 12:43:31 2009 -0700 +++ b/src/readpst.c Mon Mar 16 18:31:39 2009 -0700 @@ -137,7 +137,7 @@ ff.skip_count++; } else { - DEBUG_MAIN(("main: Desc Email ID %#"PRIx64" [d_ptr->d_id = %#"PRIx64"]\n", d_ptr->desc->id, d_ptr->d_id)); + DEBUG_MAIN(("main: Desc Email ID %#"PRIx64" [d_ptr->d_id = %#"PRIx64"]\n", d_ptr->desc->i_id, d_ptr->d_id)); item = pst_parse_item(&pstfile, d_ptr, NULL); DEBUG_MAIN(("main: About to process item\n")); @@ -410,6 +410,7 @@ void write_email_body(FILE *f, char *body) { char *n = body; DEBUG_ENT("write_email_body"); + DEBUG_INFO(("buffer pointer %p\n", body)); while (n) { if (strncmp(body, "From ", 5) == 0) fprintf(f, ">"); @@ -731,6 +732,16 @@ : attach->filename1.str; DEBUG_ENT("write_separate_attachment"); + if (!attach->data) { + // make sure we can fetch data from the id + pst_index_ll *ptr = pst_getID(pst, attach->i_id); + if (!ptr) { + DEBUG_WARN(("Couldn't find i_id %#"PRIx64". Cannot save attachment to file\n", attach->i_id)); + DEBUG_RET(); + return; + } + } + check_filename(f_name); if (!attach_filename) { // generate our own (dummy) filename for the attachement @@ -755,7 +766,7 @@ WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp)); } else { if (attach->data) - pst_fwrite(attach->data, 1, attach->size, fp); + pst_fwrite(attach->data, (size_t)1, attach->size, fp); else { (void)pst_attach_to_file(pst, attach, fp); } @@ -772,7 +783,7 @@ DEBUG_ENT("write_embedded_message"); fprintf(f_output, "\n--%s\n", boundary); fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype.str); - ptr = pst_getID(pf, attach->id_val); + ptr = pst_getID(pf, attach->i_id); pst_desc_ll d_ptr; d_ptr.d_id = 0; @@ -799,7 +810,7 @@ char *attach_filename; char *enc = NULL; // base64 encoded attachment DEBUG_ENT("write_inline_attachment"); - DEBUG_EMAIL(("Attachment Size is %i, pointer %p, id %d\n", attach->size, attach->data, attach->id_val)); + DEBUG_EMAIL(("Attachment Size is %"PRIu64", id %#"PRIx64"\n", (uint64_t)attach->size, attach->i_id)); if (attach->data) { enc = base64_encode (attach->data, attach->size); if (!enc) { @@ -810,7 +821,7 @@ } else { // make sure we can fetch data from the id - pst_index_ll *ptr = pst_getID(pst, attach->id_val); + pst_index_ll *ptr = pst_getID(pst, attach->i_id); if (!ptr) { DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to file\n")); DEBUG_RET(); @@ -1023,7 +1034,7 @@ size_t rc; DEBUG_EMAIL(("Convert %s utf-8 to %s\n", mime, charset)); vbuf *newer = vballoc(2); - rc = vb_utf8to8bit(newer, body->str, strlen(body->str) + 1, charset); + rc = vb_utf8to8bit(newer, body->str, strlen(body->str), charset); if (rc == (size_t)-1) { // unable to convert, change the charset to utf8 free(newer->b); @@ -1031,6 +1042,9 @@ charset = "utf-8"; } else { + // null terminate the output string + vbgrow(newer, 1); + newer->b[newer->dlen] = '\0'; free(body->str); body->str = newer->b; } @@ -1323,10 +1337,12 @@ find_rfc822_headers(extra_mime_headers); write_embedded_message(f_output, attach, boundary, pst, extra_mime_headers); } - else if (mode == MODE_SEPARATE && !mode_MH) - write_separate_attachment(f_name, attach, ++attach_num, pst); - else - write_inline_attachment(f_output, attach, boundary, pst); + else if (attach->data || attach->i_id) { + if (mode == MODE_SEPARATE && !mode_MH) + write_separate_attachment(f_name, attach, ++attach_num, pst); + else + write_inline_attachment(f_output, attach, boundary, pst); + } } } diff -r 03fbb0269f3c -r ab384fed78c5 src/vbuf.c --- a/src/vbuf.c Mon Mar 16 12:43:31 2009 -0700 +++ b/src/vbuf.c Mon Mar 16 18:31:39 2009 -0700 @@ -100,11 +100,10 @@ size_t icresult = (size_t)-1; size_t outbytesleft = 0; char *outbuf = NULL; + int myerrno; ASSERT(unicode_up, "vb_utf16to8() called before unicode started."); - - if (2 > dest->blen) vbresize(dest, 2); - dest->dlen = 0; + vbresize(dest, iblen); //Bad Things can happen if a non-zero-terminated utf16 string comes through here if (!utf16_is_terminated(inbuf, iblen)) @@ -114,12 +113,13 @@ outbytesleft = dest->blen - dest->dlen; outbuf = dest->b + dest->dlen; icresult = iconv(i16to8, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); + myerrno = errno; dest->dlen = outbuf - dest->b; - vbgrow(dest, inbytesleft); - } while ((size_t)-1 == icresult && E2BIG == errno); + if (inbytesleft) vbgrow(dest, inbytesleft); + } while ((size_t)-1 == icresult && E2BIG == myerrno); if (icresult == (size_t)-1) { - DEBUG_WARN(("iconv failure: %s\n", strerror(errno))); + DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); unicode_init(); return (size_t)-1; } @@ -158,20 +158,21 @@ size_t icresult = (size_t)-1; size_t outbytesleft = 0; char *outbuf = NULL; + int myerrno; vbresize(dest, 2*iblen); - dest->dlen = 0; do { outbytesleft = dest->blen - dest->dlen; outbuf = dest->b + dest->dlen; icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); + myerrno = errno; dest->dlen = outbuf - dest->b; if (inbytesleft) vbgrow(dest, 2*inbytesleft); - } while ((size_t)-1 == icresult && E2BIG == errno); + } while ((size_t)-1 == icresult && E2BIG == myerrno); if (icresult == (size_t)-1) { - WARN(("iconv failure: %s\n", strerror(errno))); + DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); unicode_init(); return (size_t)-1; } @@ -287,7 +288,6 @@ void vbset(vbuf * vb, void *b, size_t len) // set vbuf b size=len, resize if necessary, relen = how much to over-allocate { vbresize(vb, len); - memcpy(vb->b, b, len); vb->dlen = len; }