comparison src/libpst.c @ 31:b88ceb81dba2

mege changes from Joe Nahmias
author carl
date Tue, 10 Jul 2007 17:17:28 -0700
parents 51d826f31329
children 12cac756bc05
comparison
equal deleted inserted replaced
30:45eccad4b606 31:b88ceb81dba2
117 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2, 117 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2,
118 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec}; /*0xff*/ 118 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec}; /*0xff*/
119 119
120 int32_t pst_open(pst_file *pf, char *name, char *mode) { 120 int32_t pst_open(pst_file *pf, char *name, char *mode) {
121 u_int32_t sig; 121 u_int32_t sig;
122 // unsigned char ind_type;
123 122
124 DEBUG_ENT("pst_open"); 123 DEBUG_ENT("pst_open");
124
125 if (!pf) {
126 WARN (("cannot be passed a NULL pst_file\n"));
127 DEBUG_RET();
128 return -1;
129 }
130 memset(pf, 0, sizeof(pst_file));
131
125 #ifdef _MSC_VER 132 #ifdef _MSC_VER
126 // set the default open mode for windows 133 // set the default open mode for windows
127 _fmode = _O_BINARY; 134 _fmode = _O_BINARY;
128 #endif //_MSC_VER 135 #endif //_MSC_VER
129
130 if (!pf) {
131 WARN (("cannot be passed a NULL pst_file\n"));
132 DEBUG_RET();
133 return -1;
134 }
135 memset(pf, 0, sizeof(pst_file));
136
137 if ((pf->fp = fopen(name, mode)) == NULL) { 136 if ((pf->fp = fopen(name, mode)) == NULL) {
138 WARN(("cannot open PST file. Error\n")); 137 WARN(("cannot open PST file. Error\n"));
139 DEBUG_RET(); 138 DEBUG_RET();
140 return -1; 139 return -1;
141 } 140 }
141
142 // Check pst file magic
142 if (fread(&sig, sizeof(sig), 1, pf->fp) == 0) { 143 if (fread(&sig, sizeof(sig), 1, pf->fp) == 0) {
143 fclose(pf->fp); 144 fclose(pf->fp);
144 WARN(("cannot read signature from PST file. Closing on error\n")); 145 WARN(("cannot read signature from PST file. Closing on error\n"));
145 DEBUG_RET(); 146 DEBUG_RET();
146 return -1; 147 return -1;
147 } 148 }
148 149 LE32_CPU(sig); // architecture independant byte-swapping (little, big, pdp)
149 // architecture independant byte-swapping (little, big, pdp)
150 LE32_CPU(sig);
151
152 DEBUG_INFO(("sig = %X\n", sig)); 150 DEBUG_INFO(("sig = %X\n", sig));
153 if (sig != PST_SIGNATURE) { 151 if (sig != PST_SIGNATURE) {
154 fclose(pf->fp); 152 fclose(pf->fp);
155 WARN(("not a PST file that I know. Closing with error\n")); 153 WARN(("not a PST file that I know. Closing with error\n"));
156 DEBUG_RET(); 154 DEBUG_RET();
157 return -1; 155 return -1;
158 } 156 }
157
158 // read index type
159 _pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(unsigned char)); 159 _pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(unsigned char));
160 DEBUG_INFO(("index_type = %i\n", pf->ind_type)); 160 DEBUG_INFO(("index_type = %i\n", pf->ind_type));
161 if (pf->ind_type != 0x0E) { 161 if (pf->ind_type != 0x0E) {
162 WARN(("unknown index structure. Could this be a new Outlook 2003 PST file?\n")); 162 WARN(("unknown index structure. Could this be a new Outlook 2003 PST file?\n"));
163 DEBUG_RET(); 163 DEBUG_RET();
164 return -1; 164 return -1;
165 } 165 }
166 166
167 // read encryption setting
167 _pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(unsigned char)); 168 _pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(unsigned char));
168 DEBUG_INFO(("encrypt = %i\n", pf->encryption)); 169 DEBUG_INFO(("encrypt = %i\n", pf->encryption));
169 170
170 _pst_getAtPos(pf->fp, SECOND_POINTER-4, &(pf->index2_count), sizeof(pf->index2_count)); 171 _pst_getAtPos(pf->fp, SECOND_POINTER-4, &(pf->index2_count), sizeof(pf->index2_count));
171 _pst_getAtPos(pf->fp, SECOND_POINTER, &(pf->index2), sizeof(pf->index2)); 172 _pst_getAtPos(pf->fp, SECOND_POINTER, &(pf->index2), sizeof(pf->index2));
238 ptr = _pst_getID(pf, attach->id_val); 239 ptr = _pst_getID(pf, attach->id_val);
239 if (ptr) { 240 if (ptr) {
240 size = _pst_ff_getID2data(pf, ptr, &h); 241 size = _pst_ff_getID2data(pf, ptr, &h);
241 } else { 242 } else {
242 DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n")); 243 DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n"));
243 } 244 size = 0;
244 attach->size = size; // may aswell update it to what is correct for this instance 245 }
246 attach->size = size; // may as well update it to what is correct for this instance
245 } else { 247 } else {
246 size = attach->size; 248 size = attach->size;
247 } 249 }
248 DEBUG_RET(); 250 DEBUG_RET();
249 return size; 251 return size;
259 ptr = _pst_getID(pf, attach->id_val); 261 ptr = _pst_getID(pf, attach->id_val);
260 if (ptr) { 262 if (ptr) {
261 size = _pst_ff_getID2data(pf, ptr, &h); 263 size = _pst_ff_getID2data(pf, ptr, &h);
262 } else { 264 } else {
263 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to file\n")); 265 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to file\n"));
266 size = 0;
264 } 267 }
265 attach->size = size; 268 attach->size = size;
266 } else { 269 } else {
267 // save the attachment to file 270 // save the attachment to file
268 size = attach->size; 271 size = attach->size;
283 ptr = _pst_getID(pf, attach->id_val); 286 ptr = _pst_getID(pf, attach->id_val);
284 if (ptr) { 287 if (ptr) {
285 size = _pst_ff_getID2data(pf, ptr, &h); 288 size = _pst_ff_getID2data(pf, ptr, &h);
286 // will need to encode any bytes left over 289 // will need to encode any bytes left over
287 c = base64_encode(h.base64_extra_chars, h.base64_extra); 290 c = base64_encode(h.base64_extra_chars, h.base64_extra);
288 pst_fwrite(c, 1, strlen(c), fp); 291 if (c) pst_fwrite(c, 1, strlen(c), fp);
289 } else { 292 } else {
290 DEBUG_WARN (("Couldn't find ID pointer. Cannot save attachement to Base64\n")); 293 DEBUG_WARN (("Couldn't find ID pointer. Cannot save attachement to Base64\n"));
294 size = 0;
291 } 295 }
292 attach->size = size; 296 attach->size = size;
293 } else { 297 } else {
294 // encode the attachment to the file 298 // encode the attachment to the file
295 c = base64_encode(attach->data, attach->size); 299 c = base64_encode(attach->data, attach->size);
296 pst_fwrite(c, 1, strlen(c), fp); 300 if (c) pst_fwrite(c, 1, strlen(c), fp);
297 size = attach->size; 301 size = attach->size;
298 } 302 }
299 DEBUG_RET(); 303 DEBUG_RET();
300 return 1; 304 return 1;
301 } 305 }
348 352
349 int32_t pst_load_extended_attributes(pst_file *pf) { 353 int32_t pst_load_extended_attributes(pst_file *pf) {
350 // for PST files this will load up ID2 0x61 and check it's "list" attribute. 354 // for PST files this will load up ID2 0x61 and check it's "list" attribute.
351 pst_desc_ll *p; 355 pst_desc_ll *p;
352 pst_num_array *na; 356 pst_num_array *na;
353 // pst_index_ll *list; 357 pst_index2_ll *list2;
354 pst_index2_ll *list2;//, *t;
355 unsigned char * buffer=NULL, *headerbuffer=NULL;//, *tc; 358 unsigned char * buffer=NULL, *headerbuffer=NULL;//, *tc;
356 pst_x_attrib xattrib; 359 pst_x_attrib xattrib;
357 int32_t bptr = 0, bsize, hsize, tint, err=0, x; 360 int32_t bptr = 0, bsize, hsize, tint, err=0, x;
358 pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL; 361 pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL;
359 char *wt;
360 362
361 DEBUG_ENT("pst_loadExtendedAttributes"); 363 DEBUG_ENT("pst_loadExtendedAttributes");
362 if ((p = _pst_getDptr(pf, 0x61)) == NULL) { 364 if ((p = _pst_getDptr(pf, 0x61)) == NULL) {
363 DEBUG_WARN(("Cannot find DescID 0x61 for loading the Extended Attributes\n")); 365 DEBUG_WARN(("Cannot find DescID 0x61 for loading the Extended Attributes\n"));
364 DEBUG_RET(); 366 DEBUG_RET();
388 } 390 }
389 x++; 391 x++;
390 } 392 }
391 393
392 if (!buffer) { 394 if (!buffer) {
395 if (na) _pst_free_list(na);
393 DEBUG_WARN(("No extended attributes buffer found. Not processing\n")); 396 DEBUG_WARN(("No extended attributes buffer found. Not processing\n"));
394 DEBUG_RET(); 397 DEBUG_RET();
395 return 0; 398 return 0;
396 } 399 }
397 400
412 xattrib.extended, xattrib.zero, xattrib.type, xattrib.map)); 415 xattrib.extended, xattrib.zero, xattrib.type, xattrib.map));
413 err=0; 416 err=0;
414 if (xattrib.type & 0x0001) { // if the Bit 1 is set 417 if (xattrib.type & 0x0001) { // if the Bit 1 is set
415 // pointer to Unicode field in buffer 418 // pointer to Unicode field in buffer
416 if (xattrib.extended < hsize) { 419 if (xattrib.extended < hsize) {
420 char *wt;
417 // copy the size of the header. It is 32 bit int 421 // copy the size of the header. It is 32 bit int
418 memcpy(&tint, &(headerbuffer[xattrib.extended]), sizeof(tint)); 422 memcpy(&tint, &(headerbuffer[xattrib.extended]), sizeof(tint));
419 LE32_CPU(tint); 423 LE32_CPU(tint);
420 wt = (char*) xmalloc(tint+2); // plus 2 for a uni-code zero 424 wt = (char*) xmalloc(tint+2); // plus 2 for a uni-code zero
421 memset(wt, 0, tint+2); 425 memset(wt, 0, tint+2);
422 memcpy(wt, &(headerbuffer[xattrib.extended+sizeof(tint)]), tint); 426 memcpy(wt, &(headerbuffer[xattrib.extended+sizeof(tint)]), tint);
423 ptr->data = _pst_wide_to_single(wt, tint); 427 ptr->data = _pst_wide_to_single(wt, tint);
428 free(wt);
424 DEBUG_INDEX(("Read string (converted from UTF-16): %s\n", ptr->data)); 429 DEBUG_INDEX(("Read string (converted from UTF-16): %s\n", ptr->data));
425 } else { 430 } else {
426 DEBUG_INDEX(("Cannot read outside of buffer [%i !< %i]\n", xattrib.extended, hsize)); 431 DEBUG_INDEX(("Cannot read outside of buffer [%i !< %i]\n", xattrib.extended, hsize));
427 } 432 }
428 ptr->mytype = PST_MAP_HEADER; 433 ptr->mytype = PST_MAP_HEADER;
461 LE16_CPU(xattrib.zero); 466 LE16_CPU(xattrib.zero);
462 LE16_CPU(xattrib.type); 467 LE16_CPU(xattrib.type);
463 LE16_CPU(xattrib.map); 468 LE16_CPU(xattrib.map);
464 bptr += sizeof(xattrib); 469 bptr += sizeof(xattrib);
465 } 470 }
466 if (buffer) free(buffer); 471 if (list2) _pst_free_id2(list2);
467 if (headerbuffer) free(headerbuffer); 472 if (na) _pst_free_list(na);
468 pf->x_head = p_head; 473 pf->x_head = p_head;
469 DEBUG_RET(); 474 DEBUG_RET();
470 return 1; 475 return 1;
471 } 476 }
472 477
979 DEBUG_WARN(("Have not been able to fetch any id2 values for this item. Brace yourself!\n")); 984 DEBUG_WARN(("Have not been able to fetch any id2 values for this item. Brace yourself!\n"));
980 } 985 }
981 986
982 if (!d_ptr->desc) { 987 if (!d_ptr->desc) {
983 DEBUG_WARN(("why is d_ptr->desc == NULL? I don't want to do anything else with this record\n")); 988 DEBUG_WARN(("why is d_ptr->desc == NULL? I don't want to do anything else with this record\n"));
989 if (id2_head) _pst_free_id2(id2_head);
984 DEBUG_RET(); 990 DEBUG_RET();
985 return NULL; 991 return NULL;
986 } 992 }
987 993
988 if ((list = _pst_parse_block(pf, d_ptr->desc->id, id2_head)) == NULL) { 994 if ((list = _pst_parse_block(pf, d_ptr->desc->id, id2_head)) == NULL) {
989 DEBUG_WARN(("_pst_parse_block() returned an error for d_ptr->desc->id [%#x]\n", d_ptr->desc->id)); 995 DEBUG_WARN(("_pst_parse_block() returned an error for d_ptr->desc->id [%#x]\n", d_ptr->desc->id));
996 if (id2_head) _pst_free_id2(id2_head);
990 DEBUG_RET(); 997 DEBUG_RET();
991 return NULL; 998 return NULL;
992 } 999 }
993 1000
994 item = (pst_item*) xmalloc(sizeof(pst_item)); 1001 item = (pst_item*) xmalloc(sizeof(pst_item));
995 memset(item, 0, sizeof(pst_item)); 1002 memset(item, 0, sizeof(pst_item));
996 1003
997 if (_pst_process(list, item)) { 1004 if (_pst_process(list, item)) {
998 DEBUG_WARN(("_pst_process() returned non-zero value. That is an error\n")); 1005 DEBUG_WARN(("_pst_process() returned non-zero value. That is an error\n"));
999 _pst_free_list(list); 1006 if (item) free(item);
1007 if (list) _pst_free_list(list);
1008 if (id2_head) _pst_free_id2(id2_head);
1000 DEBUG_RET(); 1009 DEBUG_RET();
1001 return NULL; 1010 return NULL;
1002 } else { 1011 } else {
1003 _pst_free_list(list); 1012 if (list) _pst_free_list(list);
1004 list = NULL; //_pst_process will free the items in the list 1013 list = NULL; //_pst_process will free the items in the list
1005 } 1014 }
1006 1015
1007 if ((id_ptr = _pst_getID2(id2_head, 0x671))) { 1016 if ((id_ptr = _pst_getID2(id2_head, 0x671))) {
1008 // attachements exist - so we will process them 1017 // attachements exist - so we will process them
1013 } 1022 }
1014 1023
1015 DEBUG_EMAIL(("ATTACHEMENT processing attachement\n")); 1024 DEBUG_EMAIL(("ATTACHEMENT processing attachement\n"));
1016 if ((list = _pst_parse_block(pf, id_ptr->id, id2_head)) == NULL) { 1025 if ((list = _pst_parse_block(pf, id_ptr->id, id2_head)) == NULL) {
1017 DEBUG_WARN(("ERROR error processing main attachment record\n")); 1026 DEBUG_WARN(("ERROR error processing main attachment record\n"));
1018 // DEBUG_RET(); 1027 if (item) free(item);
1019 // return NULL; 1028 if (id2_head) _pst_free_id2(id2_head);
1029 DEBUG_RET();
1030 return NULL;
1020 } 1031 }
1021 else { 1032 else {
1022 x = 0; 1033 x = 0;
1023 while (x < list->count_array) { 1034 while (x < list->count_array) {
1024 attach = (pst_item_attach*) xmalloc (sizeof(pst_item_attach)); 1035 attach = (pst_item_attach*) xmalloc (sizeof(pst_item_attach));
1028 x++; 1039 x++;
1029 } 1040 }
1030 1041
1031 if (_pst_process(list, item)) { 1042 if (_pst_process(list, item)) {
1032 DEBUG_WARN(("ERROR _pst_process() failed with attachments\n")); 1043 DEBUG_WARN(("ERROR _pst_process() failed with attachments\n"));
1033 _pst_free_list(list); 1044 if (item) free(item);
1045 if (list) _pst_free_list(list);
1046 if (id2_head) _pst_free_id2(id2_head);
1034 DEBUG_RET(); 1047 DEBUG_RET();
1035 return NULL; 1048 return NULL;
1036 } 1049 }
1037 _pst_free_list(list); 1050 if (list) _pst_free_list(list);
1051 list = NULL;
1038 1052
1039 // now we will have initial information of each attachment stored in item->attach... 1053 // now we will have initial information of each attachment stored in item->attach...
1040 // we must now read the secondary record for each based on the id2 val associated with 1054 // we must now read the secondary record for each based on the id2 val associated with
1041 // each attachment 1055 // each attachment
1042 attach = item->attach; 1056 attach = item->attach;
1050 attach = attach->next; 1064 attach = attach->next;
1051 continue; 1065 continue;
1052 } 1066 }
1053 if (_pst_process(list, item)) { 1067 if (_pst_process(list, item)) {
1054 DEBUG_WARN(("ERROR _pst_process() failed with an attachment\n")); 1068 DEBUG_WARN(("ERROR _pst_process() failed with an attachment\n"));
1055 _pst_free_list(list); 1069 if (list) _pst_free_list(list);
1070 list = NULL;
1056 attach = attach->next; 1071 attach = attach->next;
1057 continue; 1072 continue;
1058 } 1073 }
1059 _pst_free_list(list); 1074 if (list) _pst_free_list(list);
1075 list = NULL;
1060 if ((id_ptr = _pst_getID2(id2_head, attach->id2_val))) { 1076 if ((id_ptr = _pst_getID2(id2_head, attach->id2_val))) {
1061 // id2_val has been updated to the ID2 value of the datablock containing the 1077 // id2_val has been updated to the ID2 value of the datablock containing the
1062 // attachment data 1078 // attachment data
1063 attach->id_val = id_ptr->id; 1079 attach->id_val = id_ptr->id;
1064 } else { 1080 } else {
1071 } 1087 }
1072 } 1088 }
1073 } 1089 }
1074 1090
1075 _pst_free_id2(id2_head); 1091 _pst_free_id2(id2_head);
1092 id2_head = NULL;
1076 DEBUG_RET(); 1093 DEBUG_RET();
1077 return item; 1094 return item;
1078 } 1095 }
1079 1096
1080 1097
1279 } 1296 }
1280 1297
1281 fr_ptr += sizeof(table2_rec); 1298 fr_ptr += sizeof(table2_rec);
1282 } else { 1299 } else {
1283 WARN(("Missing code for block_type %i\n", block_type)); 1300 WARN(("Missing code for block_type %i\n", block_type));
1284 if (buf) free(buf); 1301 if (buf) free(buf);
1302 if (na_head) _pst_free_list(na_head);
1285 DEBUG_RET(); 1303 DEBUG_RET();
1286 return NULL; 1304 return NULL;
1287 } 1305 }
1288 cur_list++; // get ready to read next bit from list 1306 cur_list++; // get ready to read next bit from list
1289 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", 1307 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n",
1375 "Will change to 1 byte\n", block_offset.from, block_offset.to)); 1393 "Will change to 1 byte\n", block_offset.from, block_offset.to));
1376 na_ptr->items[x]->size = size = 0; // the malloc statement will add one to this 1394 na_ptr->items[x]->size = size = 0; // the malloc statement will add one to this
1377 } 1395 }
1378 1396
1379 // plus one for good luck (and strings) we will null terminate all reads 1397 // plus one for good luck (and strings) we will null terminate all reads
1380 na_ptr->items[x]->data = (char*) xmalloc(size+1); 1398 na_ptr->items[x]->data = (unsigned char*) xmalloc(size+1);
1381 memcpy(na_ptr->items[x]->data, &(buf[t_ptr]), size); 1399 memcpy(na_ptr->items[x]->data, &(buf[t_ptr]), size);
1382 na_ptr->items[x]->data[size] = '\0'; // null terminate buffer 1400 na_ptr->items[x]->data[size] = '\0'; // null terminate buffer
1383 1401
1384 if (table_rec.ref_type == 0xd) { 1402 if (table_rec.ref_type == 0xd) {
1385 // there is still more to do for the type of 0xD 1403 // there is still more to do for the type of 0xD
1405 //it can be used to convey information 1423 //it can be used to convey information
1406 // to later functions 1424 // to later functions
1407 na_ptr->items[x]->type = table_rec.ref_type; 1425 na_ptr->items[x]->type = table_rec.ref_type;
1408 } else { 1426 } else {
1409 WARN(("ERROR Unknown ref_type %#x\n", table_rec.ref_type)); 1427 WARN(("ERROR Unknown ref_type %#x\n", table_rec.ref_type));
1428 if (buf) free(buf);
1429 if (na_head) _pst_free_list(na_head);
1410 DEBUG_RET(); 1430 DEBUG_RET();
1411 return NULL; 1431 return NULL;
1412 } 1432 }
1413 x++; 1433 x++;
1414 } 1434 }
2998 DEBUG_EMAIL(("Birthday\n")); break; 3018 DEBUG_EMAIL(("Birthday\n")); break;
2999 case PST_APP_LABEL_ANNIVERSARY: 3019 case PST_APP_LABEL_ANNIVERSARY:
3000 DEBUG_EMAIL(("Anniversary\n")); break; 3020 DEBUG_EMAIL(("Anniversary\n")); break;
3001 case PST_APP_LABEL_PHONE_CALL: 3021 case PST_APP_LABEL_PHONE_CALL:
3002 DEBUG_EMAIL(("Phone Call\n")); break; 3022 DEBUG_EMAIL(("Phone Call\n")); break;
3023 }
3024 break;
3025 case 0x8215: // All day appointment flag
3026 DEBUG_EMAIL(("All day flag - "));
3027 MALLOC_APPOINTMENT(item);
3028 if (*(int16_t*)list->items[x]->data != 0) {
3029 DEBUG_EMAIL(("True\n"));
3030 item->appointment->all_day = 1;
3031 } else {
3032 DEBUG_EMAIL(("False\n"));
3033 item->appointment->all_day = 0;
3003 } 3034 }
3004 break; 3035 break;
3005 case 0x8234: // TimeZone as String 3036 case 0x8234: // TimeZone as String
3006 DEBUG_EMAIL(("TimeZone of times - ")); 3037 DEBUG_EMAIL(("TimeZone of times - "));
3007 MALLOC_APPOINTMENT(item); 3038 MALLOC_APPOINTMENT(item);
3241 char *buf = NULL; 3272 char *buf = NULL;
3242 pst_id2_assoc id2_rec; 3273 pst_id2_assoc id2_rec;
3243 pst_index_ll *i_ptr = NULL; 3274 pst_index_ll *i_ptr = NULL;
3244 pst_index2_ll *i2_ptr = NULL; 3275 pst_index2_ll *i2_ptr = NULL;
3245 DEBUG_ENT("_pst_build_id2"); 3276 DEBUG_ENT("_pst_build_id2");
3277
3246 if (head_ptr) { 3278 if (head_ptr) {
3247 head = head_ptr; 3279 head = head_ptr;
3248 while (head_ptr) head_ptr = (tail = head_ptr)->next; 3280 while (head_ptr) head_ptr = (tail = head_ptr)->next;
3249 } 3281 }
3250 if (_pst_read_block_size(pf, list->offset, list->size, &buf, PST_NO_ENC, 0) < list->size) { 3282 if (_pst_read_block_size(pf, list->offset, list->size, &buf, PST_NO_ENC, 0) < list->size) {
3251 //an error occured in block read 3283 //an error occured in block read
3252 WARN(("block read error occured. offset = %#x, size = %#x\n", list->offset, list->size)); 3284 WARN(("block read error occured. offset = %#x, size = %#x\n", list->offset, list->size));
3285 if (buf) free(buf);
3253 DEBUG_RET(); 3286 DEBUG_RET();
3254 return NULL; 3287 return NULL;
3255 } 3288 }
3256 DEBUG_HEXDUMPC(buf, list->size, 16); 3289 DEBUG_HEXDUMPC(buf, list->size, 16);
3257 3290
3259 LE16_CPU(block_head.type); 3292 LE16_CPU(block_head.type);
3260 LE16_CPU(block_head.count); 3293 LE16_CPU(block_head.count);
3261 3294
3262 if (block_head.type != 0x0002) { // some sort of constant? 3295 if (block_head.type != 0x0002) { // some sort of constant?
3263 WARN(("Unknown constant [%#x] at start of id2 values [offset %#x].\n", block_head.type, list->offset)); 3296 WARN(("Unknown constant [%#x] at start of id2 values [offset %#x].\n", block_head.type, list->offset));
3297 if (buf) free(buf);
3264 DEBUG_RET(); 3298 DEBUG_RET();
3265 return NULL; 3299 return NULL;
3266 } 3300 }
3267 3301
3268 DEBUG_INDEX(("ID %#x is likely to be a description record. Count is %i (offset %#x)\n", 3302 DEBUG_INDEX(("ID %#x is likely to be a description record. Count is %i (offset %#x)\n",
3511 } 3545 }
3512 DEBUG_RET(); 3546 DEBUG_RET();
3513 } 3547 }
3514 3548
3515 3549
3516 int32_t _pst_getBlockOffset(char *buf, int32_t read_size, int32_t i_offset, int32_t offset, pst_block_offset *p) { 3550 int32_t _pst_getBlockOffset(unsigned char *buf, int32_t read_size, int32_t i_offset, int32_t offset, pst_block_offset *p) {
3517 int32_t of1 = offset>>4; 3551 int32_t of1 = offset>>4;
3518 DEBUG_ENT("_pst_getBlockOffset"); 3552 DEBUG_ENT("_pst_getBlockOffset");
3519 if (!p || !buf || (i_offset == 0) || (i_offset+2+of1+sizeof(*p) > read_size)) { 3553 if (!p || !buf || (i_offset == 0) || (i_offset+2+of1+sizeof(*p) > read_size)) {
3520 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset)); 3554 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset));
3521 DEBUG_RET(); 3555 DEBUG_RET();
3677 int16_t count, y; 3711 int16_t count, y;
3678 char *buf2 = NULL, *buf3 = NULL; 3712 char *buf2 = NULL, *buf3 = NULL;
3679 unsigned char fdepth; 3713 unsigned char fdepth;
3680 pst_index_ll *ptr = NULL; 3714 pst_index_ll *ptr = NULL;
3681 size_t rsize, z; 3715 size_t rsize, z;
3716
3682 DEBUG_ENT("_pst_read_block_size"); 3717 DEBUG_ENT("_pst_read_block_size");
3683 DEBUG_READ(("Reading block from %#x, %i bytes\n", offset, size)); 3718 DEBUG_READ(("Reading block from %#x, %i bytes\n", offset, size));
3719
3684 fpos = ftell(pf->fp); 3720 fpos = ftell(pf->fp);
3685 fseek(pf->fp, offset, SEEK_SET); 3721 fseek(pf->fp, offset, SEEK_SET);
3686 if (*buf) { 3722 if (*buf) {
3687 DEBUG_READ(("Freeing old memory\n")); 3723 DEBUG_READ(("Freeing old memory\n"));
3688 free(*buf); 3724 free(*buf);
3689 } 3725 }
3690 3726
3691 *buf = (void*) xmalloc(size+1); //plus one so that we can NULL terminate it later 3727 *buf = (void*) xmalloc(size+1); //plus one so that we can NUL terminate it later
3692 rsize = fread(*buf, 1, size, pf->fp); 3728 rsize = fread(*buf, 1, size, pf->fp);
3693 if (rsize != size) { 3729 if (rsize != size) {
3694 DEBUG_WARN(("Didn't read all that I could. fread returned less [%i instead of %i]\n", rsize, size)); 3730 DEBUG_WARN(("Didn't read all that I could. fread returned less [%i instead of %i]\n", rsize, size));
3695 if (feof(pf->fp)) { 3731 if (feof(pf->fp)) {
3696 DEBUG_WARN(("We tried to read past the end of the file at [offset %#x, size %#x]\n", offset, size)); 3732 DEBUG_WARN(("We tried to read past the end of the file at [offset %#x, size %#x]\n", offset, size));
3892 ret = _pst_ff_getIDblock_dec(pf, ptr->id, &b); 3928 ret = _pst_ff_getIDblock_dec(pf, ptr->id, &b);
3893 if (h->buf) { 3929 if (h->buf) {
3894 *(h->buf) = b; 3930 *(h->buf) = b;
3895 } else if ((h->base64 == 1) && h->fp) { 3931 } else if ((h->base64 == 1) && h->fp) {
3896 t = base64_encode(b, ret); 3932 t = base64_encode(b, ret);
3897 pst_fwrite(t, 1, strlen(t), h->fp); 3933 if (t) pst_fwrite(t, 1, strlen(t), h->fp);
3898 free(b); 3934 free(b);
3899 } else if (h->fp) { 3935 } else if (h->fp) {
3900 pst_fwrite(b, 1, ret, h->fp); 3936 pst_fwrite(b, 1, ret, h->fp);
3901 free(b); 3937 free(b);
3902 } 3938 }
3921 u_int32_t x, b; 3957 u_int32_t x, b;
3922 unsigned char * buf3 = NULL, *buf2 = NULL, *t; 3958 unsigned char * buf3 = NULL, *buf2 = NULL, *t;
3923 unsigned char fdepth; 3959 unsigned char fdepth;
3924 3960
3925 DEBUG_ENT("_pst_ff_compile_ID"); 3961 DEBUG_ENT("_pst_ff_compile_ID");
3926 if ((a = _pst_ff_getIDblock(pf, id, &buf3))==0) 3962 if ((a = _pst_ff_getIDblock(pf, id, &buf3))==0) {
3963 if (buf3) free(buf3);
3927 return 0; 3964 return 0;
3965 }
3928 if ((buf3[0] != 0x1)) { // if bit 8 is set) { 3966 if ((buf3[0] != 0x1)) { // if bit 8 is set) {
3929 // if ((buf3)[0] != 0x1 && (buf3)[1] > 4) { 3967 // if ((buf3)[0] != 0x1 && (buf3)[1] > 4) {
3930 DEBUG_WARN(("WARNING: buffer doesn't start with 0x1, but I expected it to or doesn't have it's two-bit set!\n")); 3968 DEBUG_WARN(("WARNING: buffer doesn't start with 0x1, but I expected it to or doesn't have it's two-bit set!\n"));
3931 DEBUG_WARN(("Treating as normal buffer\n")); 3969 DEBUG_WARN(("Treating as normal buffer\n"));
3932 if (pf->encryption) _pst_decrypt(buf3, a, pf->encryption); 3970 if (pf->encryption) _pst_decrypt(buf3, a, pf->encryption);
3933 if (h->buf) 3971 if (h->buf)
3934 *(h->buf) = buf3; 3972 *(h->buf) = buf3;
3935 else if (h->base64 == 1 && h->fp) { 3973 else if (h->base64 == 1 && h->fp) {
3936 t = base64_encode(buf3, a); 3974 t = base64_encode(buf3, a);
3937 pst_fwrite(t, 1, strlen(t), h->fp); 3975 if (t) pst_fwrite(t, 1, strlen(t), h->fp);
3938 free(buf3); 3976 free(buf3);
3939 } else if (h->fp) { 3977 } else if (h->fp) {
3940 pst_fwrite(buf3, 1, a, h->fp); 3978 pst_fwrite(buf3, 1, a, h->fp);
3941 free(buf3); 3979 free(buf3);
3942 } 3980 }
3976 b = z % 3; // find out how many bytes will be left over after the encoding. 4014 b = z % 3; // find out how many bytes will be left over after the encoding.
3977 // and save them 4015 // and save them
3978 memcpy(h->base64_extra_chars, &(buf2[z-b]), b); 4016 memcpy(h->base64_extra_chars, &(buf2[z-b]), b);
3979 h->base64_extra = b; 4017 h->base64_extra = b;
3980 t = base64_encode(buf2, z-b); 4018 t = base64_encode(buf2, z-b);
3981 pst_fwrite(t, 1, strlen(t), h->fp); 4019 if (t) pst_fwrite(t, 1, strlen(t), h->fp);
3982 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", 4020 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n",
3983 z, strlen(t), size)); 4021 z, strlen(t), size));
3984 } 4022 }
3985 else if (h->fp) { 4023 else if (h->fp) {
3986 DEBUG_READ(("writing %i bytes to file. Currently %i\n", z, size)); 4024 DEBUG_READ(("writing %i bytes to file. Currently %i\n", z, size));