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;