Deleted Added
full compact
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