Mercurial > libpst
comparison src/libpst.c @ 94:997cf1373f9e
fix base64 encoding that could create long lines
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 09 Sep 2008 11:11:56 -0700 |
parents | cb14583c119a |
children | 57bc6251f8dd |
comparison
equal
deleted
inserted
replaced
93:cb14583c119a | 94:997cf1373f9e |
---|---|
266 | 266 |
267 | 267 |
268 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b){ | 268 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b){ |
269 size_t size=0; | 269 size_t size=0; |
270 pst_index_ll *ptr; | 270 pst_index_ll *ptr; |
271 pst_holder h = {b, NULL, 0, "", 0}; | 271 pst_holder h = {b, NULL, 0}; |
272 DEBUG_ENT("pst_attach_to_mem"); | 272 DEBUG_ENT("pst_attach_to_mem"); |
273 if (attach->id_val != (uint64_t)-1) { | 273 if (attach->id_val != (uint64_t)-1) { |
274 ptr = pst_getID(pf, attach->id_val); | 274 ptr = pst_getID(pf, attach->id_val); |
275 if (ptr) { | 275 if (ptr) { |
276 size = pst_ff_getID2data(pf, ptr, &h); | 276 size = pst_ff_getID2data(pf, ptr, &h); |
287 } | 287 } |
288 | 288 |
289 | 289 |
290 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { | 290 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { |
291 pst_index_ll *ptr; | 291 pst_index_ll *ptr; |
292 pst_holder h = {NULL, fp, 0, "", 0}; | 292 pst_holder h = {NULL, fp, 0}; |
293 size_t size = 0; | 293 size_t size = 0; |
294 int32_t x; | 294 int32_t x; |
295 DEBUG_ENT("pst_attach_to_file"); | 295 DEBUG_ENT("pst_attach_to_file"); |
296 if (attach->id_val != (uint64_t)-1) { | 296 if (attach->id_val != (uint64_t)-1) { |
297 ptr = pst_getID(pf, attach->id_val); | 297 ptr = pst_getID(pf, attach->id_val); |
317 } | 317 } |
318 | 318 |
319 | 319 |
320 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { | 320 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { |
321 pst_index_ll *ptr; | 321 pst_index_ll *ptr; |
322 pst_holder h = {NULL, fp, 1, "", 0}; | 322 pst_holder h = {NULL, fp, 1}; |
323 size_t size = 0; | 323 size_t size = 0; |
324 int32_t x; | 324 int32_t x; |
325 char *c; | 325 char *c; |
326 DEBUG_ENT("pst_attach_to_file_base64"); | 326 DEBUG_ENT("pst_attach_to_file_base64"); |
327 if (attach->id_val != (uint64_t)-1) { | 327 if (attach->id_val != (uint64_t)-1) { |
336 // (void)pst_fwrite(c, (size_t)1, strlen(c), fp); | 336 // (void)pst_fwrite(c, (size_t)1, strlen(c), fp); |
337 // free(c); // caught by valgrind | 337 // free(c); // caught by valgrind |
338 // } | 338 // } |
339 // } | 339 // } |
340 size = pst_ff_getID2data(pf, ptr, &h); | 340 size = pst_ff_getID2data(pf, ptr, &h); |
341 // will need to encode any bytes left over | |
342 c = base64_encode(h.base64_extra_chars, (size_t)h.base64_extra); | |
343 if (c) { | |
344 (void)pst_fwrite(c, (size_t)1, strlen(c), fp); | |
345 free(c); // caught by valgrind | |
346 } | |
347 } else { | 341 } else { |
348 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); | 342 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); |
349 } | 343 } |
350 attach->size = size; | 344 attach->size = size; |
351 } else { | 345 } else { |
1239 // now we will have initial information of each attachment stored in item->attach... | 1233 // now we will have initial information of each attachment stored in item->attach... |
1240 // we must now read the secondary record for each based on the id2 val associated with | 1234 // we must now read the secondary record for each based on the id2 val associated with |
1241 // each attachment | 1235 // each attachment |
1242 attach = item->attach; | 1236 attach = item->attach; |
1243 while (attach) { | 1237 while (attach) { |
1244 if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) { | 1238 DEBUG_WARN(("initial attachment id2 %#"PRIx64"\n", attach->id2_val)); |
1245 // id_ptr is a record describing the attachment | 1239 if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) { |
1246 // we pass NULL instead of id2_head cause we don't want it to | 1240 DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id_ptr->id)); |
1247 // load all the extra stuff here. | 1241 // id_ptr is a record describing the attachment |
1248 if ((list = pst_parse_block(pf, id_ptr->id, NULL, NULL)) == NULL) { | 1242 // we pass NULL instead of id2_head cause we don't want it to |
1249 DEBUG_WARN(("ERROR error processing an attachment record\n")); | 1243 // load all the extra stuff here. |
1250 attach = attach->next; | 1244 if ((list = pst_parse_block(pf, id_ptr->id, NULL, NULL)) == NULL) { |
1251 continue; | 1245 DEBUG_WARN(("ERROR error processing an attachment record\n")); |
1252 } | 1246 attach = attach->next; |
1253 if (pst_process(list, item, attach)) { | 1247 continue; |
1254 DEBUG_WARN(("ERROR pst_process() failed with an attachment\n")); | 1248 } |
1255 if (list) pst_free_list(list); | 1249 if (pst_process(list, item, attach)) { |
1256 list = NULL; | 1250 DEBUG_WARN(("ERROR pst_process() failed with an attachment\n")); |
1257 attach = attach->next; | 1251 if (list) pst_free_list(list); |
1258 continue; | 1252 list = NULL; |
1259 } | 1253 attach = attach->next; |
1260 if (list) pst_free_list(list); | 1254 continue; |
1261 list = NULL; | 1255 } |
1262 id_ptr = pst_getID2(id2_head, attach->id2_val); | 1256 if (list) pst_free_list(list); |
1263 if (id_ptr) { | 1257 list = NULL; |
1264 // id2_val has been updated to the ID2 value of the datablock containing the | 1258 id_ptr = pst_getID2(id2_head, attach->id2_val); |
1265 // attachment data | 1259 if (id_ptr) { |
1266 attach->id_val = id_ptr->id; | 1260 DEBUG_WARN(("second pass attachment updating id2 found id %#"PRIx64"\n", id_ptr->id)); |
1267 } else { | 1261 // id2_val has been updated to the ID2 value of the datablock containing the |
1268 DEBUG_WARN(("have not located the correct value for the attachment [%#"PRIx64"]\n", attach->id2_val)); | 1262 // attachment data |
1269 } | 1263 attach->id_val = id_ptr->id; |
1270 } else { | 1264 } else { |
1271 DEBUG_WARN(("ERROR cannot locate id2 value %#"PRIx64"\n", attach->id2_val)); | 1265 DEBUG_WARN(("have not located the correct value for the attachment [%#"PRIx64"]\n", attach->id2_val)); |
1272 } | 1266 } |
1273 attach = attach->next; | 1267 } else { |
1268 DEBUG_WARN(("ERROR cannot locate id2 value %#"PRIx64"\n", attach->id2_val)); | |
1269 } | |
1270 attach = attach->next; | |
1274 } | 1271 } |
1275 } | 1272 } |
1276 } | 1273 } |
1277 | 1274 |
1278 if (id2_head) pst_free_id2(id2_head); | 1275 if (id2_head) pst_free_id2(id2_head); |
1618 DEBUG_EMAIL(("Internet Header mapping found %#x\n", table_rec.type)); | 1615 DEBUG_EMAIL(("Internet Header mapping found %#x\n", table_rec.type)); |
1619 na_ptr->items[x]->id = (uint32_t)PST_ATTRIB_HEADER; | 1616 na_ptr->items[x]->id = (uint32_t)PST_ATTRIB_HEADER; |
1620 na_ptr->items[x]->extra = mapptr->data; | 1617 na_ptr->items[x]->extra = mapptr->data; |
1621 } | 1618 } |
1622 else { | 1619 else { |
1620 DEBUG_WARN(("Missing assertion failure\n")); | |
1623 // nothing, should be assertion failure here | 1621 // nothing, should be assertion failure here |
1624 } | 1622 } |
1625 } else { | 1623 } else { |
1626 na_ptr->items[x]->id = table_rec.type; | 1624 na_ptr->items[x]->id = table_rec.type; |
1627 } | 1625 } |
2182 case 0x007D: // PR_TRANSPORT_MESSAGE_HEADERS Internet Header | 2180 case 0x007D: // PR_TRANSPORT_MESSAGE_HEADERS Internet Header |
2183 DEBUG_EMAIL(("Internet Header - ")); | 2181 DEBUG_EMAIL(("Internet Header - ")); |
2184 MALLOC_EMAIL(item); | 2182 MALLOC_EMAIL(item); |
2185 LIST_COPY(item->email->header, (char*)); | 2183 LIST_COPY(item->email->header, (char*)); |
2186 DEBUG_EMAIL(("%s\n", item->email->header)); | 2184 DEBUG_EMAIL(("%s\n", item->email->header)); |
2187 DEBUG_EMAIL(("NOT PRINTED\n")); | |
2188 break; | 2185 break; |
2189 case 0x0C17: // PR_REPLY_REQUESTED | 2186 case 0x0C17: // PR_REPLY_REQUESTED |
2190 DEBUG_EMAIL(("Reply Requested - ")); | 2187 DEBUG_EMAIL(("Reply Requested - ")); |
2191 MALLOC_EMAIL(item); | 2188 MALLOC_EMAIL(item); |
2192 if (*(int16_t*)list->items[x]->data) { | 2189 if (*(int16_t*)list->items[x]->data) { |
4404 | 4401 |
4405 #define PST_PTR_BLOCK_SIZE 0x120 | 4402 #define PST_PTR_BLOCK_SIZE 0x120 |
4406 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, char** buf) { | 4403 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, char** buf) { |
4407 size_t ret; | 4404 size_t ret; |
4408 pst_index_ll* ptr; | 4405 pst_index_ll* ptr; |
4409 pst_holder h = {buf, NULL, 0, "", 0}; | 4406 pst_holder h = {buf, NULL, 0}; |
4410 DEBUG_ENT("pst_ff_getID2block"); | 4407 DEBUG_ENT("pst_ff_getID2block"); |
4411 ptr = pst_getID2(id2_head, id2); | 4408 ptr = pst_getID2(id2_head, id2); |
4412 | 4409 |
4413 if (!ptr) { | 4410 if (!ptr) { |
4414 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2)); | 4411 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2)); |
4456 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, pst_holder *h, size_t size) { | 4453 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, pst_holder *h, size_t size) { |
4457 size_t z, a, b; | 4454 size_t z, a, b; |
4458 uint16_t count, y; | 4455 uint16_t count, y; |
4459 char *buf3 = NULL, *buf2 = NULL, *t; | 4456 char *buf3 = NULL, *buf2 = NULL, *t; |
4460 char *b_ptr; | 4457 char *b_ptr; |
4458 int line_count = 0; | |
4459 char base64_extra_chars[3]; | |
4460 uint32_t base64_extra = 0; | |
4461 pst_block_hdr block_hdr; | 4461 pst_block_hdr block_hdr; |
4462 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks | 4462 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks |
4463 | 4463 |
4464 DEBUG_ENT("pst_ff_compile_ID"); | 4464 DEBUG_ENT("pst_ff_compile_ID"); |
4465 a = pst_ff_getIDblock(pf, id, &buf3); | 4465 a = pst_ff_getIDblock(pf, id, &buf3); |
4496 DEBUG_RET(); | 4496 DEBUG_RET(); |
4497 return a; | 4497 return a; |
4498 } | 4498 } |
4499 count = block_hdr.type; | 4499 count = block_hdr.type; |
4500 b_ptr = buf3 + 8; | 4500 b_ptr = buf3 + 8; |
4501 line_count = 0; | |
4501 for (y=0; y<count; y++) { | 4502 for (y=0; y<count; y++) { |
4502 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); | 4503 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); |
4503 z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); | 4504 z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); |
4504 if (!z) { | 4505 if (!z) { |
4505 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); | 4506 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); |
4511 if (h->buf) { | 4512 if (h->buf) { |
4512 *(h->buf) = realloc(*(h->buf), size+z+1); | 4513 *(h->buf) = realloc(*(h->buf), size+z+1); |
4513 DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); | 4514 DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); |
4514 memcpy(&((*(h->buf))[size]), buf2, z); | 4515 memcpy(&((*(h->buf))[size]), buf2, z); |
4515 } else if ((h->base64 == 1) && h->fp) { | 4516 } else if ((h->base64 == 1) && h->fp) { |
4516 // include any byte left over from the last one encoding | 4517 if (base64_extra) { |
4517 buf2 = (char*)realloc(buf2, z+h->base64_extra); | 4518 // include any bytes left over from the last encoding |
4518 memmove(buf2+h->base64_extra, buf2, z); | 4519 buf2 = (char*)realloc(buf2, z+base64_extra); |
4519 memcpy(buf2, h->base64_extra_chars, h->base64_extra); | 4520 memmove(buf2+base64_extra, buf2, z); |
4520 z += h->base64_extra; | 4521 memcpy(buf2, base64_extra_chars, base64_extra); |
4521 | 4522 z += base64_extra; |
4522 b = z % 3; // find out how many bytes will be left over after the encoding. | 4523 } |
4523 // and save them | 4524 |
4524 memcpy(h->base64_extra_chars, &(buf2[z-b]), b); | 4525 // find out how many bytes will be left over after this encoding and save them |
4525 h->base64_extra = b; | 4526 base64_extra = z % 3; |
4526 t = base64_encode(buf2, z-b); | 4527 if (base64_extra) { |
4528 z -= base64_extra; | |
4529 memcpy(base64_extra_chars, buf2+z, base64_extra); | |
4530 } | |
4531 | |
4532 // encode this chunk | |
4533 t = base64_encode_multiple(buf2, z, &line_count); | |
4527 if (t) { | 4534 if (t) { |
4528 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); | 4535 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); |
4529 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | 4536 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); |
4530 free(t); // caught by valgrind | 4537 free(t); // caught by valgrind |
4531 } | 4538 } |
4534 (void)pst_fwrite(buf2, (size_t)1, z, h->fp); | 4541 (void)pst_fwrite(buf2, (size_t)1, z, h->fp); |
4535 } else { | 4542 } else { |
4536 // h-> does not specify any output | 4543 // h-> does not specify any output |
4537 } | 4544 } |
4538 size += z; | 4545 size += z; |
4546 } | |
4547 if ((h->base64 == 1) && h->fp && base64_extra) { | |
4548 // need to encode any bytes left over | |
4549 t = base64_encode_multiple(base64_extra_chars, (size_t)base64_extra, &line_count); | |
4550 if (t) { | |
4551 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | |
4552 free(t); // caught by valgrind | |
4553 } | |
4539 } | 4554 } |
4540 free(buf3); | 4555 free(buf3); |
4541 if (buf2) free(buf2); | 4556 if (buf2) free(buf2); |
4542 DEBUG_RET(); | 4557 DEBUG_RET(); |
4543 return size; | 4558 return size; |