cdf.c (267897) | cdf.c (275698) |
---|---|
1/*- 2 * Copyright (c) 2008 Christos Zoulas 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 21 unchanged lines hidden (view full) --- 30 * 31 * N.B. This is the "Composite Document File" format, and not the 32 * "Compound Document Format", nor the "Channel Definition Format". 33 */ 34 35#include "file.h" 36 37#ifndef lint | 1/*- 2 * Copyright (c) 2008 Christos Zoulas 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 21 unchanged lines hidden (view full) --- 30 * 31 * N.B. This is the "Composite Document File" format, and not the 32 * "Compound Document Format", nor the "Channel Definition Format". 33 */ 34 35#include "file.h" 36 37#ifndef lint |
38FILE_RCSID("@(#)$File: cdf.c,v 1.63 2014/06/09 13:04:37 christos Exp $") | 38FILE_RCSID("@(#)$File: cdf.c,v 1.69 2014/12/04 15:56:46 christos Exp $") |
39#endif 40 41#include <assert.h> 42#ifdef CDF_DEBUG 43#include <err.h> 44#endif 45#include <stdlib.h> 46#include <unistd.h> --- 21 unchanged lines hidden (view full) --- 68 uint32_t u; 69} cdf_bo; 70 71#define NEED_SWAP (cdf_bo.u == (uint32_t)0x01020304) 72 73#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x))) 74#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x))) 75#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x))) | 39#endif 40 41#include <assert.h> 42#ifdef CDF_DEBUG 43#include <err.h> 44#endif 45#include <stdlib.h> 46#include <unistd.h> --- 21 unchanged lines hidden (view full) --- 68 uint32_t u; 69} cdf_bo; 70 71#define NEED_SWAP (cdf_bo.u == (uint32_t)0x01020304) 72 73#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x))) 74#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x))) 75#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x))) |
76#define CDF_TOLE(x) (sizeof(x) == 2 ? CDF_TOLE2(x) : (sizeof(x) == 4 ? \ 77 CDF_TOLE4(x) : CDF_TOLE8(x))) |
|
76#define CDF_GETUINT32(x, y) cdf_getuint32(x, y) 77 78 79/* 80 * swap a short 81 */ 82static uint16_t 83_cdf_tole2(uint16_t sv) --- 372 unchanged lines hidden (view full) --- 456size_t 457cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) 458{ 459 size_t i, j; 460 cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size) 461 / sizeof(maxsector)); 462 463 DPRINTF(("Chain:")); | 78#define CDF_GETUINT32(x, y) cdf_getuint32(x, y) 79 80 81/* 82 * swap a short 83 */ 84static uint16_t 85_cdf_tole2(uint16_t sv) --- 372 unchanged lines hidden (view full) --- 458size_t 459cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) 460{ 461 size_t i, j; 462 cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size) 463 / sizeof(maxsector)); 464 465 DPRINTF(("Chain:")); |
466 if (sid == CDF_SECID_END_OF_CHAIN) { 467 /* 0-length chain. */ 468 DPRINTF((" empty\n")); 469 return 0; 470 } 471 |
|
464 for (j = i = 0; sid >= 0; i++, j++) { 465 DPRINTF((" %d", sid)); 466 if (j >= CDF_LOOP_LIMIT) { 467 DPRINTF(("Counting chain loop limit")); 468 errno = EFTYPE; 469 return (size_t)-1; 470 } 471 if (sid >= maxsector) { --- 340 unchanged lines hidden (view full) --- 812 ((const char *)(const void *)sst->sst_tab + 813 offs + sizeof(sh))); 814 e = CAST(const uint8_t *, (const void *) 815 (((const char *)(const void *)shp) + sh.sh_len)); 816 if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1) 817 goto out; 818 for (i = 0; i < sh.sh_properties; i++) { 819 size_t tail = (i << 1) + 1; | 472 for (j = i = 0; sid >= 0; i++, j++) { 473 DPRINTF((" %d", sid)); 474 if (j >= CDF_LOOP_LIMIT) { 475 DPRINTF(("Counting chain loop limit")); 476 errno = EFTYPE; 477 return (size_t)-1; 478 } 479 if (sid >= maxsector) { --- 340 unchanged lines hidden (view full) --- 820 ((const char *)(const void *)sst->sst_tab + 821 offs + sizeof(sh))); 822 e = CAST(const uint8_t *, (const void *) 823 (((const char *)(const void *)shp) + sh.sh_len)); 824 if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1) 825 goto out; 826 for (i = 0; i < sh.sh_properties; i++) { 827 size_t tail = (i << 1) + 1; |
828 size_t ofs; |
|
820 if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t), 821 __LINE__) == -1) 822 goto out; | 829 if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t), 830 __LINE__) == -1) 831 goto out; |
823 size_t ofs = CDF_GETUINT32(p, tail); | 832 ofs = CDF_GETUINT32(p, tail); |
824 q = (const uint8_t *)(const void *) 825 ((const char *)(const void *)p + ofs 826 - 2 * sizeof(uint32_t)); | 833 q = (const uint8_t *)(const void *) 834 ((const char *)(const void *)p + ofs 835 - 2 * sizeof(uint32_t)); |
836 if (q < p) { 837 DPRINTF(("Wrapped around %p < %p\n", q, p)); 838 goto out; 839 } |
|
827 if (q > e) { 828 DPRINTF(("Ran of the end %p > %p\n", q, e)); 829 goto out; 830 } 831 inp[i].pi_id = CDF_GETUINT32(p, i << 1); 832 inp[i].pi_type = CDF_GETUINT32(q, 0); 833 DPRINTF(("%" SIZE_T_FORMAT "u) id=%x type=%x offs=0x%tx,0x%x\n", 834 i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); --- 145 unchanged lines hidden (view full) --- 980 *info = NULL; 981 if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, 982 count, &maxcount) == -1) 983 return -1; 984 return 0; 985} 986 987 | 840 if (q > e) { 841 DPRINTF(("Ran of the end %p > %p\n", q, e)); 842 goto out; 843 } 844 inp[i].pi_id = CDF_GETUINT32(p, i << 1); 845 inp[i].pi_type = CDF_GETUINT32(q, 0); 846 DPRINTF(("%" SIZE_T_FORMAT "u) id=%x type=%x offs=0x%tx,0x%x\n", 847 i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); --- 145 unchanged lines hidden (view full) --- 993 *info = NULL; 994 if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, 995 count, &maxcount) == -1) 996 return -1; 997 return 0; 998} 999 1000 |
1001#define extract_catalog_field(f, l) \ 1002 memcpy(&ce[i].f, b + (l), sizeof(ce[i].f)); \ 1003 ce[i].f = CDF_TOLE(ce[i].f) |
|
988 989int | 1004 1005int |
1006cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst, 1007 cdf_catalog_t **cat) 1008{ 1009 size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? 1010 CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); 1011 const char *b = CAST(const char *, sst->sst_tab); 1012 const char *eb = b + ss * sst->sst_len; 1013 size_t nr, i, k; 1014 cdf_catalog_entry_t *ce; 1015 uint16_t reclen; 1016 const uint16_t *np; 1017 1018 for (nr = 0; b < eb; nr++) { 1019 memcpy(&reclen, b, sizeof(reclen)); 1020 reclen = CDF_TOLE2(reclen); 1021 if (reclen == 0) 1022 break; 1023 b += reclen; 1024 } 1025 *cat = CAST(cdf_catalog_t *, 1026 malloc(sizeof(cdf_catalog_t) + nr * sizeof(*ce))); 1027 (*cat)->cat_num = nr; 1028 ce = (*cat)->cat_e; 1029 b = CAST(const char *, sst->sst_tab); 1030 for (i = 0; i < nr; i++) { 1031 extract_catalog_field(ce_namlen, 0); 1032 extract_catalog_field(ce_num, 2); 1033 extract_catalog_field(ce_timestamp, 6); 1034 reclen = ce[i].ce_namlen; 1035 ce[i].ce_namlen = 1036 sizeof(ce[i].ce_name) / sizeof(ce[i].ce_name[0]) - 1; 1037 if (ce[i].ce_namlen > reclen - 14) 1038 ce[i].ce_namlen = reclen - 14; 1039 np = CAST(const uint16_t *, (b + 16)); 1040 for (k = 0; k < ce[i].ce_namlen; k++) { 1041 ce[i].ce_name[k] = np[k]; 1042 CDF_TOLE2(ce[i].ce_name[k]); 1043 } 1044 ce[i].ce_name[ce[i].ce_namlen] = 0; 1045 b += reclen; 1046 } 1047 return 0; 1048} 1049 1050int |
|
990cdf_print_classid(char *buf, size_t buflen, const cdf_classid_t *id) 991{ 992 return snprintf(buf, buflen, "%.8x-%.4x-%.4x-%.2x%.2x-" 993 "%.2x%.2x%.2x%.2x%.2x%.2x", id->cl_dword, id->cl_word[0], 994 id->cl_word[1], id->cl_two[0], id->cl_two[1], id->cl_six[0], 995 id->cl_six[1], id->cl_six[2], id->cl_six[3], id->cl_six[4], 996 id->cl_six[5]); 997} --- 65 unchanged lines hidden (view full) --- 1063 len += snprintf(buf + len, bufsiz - len, "%.2d:", mins); 1064 if ((size_t)len >= bufsiz) 1065 return len; 1066 1067 len += snprintf(buf + len, bufsiz - len, "%.2d", secs); 1068 return len; 1069} 1070 | 1051cdf_print_classid(char *buf, size_t buflen, const cdf_classid_t *id) 1052{ 1053 return snprintf(buf, buflen, "%.8x-%.4x-%.4x-%.2x%.2x-" 1054 "%.2x%.2x%.2x%.2x%.2x%.2x", id->cl_dword, id->cl_word[0], 1055 id->cl_word[1], id->cl_two[0], id->cl_two[1], id->cl_six[0], 1056 id->cl_six[1], id->cl_six[2], id->cl_six[3], id->cl_six[4], 1057 id->cl_six[5]); 1058} --- 65 unchanged lines hidden (view full) --- 1124 len += snprintf(buf + len, bufsiz - len, "%.2d:", mins); 1125 if ((size_t)len >= bufsiz) 1126 return len; 1127 1128 len += snprintf(buf + len, bufsiz - len, "%.2d", secs); 1129 return len; 1130} 1131 |
1132char * 1133cdf_u16tos8(char *buf, size_t len, const uint16_t *p) 1134{ 1135 size_t i; 1136 for (i = 0; i < len && p[i]; i++) 1137 buf[i] = (char)p[i]; 1138 buf[i] = '\0'; 1139 return buf; 1140} |
|
1071 1072#ifdef CDF_DEBUG 1073void 1074cdf_dump_header(const cdf_header_t *h) 1075{ 1076 size_t i; 1077 1078#define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b) --- 9 unchanged lines hidden (view full) --- 1088 DUMP("%d", min_size_standard_stream); 1089 DUMP("%d", secid_first_sector_in_short_sat); 1090 DUMP("%d", num_sectors_in_short_sat); 1091 DUMP("%d", secid_first_sector_in_master_sat); 1092 DUMP("%d", num_sectors_in_master_sat); 1093 for (i = 0; i < __arraycount(h->h_master_sat); i++) { 1094 if (h->h_master_sat[i] == CDF_SECID_FREE) 1095 break; | 1141 1142#ifdef CDF_DEBUG 1143void 1144cdf_dump_header(const cdf_header_t *h) 1145{ 1146 size_t i; 1147 1148#define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b) --- 9 unchanged lines hidden (view full) --- 1158 DUMP("%d", min_size_standard_stream); 1159 DUMP("%d", secid_first_sector_in_short_sat); 1160 DUMP("%d", num_sectors_in_short_sat); 1161 DUMP("%d", secid_first_sector_in_master_sat); 1162 DUMP("%d", num_sectors_in_master_sat); 1163 for (i = 0; i < __arraycount(h->h_master_sat); i++) { 1164 if (h->h_master_sat[i] == CDF_SECID_FREE) 1165 break; |
1096 (void)fprintf(stderr, "%35.35s[%.3zu] = %d\n", | 1166 (void)fprintf(stderr, "%35.35s[%.3" SIZE_T_FORMAT "u] = %d\n", |
1097 "master_sat", i, h->h_master_sat[i]); 1098 } 1099} 1100 1101void 1102cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size) 1103{ 1104 size_t i, j, s = size / sizeof(cdf_secid_t); --- 178 unchanged lines hidden (view full) --- 1283 cdf_property_info_t *info; 1284 size_t count; 1285 1286 (void)&h; 1287 if (cdf_unpack_summary_info(sst, h, &ssi, &info, &count) == -1) 1288 return; 1289 (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order); 1290 (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff, | 1167 "master_sat", i, h->h_master_sat[i]); 1168 } 1169} 1170 1171void 1172cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size) 1173{ 1174 size_t i, j, s = size / sizeof(cdf_secid_t); --- 178 unchanged lines hidden (view full) --- 1353 cdf_property_info_t *info; 1354 size_t count; 1355 1356 (void)&h; 1357 if (cdf_unpack_summary_info(sst, h, &ssi, &info, &count) == -1) 1358 return; 1359 (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order); 1360 (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff, |
1291 ssi.si_os_version >> 8); | 1361 ssi.si_os_version >> 8); |
1292 (void)fprintf(stderr, "Os %d\n", ssi.si_os); 1293 cdf_print_classid(buf, sizeof(buf), &ssi.si_class); 1294 (void)fprintf(stderr, "Class %s\n", buf); 1295 (void)fprintf(stderr, "Count %d\n", ssi.si_count); 1296 cdf_dump_property_info(info, count); 1297 free(info); 1298} 1299 | 1362 (void)fprintf(stderr, "Os %d\n", ssi.si_os); 1363 cdf_print_classid(buf, sizeof(buf), &ssi.si_class); 1364 (void)fprintf(stderr, "Class %s\n", buf); 1365 (void)fprintf(stderr, "Count %d\n", ssi.si_count); 1366 cdf_dump_property_info(info, count); 1367 free(info); 1368} 1369 |
1370 1371void 1372cdf_dump_catalog(const cdf_header_t *h, const cdf_stream_t *sst) 1373{ 1374 cdf_catalog_t *cat; 1375 cdf_unpack_catalog(h, sst, &cat); 1376 const cdf_catalog_entry_t *ce = cat->cat_e; 1377 struct timespec ts; 1378 char tbuf[64], sbuf[256]; 1379 size_t i; 1380 1381 printf("Catalog:\n"); 1382 for (i = 0; i < cat->cat_num; i++) { 1383 cdf_timestamp_to_timespec(&ts, ce[i].ce_timestamp); 1384 printf("\t%d %s %s", ce[i].ce_num, 1385 cdf_u16tos8(sbuf, ce[i].ce_namlen, ce[i].ce_name), 1386 cdf_ctime(&ts.tv_sec, tbuf)); 1387 } 1388 free(cat); 1389} 1390 |
|
1300#endif 1301 1302#ifdef TEST 1303int 1304main(int argc, char *argv[]) 1305{ 1306 int i; 1307 cdf_header_t h; 1308 cdf_sat_t sat, ssat; 1309 cdf_stream_t sst, scn; 1310 cdf_dir_t dir; 1311 cdf_info_t info; | 1391#endif 1392 1393#ifdef TEST 1394int 1395main(int argc, char *argv[]) 1396{ 1397 int i; 1398 cdf_header_t h; 1399 cdf_sat_t sat, ssat; 1400 cdf_stream_t sst, scn; 1401 cdf_dir_t dir; 1402 cdf_info_t info; |
1403 const cdf_directory_t *root; |
|
1312 1313 if (argc < 2) { 1314 (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname()); 1315 return -1; 1316 } 1317 1318 info.i_buf = NULL; 1319 info.i_len = 0; --- 17 unchanged lines hidden (view full) --- 1337 err(1, "Cannot read ssat"); 1338#ifdef CDF_DEBUG 1339 cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); 1340#endif 1341 1342 if (cdf_read_dir(&info, &h, &sat, &dir) == -1) 1343 err(1, "Cannot read dir"); 1344 | 1404 1405 if (argc < 2) { 1406 (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname()); 1407 return -1; 1408 } 1409 1410 info.i_buf = NULL; 1411 info.i_len = 0; --- 17 unchanged lines hidden (view full) --- 1429 err(1, "Cannot read ssat"); 1430#ifdef CDF_DEBUG 1431 cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); 1432#endif 1433 1434 if (cdf_read_dir(&info, &h, &sat, &dir) == -1) 1435 err(1, "Cannot read dir"); 1436 |
1345 if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1) | 1437 if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst, &root) 1438 == -1) |
1346 err(1, "Cannot read short stream"); 1347#ifdef CDF_DEBUG 1348 cdf_dump_stream(&h, &sst); 1349#endif 1350 1351#ifdef CDF_DEBUG 1352 cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); 1353#endif 1354 1355 1356 if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, 1357 &scn) == -1) | 1439 err(1, "Cannot read short stream"); 1440#ifdef CDF_DEBUG 1441 cdf_dump_stream(&h, &sst); 1442#endif 1443 1444#ifdef CDF_DEBUG 1445 cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); 1446#endif 1447 1448 1449 if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, 1450 &scn) == -1) |
1358 err(1, "Cannot read summary info"); | 1451 warn("Cannot read summary info"); |
1359#ifdef CDF_DEBUG | 1452#ifdef CDF_DEBUG |
1360 cdf_dump_summary_info(&h, &scn); | 1453 else 1454 cdf_dump_summary_info(&h, &scn); |
1361#endif | 1455#endif |
1456 if (cdf_read_catalog(&info, &h, &sat, &ssat, &sst, &dir, 1457 &scn) == -1) 1458 warn("Cannot read catalog"); 1459#ifdef CDF_DEBUG 1460 else 1461 cdf_dump_catalog(&h, &scn); 1462#endif |
|
1362 1363 (void)close(info.i_fd); 1364 } 1365 1366 return 0; 1367} 1368#endif | 1463 1464 (void)close(info.i_fd); 1465 } 1466 1467 return 0; 1468} 1469#endif |