]> granicus.if.org Git - file/commitdiff
Clarify which sort of CDF we mean.
authorReuben Thomas <rrt@sc3d.org>
Sat, 20 Feb 2010 15:19:53 +0000 (15:19 +0000)
committerReuben Thomas <rrt@sc3d.org>
Sat, 20 Feb 2010 15:19:53 +0000 (15:19 +0000)
ChangeLog
src/cdf.c
src/cdf.h
src/readcdf.c

index 330b20a7302d5d4fdd6e09278a1206b5e9724cb6..8838a3c6c1caead5f696314e481054328a4c39d6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-02-20  15:18  Reuben Thomas <rrt@sc3d.org>
+
+       * Clarify which sort of CDF we mean.
+
 2010-02-14  22:58  Reuben Thomas <rrt@sc3d.org>
 
        * Re-jig Zip file type magic so that unsupported special
index d59e52b17b2a4d45c3dcec05b47e08e465eaa0ab..1e374385fa78e022db31728e4d72df2956923de2 100644 (file)
--- a/src/cdf.c
+++ b/src/cdf.c
  * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
- * Parse composite document files, the format used in Microsoft Office
- * document files before they switched to zipped xml.
+ * Parse Composite Document Files, the format used in Microsoft Office
+ * document files before they switched to zipped XML.
  * Info from: http://sc.openoffice.org/compdocfileformat.pdf
+ *
+ * N.B. This is the "Composite Document File" format, and not the
+ * "Compound Document Format", nor the "Channel Definition Format".
  */
 
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.35 2009/09/13 23:25:16 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.36 2010/01/22 20:56:26 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -65,8 +68,8 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.35 2009/09/13 23:25:16 christos Exp $")
 #endif
 
 static union {
-       char s[4];
-       uint32_t u;
+        char s[4];
+        uint32_t u;
 } cdf_bo;
 
 #define NEED_SWAP      (cdf_bo.u == (uint32_t)0x01020304)
@@ -81,12 +84,12 @@ static union {
 uint16_t
 cdf_tole2(uint16_t sv)
 {
-       uint16_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv; 
-       uint8_t *d = (uint8_t *)(void *)&rv; 
-       d[0] = s[1];
-       d[1] = s[0];
-       return rv;
+        uint16_t rv;
+        uint8_t *s = (uint8_t *)(void *)&sv;
+        uint8_t *d = (uint8_t *)(void *)&rv;
+        d[0] = s[1];
+        d[1] = s[0];
+        return rv;
 }
 
 /*
@@ -95,14 +98,14 @@ cdf_tole2(uint16_t sv)
 uint32_t
 cdf_tole4(uint32_t sv)
 {
-       uint32_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv; 
-       uint8_t *d = (uint8_t *)(void *)&rv; 
-       d[0] = s[3];
-       d[1] = s[2];
-       d[2] = s[1];
-       d[3] = s[0];
-       return rv;
+        uint32_t rv;
+        uint8_t *s = (uint8_t *)(void *)&sv;
+        uint8_t *d = (uint8_t *)(void *)&rv;
+        d[0] = s[3];
+        d[1] = s[2];
+        d[2] = s[1];
+        d[3] = s[0];
+        return rv;
 }
 
 /*
@@ -111,18 +114,18 @@ cdf_tole4(uint32_t sv)
 uint64_t
 cdf_tole8(uint64_t sv)
 {
-       uint64_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv; 
-       uint8_t *d = (uint8_t *)(void *)&rv; 
-       d[0] = s[7];
-       d[1] = s[6];
-       d[2] = s[5];
-       d[3] = s[4];
-       d[4] = s[3];
-       d[5] = s[2];
-       d[6] = s[1];
-       d[7] = s[0];
-       return rv;
+        uint64_t rv;
+        uint8_t *s = (uint8_t *)(void *)&sv;
+        uint8_t *d = (uint8_t *)(void *)&rv;
+        d[0] = s[7];
+        d[1] = s[6];
+        d[2] = s[5];
+        d[3] = s[4];
+        d[4] = s[3];
+        d[5] = s[2];
+        d[6] = s[1];
+        d[7] = s[0];
+        return rv;
 }
 
 #define CDF_UNPACK(a)  \
@@ -133,175 +136,175 @@ cdf_tole8(uint64_t sv)
 void
 cdf_swap_header(cdf_header_t *h)
 {
-       size_t i;
-
-       h->h_magic = CDF_TOLE8(h->h_magic);
-       h->h_uuid[0] = CDF_TOLE8(h->h_uuid[0]);
-       h->h_uuid[1] = CDF_TOLE8(h->h_uuid[1]);
-       h->h_revision = CDF_TOLE2(h->h_revision);
-       h->h_version = CDF_TOLE2(h->h_version);
-       h->h_byte_order = CDF_TOLE2(h->h_byte_order);
-       h->h_sec_size_p2 = CDF_TOLE2(h->h_sec_size_p2);
-       h->h_short_sec_size_p2 = CDF_TOLE2(h->h_short_sec_size_p2);
-       h->h_num_sectors_in_sat = CDF_TOLE4(h->h_num_sectors_in_sat);
-       h->h_secid_first_directory = CDF_TOLE4(h->h_secid_first_directory);
-       h->h_min_size_standard_stream =
-           CDF_TOLE4(h->h_min_size_standard_stream);
-       h->h_secid_first_sector_in_short_sat =
-           CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_short_sat);
-       h->h_num_sectors_in_short_sat =
-           CDF_TOLE4(h->h_num_sectors_in_short_sat);
-       h->h_secid_first_sector_in_master_sat =
-           CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_master_sat);
-       h->h_num_sectors_in_master_sat =
-           CDF_TOLE4(h->h_num_sectors_in_master_sat);
-       for (i = 0; i < __arraycount(h->h_master_sat); i++)
-               h->h_master_sat[i] = CDF_TOLE4((uint32_t)h->h_master_sat[i]);
+        size_t i;
+
+        h->h_magic = CDF_TOLE8(h->h_magic);
+        h->h_uuid[0] = CDF_TOLE8(h->h_uuid[0]);
+        h->h_uuid[1] = CDF_TOLE8(h->h_uuid[1]);
+        h->h_revision = CDF_TOLE2(h->h_revision);
+        h->h_version = CDF_TOLE2(h->h_version);
+        h->h_byte_order = CDF_TOLE2(h->h_byte_order);
+        h->h_sec_size_p2 = CDF_TOLE2(h->h_sec_size_p2);
+        h->h_short_sec_size_p2 = CDF_TOLE2(h->h_short_sec_size_p2);
+        h->h_num_sectors_in_sat = CDF_TOLE4(h->h_num_sectors_in_sat);
+        h->h_secid_first_directory = CDF_TOLE4(h->h_secid_first_directory);
+        h->h_min_size_standard_stream =
+            CDF_TOLE4(h->h_min_size_standard_stream);
+        h->h_secid_first_sector_in_short_sat =
+            CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_short_sat);
+        h->h_num_sectors_in_short_sat =
+            CDF_TOLE4(h->h_num_sectors_in_short_sat);
+        h->h_secid_first_sector_in_master_sat =
+            CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_master_sat);
+        h->h_num_sectors_in_master_sat =
+            CDF_TOLE4(h->h_num_sectors_in_master_sat);
+        for (i = 0; i < __arraycount(h->h_master_sat); i++)
+                h->h_master_sat[i] = CDF_TOLE4((uint32_t)h->h_master_sat[i]);
 }
 
 void
 cdf_unpack_header(cdf_header_t *h, char *buf)
 {
-       size_t i;
-       size_t len = 0;
-
-       CDF_UNPACK(h->h_magic);
-       CDF_UNPACKA(h->h_uuid);
-       CDF_UNPACK(h->h_revision);
-       CDF_UNPACK(h->h_version);
-       CDF_UNPACK(h->h_byte_order);
-       CDF_UNPACK(h->h_sec_size_p2);
-       CDF_UNPACK(h->h_short_sec_size_p2);
-       CDF_UNPACKA(h->h_unused0);
-       CDF_UNPACK(h->h_num_sectors_in_sat);
-       CDF_UNPACK(h->h_secid_first_directory);
-       CDF_UNPACKA(h->h_unused1);
-       CDF_UNPACK(h->h_min_size_standard_stream);
-       CDF_UNPACK(h->h_secid_first_sector_in_short_sat);
-       CDF_UNPACK(h->h_num_sectors_in_short_sat);
-       CDF_UNPACK(h->h_secid_first_sector_in_master_sat);
-       CDF_UNPACK(h->h_num_sectors_in_master_sat);
-       for (i = 0; i < __arraycount(h->h_master_sat); i++)
-               CDF_UNPACK(h->h_master_sat[i]);
+        size_t i;
+        size_t len = 0;
+
+        CDF_UNPACK(h->h_magic);
+        CDF_UNPACKA(h->h_uuid);
+        CDF_UNPACK(h->h_revision);
+        CDF_UNPACK(h->h_version);
+        CDF_UNPACK(h->h_byte_order);
+        CDF_UNPACK(h->h_sec_size_p2);
+        CDF_UNPACK(h->h_short_sec_size_p2);
+        CDF_UNPACKA(h->h_unused0);
+        CDF_UNPACK(h->h_num_sectors_in_sat);
+        CDF_UNPACK(h->h_secid_first_directory);
+        CDF_UNPACKA(h->h_unused1);
+        CDF_UNPACK(h->h_min_size_standard_stream);
+        CDF_UNPACK(h->h_secid_first_sector_in_short_sat);
+        CDF_UNPACK(h->h_num_sectors_in_short_sat);
+        CDF_UNPACK(h->h_secid_first_sector_in_master_sat);
+        CDF_UNPACK(h->h_num_sectors_in_master_sat);
+        for (i = 0; i < __arraycount(h->h_master_sat); i++)
+                CDF_UNPACK(h->h_master_sat[i]);
 }
 
 void
 cdf_swap_dir(cdf_directory_t *d)
 {
-       d->d_namelen = CDF_TOLE2(d->d_namelen);
-       d->d_left_child = CDF_TOLE4((uint32_t)d->d_left_child);
-       d->d_right_child = CDF_TOLE4((uint32_t)d->d_right_child);
-       d->d_storage = CDF_TOLE4((uint32_t)d->d_storage);
-       d->d_storage_uuid[0] = CDF_TOLE8(d->d_storage_uuid[0]);
-       d->d_storage_uuid[1] = CDF_TOLE8(d->d_storage_uuid[1]);
-       d->d_flags = CDF_TOLE4(d->d_flags);
-       d->d_created = CDF_TOLE8((uint64_t)d->d_created);
-       d->d_modified = CDF_TOLE8((uint64_t)d->d_modified);
-       d->d_stream_first_sector = CDF_TOLE4((uint32_t)d->d_stream_first_sector);
-       d->d_size = CDF_TOLE4(d->d_size);
+        d->d_namelen = CDF_TOLE2(d->d_namelen);
+        d->d_left_child = CDF_TOLE4((uint32_t)d->d_left_child);
+        d->d_right_child = CDF_TOLE4((uint32_t)d->d_right_child);
+        d->d_storage = CDF_TOLE4((uint32_t)d->d_storage);
+        d->d_storage_uuid[0] = CDF_TOLE8(d->d_storage_uuid[0]);
+        d->d_storage_uuid[1] = CDF_TOLE8(d->d_storage_uuid[1]);
+        d->d_flags = CDF_TOLE4(d->d_flags);
+        d->d_created = CDF_TOLE8((uint64_t)d->d_created);
+        d->d_modified = CDF_TOLE8((uint64_t)d->d_modified);
+        d->d_stream_first_sector = CDF_TOLE4((uint32_t)d->d_stream_first_sector);
+        d->d_size = CDF_TOLE4(d->d_size);
 }
 
 void
 cdf_swap_class(cdf_classid_t *d)
 {
-       d->cl_dword = CDF_TOLE4(d->cl_dword);
-       d->cl_word[0] = CDF_TOLE2(d->cl_word[0]);
-       d->cl_word[1] = CDF_TOLE2(d->cl_word[1]);
+        d->cl_dword = CDF_TOLE4(d->cl_dword);
+        d->cl_word[0] = CDF_TOLE2(d->cl_word[0]);
+        d->cl_word[1] = CDF_TOLE2(d->cl_word[1]);
 }
 
 void
 cdf_unpack_dir(cdf_directory_t *d, char *buf)
 {
-       size_t len = 0;
-
-       CDF_UNPACKA(d->d_name);
-       CDF_UNPACK(d->d_namelen);
-       CDF_UNPACK(d->d_type);
-       CDF_UNPACK(d->d_color);
-       CDF_UNPACK(d->d_left_child);
-       CDF_UNPACK(d->d_right_child);
-       CDF_UNPACK(d->d_storage);
-       CDF_UNPACKA(d->d_storage_uuid);
-       CDF_UNPACK(d->d_flags);
-       CDF_UNPACK(d->d_created);
-       CDF_UNPACK(d->d_modified);
-       CDF_UNPACK(d->d_stream_first_sector);
-       CDF_UNPACK(d->d_size);
-       CDF_UNPACK(d->d_unused0);
+        size_t len = 0;
+
+        CDF_UNPACKA(d->d_name);
+        CDF_UNPACK(d->d_namelen);
+        CDF_UNPACK(d->d_type);
+        CDF_UNPACK(d->d_color);
+        CDF_UNPACK(d->d_left_child);
+        CDF_UNPACK(d->d_right_child);
+        CDF_UNPACK(d->d_storage);
+        CDF_UNPACKA(d->d_storage_uuid);
+        CDF_UNPACK(d->d_flags);
+        CDF_UNPACK(d->d_created);
+        CDF_UNPACK(d->d_modified);
+        CDF_UNPACK(d->d_stream_first_sector);
+        CDF_UNPACK(d->d_size);
+        CDF_UNPACK(d->d_unused0);
 }
 
 static int
 cdf_check_stream_offset(const cdf_stream_t *sst, const void *p, size_t tail,
     int line)
 {
-       const char *b = (const char *)sst->sst_tab;
-       const char *e = ((const char *)p) + tail;
-       (void)&line;
-       if (e >= b && (size_t)(e - b) < sst->sst_dirlen * sst->sst_len)
-               return 0;
-       DPRINTF(("%d: offset begin %p end %p %zu >= %zu [%zu %zu]\n",
-           line, b, e, (size_t)(e - b), sst->sst_dirlen * sst->sst_len,
-           sst->sst_dirlen, sst->sst_len));
-       errno = EFTYPE;
-       return -1;
+        const char *b = (const char *)sst->sst_tab;
+        const char *e = ((const char *)p) + tail;
+        (void)&line;
+        if (e >= b && (size_t)(e - b) < sst->sst_dirlen * sst->sst_len)
+                return 0;
+        DPRINTF(("%d: offset begin %p end %p %zu >= %zu [%zu %zu]\n",
+            line, b, e, (size_t)(e - b), sst->sst_dirlen * sst->sst_len,
+            sst->sst_dirlen, sst->sst_len));
+        errno = EFTYPE;
+        return -1;
 }
 
 static ssize_t
 cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
 {
-       size_t siz = (size_t)off + len;
+        size_t siz = (size_t)off + len;
 
-       if ((off_t)(off + len) != (off_t)siz) {
-               errno = EINVAL;
-               return -1;
-       }
+        if ((off_t)(off + len) != (off_t)siz) {
+                errno = EINVAL;
+                return -1;
+        }
 
-       if (info->i_buf != NULL && info->i_len >= siz) {
-               (void)memcpy(buf, &info->i_buf[off], len);
-               return (ssize_t)len;
-       }
+        if (info->i_buf != NULL && info->i_len >= siz) {
+                (void)memcpy(buf, &info->i_buf[off], len);
+                return (ssize_t)len;
+        }
 
-       if (info->i_fd == -1)
-               return -1;
+        if (info->i_fd == -1)
+                return -1;
 
-       if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1)
-               return -1;
+        if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1)
+                return -1;
 
-       if (read(info->i_fd, buf, len) != (ssize_t)len)
-               return -1;
+        if (read(info->i_fd, buf, len) != (ssize_t)len)
+                return -1;
 
-       return (ssize_t)len;
+        return (ssize_t)len;
 }
 
 int
 cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
 {
-       char buf[512];
-
-       (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
-       if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
-               return -1;
-       cdf_unpack_header(h, buf);
-       cdf_swap_header(h);
-       if (h->h_magic != CDF_MAGIC) {
-               DPRINTF(("Bad magic 0x%llx != 0x%llx\n",
-                   (unsigned long long)h->h_magic,
-                   (unsigned long long)CDF_MAGIC));
-               goto out;
-       }
-       if (h->h_sec_size_p2 > 20) {
-               DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2));
-               goto out;
-       }
-       if (h->h_short_sec_size_p2 > 20) {
-               DPRINTF(("Bad short sector size 0x%u\n",
-                   h->h_short_sec_size_p2));
-               goto out;
-       }
-       return 0;
+        char buf[512];
+
+        (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
+        if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
+                return -1;
+        cdf_unpack_header(h, buf);
+        cdf_swap_header(h);
+        if (h->h_magic != CDF_MAGIC) {
+                DPRINTF(("Bad magic 0x%llx != 0x%llx\n",
+                    (unsigned long long)h->h_magic,
+                    (unsigned long long)CDF_MAGIC));
+                goto out;
+        }
+        if (h->h_sec_size_p2 > 20) {
+                DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2));
+                goto out;
+        }
+        if (h->h_short_sec_size_p2 > 20) {
+                DPRINTF(("Bad short sector size 0x%u\n",
+                    h->h_short_sec_size_p2));
+                goto out;
+        }
+        return 0;
 out:
-       errno = EFTYPE;
-       return -1;
+        errno = EFTYPE;
+        return -1;
 }
 
 
@@ -309,19 +312,19 @@ ssize_t
 cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
     const cdf_header_t *h, cdf_secid_t id)
 {
-       assert((size_t)CDF_SEC_SIZE(h) == len);
-       return cdf_read(info, (off_t)CDF_SEC_POS(h, id),
-           ((char *)buf) + offs, len);
+        assert((size_t)CDF_SEC_SIZE(h) == len);
+        return cdf_read(info, (off_t)CDF_SEC_POS(h, id),
+            ((char *)buf) + offs, len);
 }
 
 ssize_t
 cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
     size_t len, const cdf_header_t *h, cdf_secid_t id)
 {
-       assert((size_t)CDF_SHORT_SEC_SIZE(h) == len);
-       (void)memcpy(((char *)buf) + offs,
-           ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len);
-       return len;
+        assert((size_t)CDF_SHORT_SEC_SIZE(h) == len);
+        (void)memcpy(((char *)buf) + offs,
+            ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len);
+        return len;
 }
 
 /*
@@ -330,154 +333,154 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
 int
 cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
 {
-       size_t i, j, k;
-       size_t ss = CDF_SEC_SIZE(h);
-       cdf_secid_t *msa, mid, sec;
-       size_t nsatpersec = (ss / sizeof(mid)) - 1;
+        size_t i, j, k;
+        size_t ss = CDF_SEC_SIZE(h);
+        cdf_secid_t *msa, mid, sec;
+        size_t nsatpersec = (ss / sizeof(mid)) - 1;
 
-       for (i = 0; i < __arraycount(h->h_master_sat); i++)
-               if (h->h_master_sat[i] == CDF_SECID_FREE)
-                       break;
+        for (i = 0; i < __arraycount(h->h_master_sat); i++)
+                if (h->h_master_sat[i] == CDF_SECID_FREE)
+                        break;
 
 #define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss))
-       if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec ||
-           i > CDF_SEC_LIMIT) {
-               DPRINTF(("Number of sectors in master SAT too big %u %zu\n",
-                   h->h_num_sectors_in_master_sat, i));
-               errno = EFTYPE;
-               return -1;
-       }
-
-       sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i;
-       DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss));
-       if ((sat->sat_tab = CAST(cdf_secid_t *, calloc(sat->sat_len, ss)))
-           == NULL)
-               return -1;
-
-       for (i = 0; i < __arraycount(h->h_master_sat); i++) {
-               if (h->h_master_sat[i] < 0)
-                       break;
-               if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
-                   h->h_master_sat[i]) != (ssize_t)ss) {
-                       DPRINTF(("Reading sector %d", h->h_master_sat[i]));
-                       goto out1;
-               }
-       }
-
-       if ((msa = CAST(cdf_secid_t *, calloc(1, ss))) == NULL)
-               goto out1;
-
-       mid = h->h_secid_first_sector_in_master_sat;
-       for (j = 0; j < h->h_num_sectors_in_master_sat; j++) {
-               if (mid < 0)
-                       goto out;
-               if (j >= CDF_LOOP_LIMIT) {
-                       DPRINTF(("Reading master sector loop limit"));
-                       errno = EFTYPE;
-                       goto out2;
-               }
-               if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) {
-                       DPRINTF(("Reading master sector %d", mid));
-                       goto out2;
-               }
-               for (k = 0; k < nsatpersec; k++, i++) {
-                       sec = CDF_TOLE4((uint32_t)msa[k]);
-                       if (sec < 0)
-                               goto out;
-                       if (i >= sat->sat_len) {
-                           DPRINTF(("Out of bounds reading MSA %u >= %u",
-                               i, sat->sat_len));
-                           errno = EFTYPE;
-                           goto out2;
-                       }
-                       if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
-                           sec) != (ssize_t)ss) {
-                               DPRINTF(("Reading sector %d",
-                                   CDF_TOLE4(msa[k])));
-                               goto out2;
-                       }
-               }
-               mid = CDF_TOLE4((uint32_t)msa[nsatpersec]);
-       }
+        if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec ||
+            i > CDF_SEC_LIMIT) {
+                DPRINTF(("Number of sectors in master SAT too big %u %zu\n",
+                    h->h_num_sectors_in_master_sat, i));
+                errno = EFTYPE;
+                return -1;
+        }
+
+        sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i;
+        DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss));
+        if ((sat->sat_tab = CAST(cdf_secid_t *, calloc(sat->sat_len, ss)))
+            == NULL)
+                return -1;
+
+        for (i = 0; i < __arraycount(h->h_master_sat); i++) {
+                if (h->h_master_sat[i] < 0)
+                        break;
+                if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
+                    h->h_master_sat[i]) != (ssize_t)ss) {
+                        DPRINTF(("Reading sector %d", h->h_master_sat[i]));
+                        goto out1;
+                }
+        }
+
+        if ((msa = CAST(cdf_secid_t *, calloc(1, ss))) == NULL)
+                goto out1;
+
+        mid = h->h_secid_first_sector_in_master_sat;
+        for (j = 0; j < h->h_num_sectors_in_master_sat; j++) {
+                if (mid < 0)
+                        goto out;
+                if (j >= CDF_LOOP_LIMIT) {
+                        DPRINTF(("Reading master sector loop limit"));
+                        errno = EFTYPE;
+                        goto out2;
+                }
+                if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) {
+                        DPRINTF(("Reading master sector %d", mid));
+                        goto out2;
+                }
+                for (k = 0; k < nsatpersec; k++, i++) {
+                        sec = CDF_TOLE4((uint32_t)msa[k]);
+                        if (sec < 0)
+                                goto out;
+                        if (i >= sat->sat_len) {
+                            DPRINTF(("Out of bounds reading MSA %u >= %u",
+                                i, sat->sat_len));
+                            errno = EFTYPE;
+                            goto out2;
+                        }
+                        if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
+                            sec) != (ssize_t)ss) {
+                                DPRINTF(("Reading sector %d",
+                                    CDF_TOLE4(msa[k])));
+                                goto out2;
+                        }
+                }
+                mid = CDF_TOLE4((uint32_t)msa[nsatpersec]);
+        }
 out:
-       sat->sat_len = i;
-       free(msa);
-       return 0;
+        sat->sat_len = i;
+        free(msa);
+        return 0;
 out2:
-       free(msa);
+        free(msa);
 out1:
-       free(sat->sat_tab);
-       return -1;
+        free(sat->sat_tab);
+        return -1;
 }
 
 size_t
 cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
 {
-       size_t i, j;
-       cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size);
-
-       DPRINTF(("Chain:"));
-       for (j = i = 0; sid >= 0; i++, j++) {
-               DPRINTF((" %d", sid));
-               if (j >= CDF_LOOP_LIMIT) {
-                       DPRINTF(("Counting chain loop limit"));
-                       errno = EFTYPE;
-                       return (size_t)-1;
-               }
-               if (sid > maxsector) {
-                       DPRINTF(("Sector %d > %d\n", sid, maxsector));
-                       errno = EFTYPE;
-                       return (size_t)-1;
-               }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
-       }
-       DPRINTF(("\n"));
-       return i;
+        size_t i, j;
+        cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size);
+
+        DPRINTF(("Chain:"));
+        for (j = i = 0; sid >= 0; i++, j++) {
+                DPRINTF((" %d", sid));
+                if (j >= CDF_LOOP_LIMIT) {
+                        DPRINTF(("Counting chain loop limit"));
+                        errno = EFTYPE;
+                        return (size_t)-1;
+                }
+                if (sid > maxsector) {
+                        DPRINTF(("Sector %d > %d\n", sid, maxsector));
+                        errno = EFTYPE;
+                        return (size_t)-1;
+                }
+                sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+        }
+        DPRINTF(("\n"));
+        return i;
 }
 
 int
 cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, cdf_secid_t sid, size_t len, cdf_stream_t *scn)
 {
-       size_t ss = CDF_SEC_SIZE(h), i, j;
-       ssize_t nr;
-       scn->sst_len = cdf_count_chain(sat, sid, ss);
-       scn->sst_dirlen = len;
-
-       if (scn->sst_len == (size_t)-1)
-               return -1;
-
-       scn->sst_tab = calloc(scn->sst_len, ss);
-       if (scn->sst_tab == NULL)
-               return -1;
-
-       for (j = i = 0; sid >= 0; i++, j++) {
-               if (j >= CDF_LOOP_LIMIT) {
-                       DPRINTF(("Read long sector chain loop limit"));
-                       errno = EFTYPE;
-                       goto out;
-               }
-               if (i >= scn->sst_len) {
-                       DPRINTF(("Out of bounds reading long sector chain "
-                           "%u > %u\n", i, scn->sst_len));
-                       errno = EFTYPE;
-                       goto out;
-               }
-               if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
-                   sid)) != (ssize_t)ss) {
-                       if (i == scn->sst_len - 1 && nr > 0) {
-                               /* Last sector might be truncated */
-                               return 0;
-                       }
-                       DPRINTF(("Reading long sector chain %d", sid));
-                       goto out;
-               }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
-       }
-       return 0;
+        size_t ss = CDF_SEC_SIZE(h), i, j;
+        ssize_t nr;
+        scn->sst_len = cdf_count_chain(sat, sid, ss);
+        scn->sst_dirlen = len;
+
+        if (scn->sst_len == (size_t)-1)
+                return -1;
+
+        scn->sst_tab = calloc(scn->sst_len, ss);
+        if (scn->sst_tab == NULL)
+                return -1;
+
+        for (j = i = 0; sid >= 0; i++, j++) {
+                if (j >= CDF_LOOP_LIMIT) {
+                        DPRINTF(("Read long sector chain loop limit"));
+                        errno = EFTYPE;
+                        goto out;
+                }
+                if (i >= scn->sst_len) {
+                        DPRINTF(("Out of bounds reading long sector chain "
+                            "%u > %u\n", i, scn->sst_len));
+                        errno = EFTYPE;
+                        goto out;
+                }
+                if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
+                    sid)) != (ssize_t)ss) {
+                        if (i == scn->sst_len - 1 && nr > 0) {
+                                /* Last sector might be truncated */
+                                return 0;
+                        }
+                        DPRINTF(("Reading long sector chain %d", sid));
+                        goto out;
+                }
+                sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+        }
+        return 0;
 out:
-       free(scn->sst_tab);
-       return -1;
+        free(scn->sst_tab);
+        return -1;
 }
 
 int
@@ -485,40 +488,40 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
     const cdf_sat_t *ssat, const cdf_stream_t *sst,
     cdf_secid_t sid, size_t len, cdf_stream_t *scn)
 {
-       size_t ss = CDF_SHORT_SEC_SIZE(h), i, j;
-       scn->sst_len = cdf_count_chain(ssat, sid, CDF_SEC_SIZE(h));
-       scn->sst_dirlen = len;
-
-       if (sst->sst_tab == NULL || scn->sst_len == (size_t)-1)
-               return -1;
-
-       scn->sst_tab = calloc(scn->sst_len, ss);
-       if (scn->sst_tab == NULL)
-               return -1;
-
-       for (j = i = 0; sid >= 0; i++, j++) {
-               if (j >= CDF_LOOP_LIMIT) {
-                       DPRINTF(("Read short sector chain loop limit"));
-                       errno = EFTYPE;
-                       goto out;
-               }
-               if (i >= scn->sst_len) {
-                       DPRINTF(("Out of bounds reading short sector chain "
-                           "%u > %u\n", i, scn->sst_len));
-                       errno = EFTYPE;
-                       goto out;
-               }
-               if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
-                   sid) != (ssize_t)ss) {
-                       DPRINTF(("Reading short sector chain %d", sid));
-                       goto out;
-               }
-               sid = CDF_TOLE4((uint32_t)ssat->sat_tab[sid]);
-       }
-       return 0;
+        size_t ss = CDF_SHORT_SEC_SIZE(h), i, j;
+        scn->sst_len = cdf_count_chain(ssat, sid, CDF_SEC_SIZE(h));
+        scn->sst_dirlen = len;
+
+        if (sst->sst_tab == NULL || scn->sst_len == (size_t)-1)
+                return -1;
+
+        scn->sst_tab = calloc(scn->sst_len, ss);
+        if (scn->sst_tab == NULL)
+                return -1;
+
+        for (j = i = 0; sid >= 0; i++, j++) {
+                if (j >= CDF_LOOP_LIMIT) {
+                        DPRINTF(("Read short sector chain loop limit"));
+                        errno = EFTYPE;
+                        goto out;
+                }
+                if (i >= scn->sst_len) {
+                        DPRINTF(("Out of bounds reading short sector chain "
+                            "%u > %u\n", i, scn->sst_len));
+                        errno = EFTYPE;
+                        goto out;
+                }
+                if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
+                    sid) != (ssize_t)ss) {
+                        DPRINTF(("Reading short sector chain %d", sid));
+                        goto out;
+                }
+                sid = CDF_TOLE4((uint32_t)ssat->sat_tab[sid]);
+        }
+        return 0;
 out:
-       free(scn->sst_tab);
-       return -1;
+        free(scn->sst_tab);
+        return -1;
 }
 
 int
@@ -527,64 +530,64 @@ cdf_read_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
     cdf_secid_t sid, size_t len, cdf_stream_t *scn)
 {
 
-       if (len < h->h_min_size_standard_stream && sst->sst_tab != NULL)
-               return cdf_read_short_sector_chain(h, ssat, sst, sid, len,
-                   scn);
-       else
-               return cdf_read_long_sector_chain(info, h, sat, sid, len, scn);
+        if (len < h->h_min_size_standard_stream && sst->sst_tab != NULL)
+                return cdf_read_short_sector_chain(h, ssat, sst, sid, len,
+                    scn);
+        else
+                return cdf_read_long_sector_chain(info, h, sat, sid, len, scn);
 }
 
 int
 cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, cdf_dir_t *dir)
 {
-       size_t i, j;
-       size_t ss = CDF_SEC_SIZE(h), ns, nd;
-       char *buf;
-       cdf_secid_t sid = h->h_secid_first_directory;
-
-       ns = cdf_count_chain(sat, sid, ss);
-       if (ns == (size_t)-1)
-               return -1;
-
-       nd = ss / CDF_DIRECTORY_SIZE;
-
-       dir->dir_len = ns * nd;
-       dir->dir_tab = CAST(cdf_directory_t *, 
-           calloc(dir->dir_len, sizeof(dir->dir_tab[0])));
-       if (dir->dir_tab == NULL)
-               return -1;
-
-       if ((buf = CAST(char *, malloc(ss))) == NULL) {
-               free(dir->dir_tab);
-               return -1;
-       }
-
-       for (j = i = 0; i < ns; i++, j++) {
-               if (j >= CDF_LOOP_LIMIT) {
-                       DPRINTF(("Read dir loop limit"));
-                       errno = EFTYPE;
-                       goto out;
-               }
-               if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) {
-                       DPRINTF(("Reading directory sector %d", sid));
-                       goto out;
-               }
-               for (j = 0; j < nd; j++) {
-                       cdf_unpack_dir(&dir->dir_tab[i * nd + j],
-                           &buf[j * CDF_DIRECTORY_SIZE]);
-               }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
-       }
-       if (NEED_SWAP)
-               for (i = 0; i < dir->dir_len; i++)
-                       cdf_swap_dir(&dir->dir_tab[i]);
-       free(buf);
-       return 0;
+        size_t i, j;
+        size_t ss = CDF_SEC_SIZE(h), ns, nd;
+        char *buf;
+        cdf_secid_t sid = h->h_secid_first_directory;
+
+        ns = cdf_count_chain(sat, sid, ss);
+        if (ns == (size_t)-1)
+                return -1;
+
+        nd = ss / CDF_DIRECTORY_SIZE;
+
+        dir->dir_len = ns * nd;
+        dir->dir_tab = CAST(cdf_directory_t *,
+            calloc(dir->dir_len, sizeof(dir->dir_tab[0])));
+        if (dir->dir_tab == NULL)
+                return -1;
+
+        if ((buf = CAST(char *, malloc(ss))) == NULL) {
+                free(dir->dir_tab);
+                return -1;
+        }
+
+        for (j = i = 0; i < ns; i++, j++) {
+                if (j >= CDF_LOOP_LIMIT) {
+                        DPRINTF(("Read dir loop limit"));
+                        errno = EFTYPE;
+                        goto out;
+                }
+                if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) {
+                        DPRINTF(("Reading directory sector %d", sid));
+                        goto out;
+                }
+                for (j = 0; j < nd; j++) {
+                        cdf_unpack_dir(&dir->dir_tab[i * nd + j],
+                            &buf[j * CDF_DIRECTORY_SIZE]);
+                }
+                sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+        }
+        if (NEED_SWAP)
+                for (i = 0; i < dir->dir_len; i++)
+                        cdf_swap_dir(&dir->dir_tab[i]);
+        free(buf);
+        return 0;
 out:
-       free(dir->dir_tab);
-       free(buf);
-       return -1;
+        free(dir->dir_tab);
+        free(buf);
+        return -1;
 }
 
 
@@ -592,79 +595,79 @@ int
 cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, cdf_sat_t *ssat)
 {
-       size_t i, j;
-       size_t ss = CDF_SEC_SIZE(h);
-       cdf_secid_t sid = h->h_secid_first_sector_in_short_sat;
-
-       ssat->sat_len = cdf_count_chain(sat, sid, CDF_SEC_SIZE(h));
-       if (ssat->sat_len == (size_t)-1)
-               return -1;
-
-       ssat->sat_tab = CAST(cdf_secid_t *, calloc(ssat->sat_len, ss));
-       if (ssat->sat_tab == NULL)
-               return -1;
-
-       for (j = i = 0; sid >= 0; i++, j++) {
-               if (j >= CDF_LOOP_LIMIT) {
-                       DPRINTF(("Read short sat sector loop limit"));
-                       errno = EFTYPE;
-                       goto out;
-               }
-               if (i >= ssat->sat_len) {
-                       DPRINTF(("Out of bounds reading short sector chain "
-                           "%u > %u\n", i, ssat->sat_len));
-                       errno = EFTYPE;
-                       goto out;
-               }
-               if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
-                   (ssize_t)ss) {
-                       DPRINTF(("Reading short sat sector %d", sid));
-                       goto out;
-               }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
-       }
-       return 0;
+        size_t i, j;
+        size_t ss = CDF_SEC_SIZE(h);
+        cdf_secid_t sid = h->h_secid_first_sector_in_short_sat;
+
+        ssat->sat_len = cdf_count_chain(sat, sid, CDF_SEC_SIZE(h));
+        if (ssat->sat_len == (size_t)-1)
+                return -1;
+
+        ssat->sat_tab = CAST(cdf_secid_t *, calloc(ssat->sat_len, ss));
+        if (ssat->sat_tab == NULL)
+                return -1;
+
+        for (j = i = 0; sid >= 0; i++, j++) {
+                if (j >= CDF_LOOP_LIMIT) {
+                        DPRINTF(("Read short sat sector loop limit"));
+                        errno = EFTYPE;
+                        goto out;
+                }
+                if (i >= ssat->sat_len) {
+                        DPRINTF(("Out of bounds reading short sector chain "
+                            "%u > %u\n", i, ssat->sat_len));
+                        errno = EFTYPE;
+                        goto out;
+                }
+                if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
+                    (ssize_t)ss) {
+                        DPRINTF(("Reading short sat sector %d", sid));
+                        goto out;
+                }
+                sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+        }
+        return 0;
 out:
-       free(ssat->sat_tab);
-       return -1;
+        free(ssat->sat_tab);
+        return -1;
 }
 
 int
 cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn)
 {
-       size_t i;
-       const cdf_directory_t *d;
+        size_t i;
+        const cdf_directory_t *d;
 
-       for (i = 0; i < dir->dir_len; i++)
-               if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE)
-                       break;
+        for (i = 0; i < dir->dir_len; i++)
+                if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE)
+                        break;
 
-       /* If the it is not there, just fake it; some docs don't have it */
-       if (i == dir->dir_len)
-               goto out;
-       d = &dir->dir_tab[i];
+        /* If the it is not there, just fake it; some docs don't have it */
+        if (i == dir->dir_len)
+                goto out;
+        d = &dir->dir_tab[i];
 
-       /* If the it is not there, just fake it; some docs don't have it */
-       if (d->d_stream_first_sector < 0)
-               goto out;
+        /* If the it is not there, just fake it; some docs don't have it */
+        if (d->d_stream_first_sector < 0)
+                goto out;
 
-       return  cdf_read_long_sector_chain(info, h, sat,
-           d->d_stream_first_sector, d->d_size, scn);
+        return  cdf_read_long_sector_chain(info, h, sat,
+            d->d_stream_first_sector, d->d_size, scn);
 out:
-       scn->sst_tab = NULL;
-       scn->sst_len = 0;
-       scn->sst_dirlen = 0;
-       return 0;
+        scn->sst_tab = NULL;
+        scn->sst_len = 0;
+        scn->sst_dirlen = 0;
+        return 0;
 }
 
 static int
 cdf_namecmp(const char *d, const uint16_t *s, size_t l)
 {
-       for (; l--; d++, s++)
-               if (*d != CDF_TOLE2(*s))
-                       return (unsigned char)*d - CDF_TOLE2(*s);
-       return 0;
+        for (; l--; d++, s++)
+                if (*d != CDF_TOLE2(*s))
+                        return (unsigned char)*d - CDF_TOLE2(*s);
+        return 0;
 }
 
 int
@@ -672,227 +675,227 @@ cdf_read_summary_info(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
     const cdf_dir_t *dir, cdf_stream_t *scn)
 {
-       size_t i;
-       const cdf_directory_t *d;
-       static const char name[] = "\05SummaryInformation";
-
-       for (i = dir->dir_len; i > 0; i--)
-               if (dir->dir_tab[i - 1].d_type == CDF_DIR_TYPE_USER_STREAM &&
-                   cdf_namecmp(name, dir->dir_tab[i - 1].d_name, sizeof(name))
-                   == 0)
-                       break;
-
-       if (i == 0) {
-               DPRINTF(("Cannot find summary information section\n"));
-               errno = ESRCH;
-               return -1;
-       }
-       d = &dir->dir_tab[i - 1];
-       return cdf_read_sector_chain(info, h, sat, ssat, sst,
-           d->d_stream_first_sector, d->d_size, scn);
+        size_t i;
+        const cdf_directory_t *d;
+        static const char name[] = "\05SummaryInformation";
+
+        for (i = dir->dir_len; i > 0; i--)
+                if (dir->dir_tab[i - 1].d_type == CDF_DIR_TYPE_USER_STREAM &&
+                    cdf_namecmp(name, dir->dir_tab[i - 1].d_name, sizeof(name))
+                    == 0)
+                        break;
+
+        if (i == 0) {
+                DPRINTF(("Cannot find summary information section\n"));
+                errno = ESRCH;
+                return -1;
+        }
+        d = &dir->dir_tab[i - 1];
+        return cdf_read_sector_chain(info, h, sat, ssat, sst,
+            d->d_stream_first_sector, d->d_size, scn);
 }
 
 int
 cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
     cdf_property_info_t **info, size_t *count, size_t *maxcount)
 {
-       const cdf_section_header_t *shp;
-       cdf_section_header_t sh;
-       const uint32_t *p, *q, *e;
-       int16_t s16;
-       int32_t s32;
-       uint32_t u32;
-       int64_t s64;
-       uint64_t u64;
-       cdf_timestamp_t tp;
-       size_t i, o, nelements, j;
-       cdf_property_info_t *inp;
-
-       if (offs > UINT32_MAX / 4) {
-               errno = EFTYPE;
-               goto out;
-       }
-       shp = CAST(const cdf_section_header_t *, (const void *)
-           ((const char *)sst->sst_tab + offs));
-       if (cdf_check_stream_offset(sst, shp, sizeof(*shp), __LINE__) == -1)
-               goto out;
-       sh.sh_len = CDF_TOLE4(shp->sh_len);
+        const cdf_section_header_t *shp;
+        cdf_section_header_t sh;
+        const uint32_t *p, *q, *e;
+        int16_t s16;
+        int32_t s32;
+        uint32_t u32;
+        int64_t s64;
+        uint64_t u64;
+        cdf_timestamp_t tp;
+        size_t i, o, nelements, j;
+        cdf_property_info_t *inp;
+
+        if (offs > UINT32_MAX / 4) {
+                errno = EFTYPE;
+                goto out;
+        }
+        shp = CAST(const cdf_section_header_t *, (const void *)
+            ((const char *)sst->sst_tab + offs));
+        if (cdf_check_stream_offset(sst, shp, sizeof(*shp), __LINE__) == -1)
+                goto out;
+        sh.sh_len = CDF_TOLE4(shp->sh_len);
 #define CDF_SHLEN_LIMIT (UINT32_MAX / 8)
-       if (sh.sh_len > CDF_SHLEN_LIMIT) {
-               errno = EFTYPE;
-               goto out;
-       }
-       sh.sh_properties = CDF_TOLE4(shp->sh_properties);
+        if (sh.sh_len > CDF_SHLEN_LIMIT) {
+                errno = EFTYPE;
+                goto out;
+        }
+        sh.sh_properties = CDF_TOLE4(shp->sh_properties);
 #define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(*inp)))
-       if (sh.sh_properties > CDF_PROP_LIMIT)
-               goto out;
-       DPRINTF(("section len: %u properties %u\n", sh.sh_len,
-           sh.sh_properties));
-       if (*maxcount) {
-               if (*maxcount > CDF_PROP_LIMIT)
-                       goto out;
-               *maxcount += sh.sh_properties;
-               inp = CAST(cdf_property_info_t *,
-                   realloc(*info, *maxcount * sizeof(*inp)));
-       } else {
-               *maxcount = sh.sh_properties;
-               inp = CAST(cdf_property_info_t *,
-                   malloc(*maxcount * sizeof(*inp)));
-       }
-       if (inp == NULL)
-               goto out;
-       *info = inp;
-       inp += *count;
-       *count += sh.sh_properties;
-       p = CAST(const uint32_t *, (const void *)
-           ((const char *)(const void *)sst->sst_tab +
-           offs + sizeof(sh)));
-       e = CAST(const uint32_t *, (const void *)
-           (((const char *)(const void *)shp) + sh.sh_len));
-       if (cdf_check_stream_offset(sst, e, 0, __LINE__) == -1)
-               goto out;
-       for (i = 0; i < sh.sh_properties; i++) {
-               q = (const uint32_t *)(const void *)
-                   ((const char *)(const void *)p +
-                   CDF_TOLE4(p[(i << 1) + 1])) - 2;
-               if (q > e) {
-                       DPRINTF(("Ran of the end %p > %p\n", q, e));
-                       goto out;
-               }
-               inp[i].pi_id = CDF_TOLE4(p[i << 1]);
-               inp[i].pi_type = CDF_TOLE4(q[0]);
-               DPRINTF(("%d) id=%x type=%x offs=%x\n", i, inp[i].pi_id,
-                   inp[i].pi_type, (const char *)q - (const char *)p));
-               if (inp[i].pi_type & CDF_VECTOR) {
-                       nelements = CDF_TOLE4(q[1]);
-                       o = 2;
-               } else {
-                       nelements = 1;
-                       o = 1;
-               }
-               if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED))
-                       goto unknown;
-               switch (inp[i].pi_type & CDF_TYPEMASK) {
-               case CDF_NULL:
-               case CDF_EMPTY:
-                       break;
-               case CDF_SIGNED16:
-                       if (inp[i].pi_type & CDF_VECTOR)
-                               goto unknown;
-                       (void)memcpy(&s16, &q[o], sizeof(s16));
-                       inp[i].pi_s16 = CDF_TOLE2(s16);
-                       break;
-               case CDF_SIGNED32:
-                       if (inp[i].pi_type & CDF_VECTOR)
-                               goto unknown;
-                       (void)memcpy(&s32, &q[o], sizeof(s32));
-                       inp[i].pi_s32 = CDF_TOLE4((uint32_t)s32);
-                       break;
-               case CDF_BOOL:
-               case CDF_UNSIGNED32:
-                       if (inp[i].pi_type & CDF_VECTOR)
-                               goto unknown;
-                       (void)memcpy(&u32, &q[o], sizeof(u32));
-                       inp[i].pi_u32 = CDF_TOLE4(u32);
-                       break;
-               case CDF_SIGNED64:
-                       if (inp[i].pi_type & CDF_VECTOR)
-                               goto unknown;
-                       (void)memcpy(&s64, &q[o], sizeof(s64));
-                       inp[i].pi_s64 = CDF_TOLE8((uint64_t)s64);
-                       break;
-               case CDF_UNSIGNED64:
-                       if (inp[i].pi_type & CDF_VECTOR)
-                               goto unknown;
-                       (void)memcpy(&u64, &q[o], sizeof(u64));
-                       inp[i].pi_u64 = CDF_TOLE8((uint64_t)u64);
-                       break;
-               case CDF_LENGTH32_STRING:
-               case CDF_LENGTH32_WSTRING:
-                       if (nelements > 1) {
-                               size_t nelem = inp - *info;
-                               if (*maxcount > CDF_PROP_LIMIT
-                                   || nelements > CDF_PROP_LIMIT)
-                                       goto out;
-                               *maxcount += nelements;
-                               inp = CAST(cdf_property_info_t *,
-                                   realloc(*info, *maxcount * sizeof(*inp)));
-                               if (inp == NULL)
-                                       goto out;
-                               *info = inp;
-                               inp = *info + nelem;
-                       }
-                       DPRINTF(("nelements = %d\n", nelements));
-                       for (j = 0; j < nelements; j++, i++) {
-                               uint32_t l = CDF_TOLE4(q[o]);
-                               inp[i].pi_str.s_len = l;
-                               inp[i].pi_str.s_buf =
-                                   (const char *)(const void *)(&q[o+1]);
-                               DPRINTF(("l = %d, r = %d, s = %s\n", l,
-                                   CDF_ROUND(l, sizeof(l)),
-                                   inp[i].pi_str.s_buf));
-                               l = 4 + (uint32_t)CDF_ROUND(l, sizeof(l));
-                               o += l >> 2;
-                       }
-                       i--;
-                       break;
-               case CDF_FILETIME:
-                       if (inp[i].pi_type & CDF_VECTOR)
-                               goto unknown;
-                       (void)memcpy(&tp, &q[o], sizeof(tp));
-                       inp[i].pi_tp = CDF_TOLE8((uint64_t)tp);
-                       break;
-               case CDF_CLIPBOARD:
-                       if (inp[i].pi_type & CDF_VECTOR)
-                               goto unknown;
-                       break;
-               default:
-               unknown:
-                       DPRINTF(("Don't know how to deal with %x\n",
-                           inp[i].pi_type));
-                       goto out;
-               }
-       }
-       return 0;
+        if (sh.sh_properties > CDF_PROP_LIMIT)
+                goto out;
+        DPRINTF(("section len: %u properties %u\n", sh.sh_len,
+            sh.sh_properties));
+        if (*maxcount) {
+                if (*maxcount > CDF_PROP_LIMIT)
+                        goto out;
+                *maxcount += sh.sh_properties;
+                inp = CAST(cdf_property_info_t *,
+                    realloc(*info, *maxcount * sizeof(*inp)));
+        } else {
+                *maxcount = sh.sh_properties;
+                inp = CAST(cdf_property_info_t *,
+                    malloc(*maxcount * sizeof(*inp)));
+        }
+        if (inp == NULL)
+                goto out;
+        *info = inp;
+        inp += *count;
+        *count += sh.sh_properties;
+        p = CAST(const uint32_t *, (const void *)
+            ((const char *)(const void *)sst->sst_tab +
+            offs + sizeof(sh)));
+        e = CAST(const uint32_t *, (const void *)
+            (((const char *)(const void *)shp) + sh.sh_len));
+        if (cdf_check_stream_offset(sst, e, 0, __LINE__) == -1)
+                goto out;
+        for (i = 0; i < sh.sh_properties; i++) {
+                q = (const uint32_t *)(const void *)
+                    ((const char *)(const void *)p +
+                    CDF_TOLE4(p[(i << 1) + 1])) - 2;
+                if (q > e) {
+                        DPRINTF(("Ran of the end %p > %p\n", q, e));
+                        goto out;
+                }
+                inp[i].pi_id = CDF_TOLE4(p[i << 1]);
+                inp[i].pi_type = CDF_TOLE4(q[0]);
+                DPRINTF(("%d) id=%x type=%x offs=%x\n", i, inp[i].pi_id,
+                    inp[i].pi_type, (const char *)q - (const char *)p));
+                if (inp[i].pi_type & CDF_VECTOR) {
+                        nelements = CDF_TOLE4(q[1]);
+                        o = 2;
+                } else {
+                        nelements = 1;
+                        o = 1;
+                }
+                if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED))
+                        goto unknown;
+                switch (inp[i].pi_type & CDF_TYPEMASK) {
+                case CDF_NULL:
+                case CDF_EMPTY:
+                        break;
+                case CDF_SIGNED16:
+                        if (inp[i].pi_type & CDF_VECTOR)
+                                goto unknown;
+                        (void)memcpy(&s16, &q[o], sizeof(s16));
+                        inp[i].pi_s16 = CDF_TOLE2(s16);
+                        break;
+                case CDF_SIGNED32:
+                        if (inp[i].pi_type & CDF_VECTOR)
+                                goto unknown;
+                        (void)memcpy(&s32, &q[o], sizeof(s32));
+                        inp[i].pi_s32 = CDF_TOLE4((uint32_t)s32);
+                        break;
+                case CDF_BOOL:
+                case CDF_UNSIGNED32:
+                        if (inp[i].pi_type & CDF_VECTOR)
+                                goto unknown;
+                        (void)memcpy(&u32, &q[o], sizeof(u32));
+                        inp[i].pi_u32 = CDF_TOLE4(u32);
+                        break;
+                case CDF_SIGNED64:
+                        if (inp[i].pi_type & CDF_VECTOR)
+                                goto unknown;
+                        (void)memcpy(&s64, &q[o], sizeof(s64));
+                        inp[i].pi_s64 = CDF_TOLE8((uint64_t)s64);
+                        break;
+                case CDF_UNSIGNED64:
+                        if (inp[i].pi_type & CDF_VECTOR)
+                                goto unknown;
+                        (void)memcpy(&u64, &q[o], sizeof(u64));
+                        inp[i].pi_u64 = CDF_TOLE8((uint64_t)u64);
+                        break;
+                case CDF_LENGTH32_STRING:
+                case CDF_LENGTH32_WSTRING:
+                        if (nelements > 1) {
+                                size_t nelem = inp - *info;
+                                if (*maxcount > CDF_PROP_LIMIT
+                                    || nelements > CDF_PROP_LIMIT)
+                                        goto out;
+                                *maxcount += nelements;
+                                inp = CAST(cdf_property_info_t *,
+                                    realloc(*info, *maxcount * sizeof(*inp)));
+                                if (inp == NULL)
+                                        goto out;
+                                *info = inp;
+                                inp = *info + nelem;
+                        }
+                        DPRINTF(("nelements = %d\n", nelements));
+                        for (j = 0; j < nelements; j++, i++) {
+                                uint32_t l = CDF_TOLE4(q[o]);
+                                inp[i].pi_str.s_len = l;
+                                inp[i].pi_str.s_buf =
+                                    (const char *)(const void *)(&q[o+1]);
+                                DPRINTF(("l = %d, r = %d, s = %s\n", l,
+                                    CDF_ROUND(l, sizeof(l)),
+                                    inp[i].pi_str.s_buf));
+                                l = 4 + (uint32_t)CDF_ROUND(l, sizeof(l));
+                                o += l >> 2;
+                        }
+                        i--;
+                        break;
+                case CDF_FILETIME:
+                        if (inp[i].pi_type & CDF_VECTOR)
+                                goto unknown;
+                        (void)memcpy(&tp, &q[o], sizeof(tp));
+                        inp[i].pi_tp = CDF_TOLE8((uint64_t)tp);
+                        break;
+                case CDF_CLIPBOARD:
+                        if (inp[i].pi_type & CDF_VECTOR)
+                                goto unknown;
+                        break;
+                default:
+                unknown:
+                        DPRINTF(("Don't know how to deal with %x\n",
+                            inp[i].pi_type));
+                        goto out;
+                }
+        }
+        return 0;
 out:
-       free(*info);
-       return -1;
+        free(*info);
+        return -1;
 }
 
 int
 cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi,
     cdf_property_info_t **info, size_t *count)
 {
-       size_t i, maxcount;
-       const cdf_summary_info_header_t *si =
-           CAST(const cdf_summary_info_header_t *, sst->sst_tab);
-       const cdf_section_declaration_t *sd =
-           CAST(const cdf_section_declaration_t *, (const void *)
-           ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET));
-
-       if (cdf_check_stream_offset(sst, si, sizeof(*si), __LINE__) == -1 ||
-           cdf_check_stream_offset(sst, sd, sizeof(*sd), __LINE__) == -1)
-               return -1;
-       ssi->si_byte_order = CDF_TOLE2(si->si_byte_order);
-       ssi->si_os_version = CDF_TOLE2(si->si_os_version);
-       ssi->si_os = CDF_TOLE2(si->si_os);
-       ssi->si_class = si->si_class;
-       cdf_swap_class(&ssi->si_class);
-       ssi->si_count = CDF_TOLE2(si->si_count);
-       *count = 0;
-       maxcount = 0;
-       *info = NULL;
-       for (i = 0; i < CDF_TOLE4(si->si_count); i++) {
-               if (i >= CDF_LOOP_LIMIT) {
-                       DPRINTF(("Unpack summary info loop limit"));
-                       errno = EFTYPE;
-                       return -1;
-               }
-               if (cdf_read_property_info(sst, CDF_TOLE4(sd->sd_offset),
-                   info, count, &maxcount) == -1)
-                       return -1;
-       }
-       return 0;
+        size_t i, maxcount;
+        const cdf_summary_info_header_t *si =
+            CAST(const cdf_summary_info_header_t *, sst->sst_tab);
+        const cdf_section_declaration_t *sd =
+            CAST(const cdf_section_declaration_t *, (const void *)
+            ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET));
+
+        if (cdf_check_stream_offset(sst, si, sizeof(*si), __LINE__) == -1 ||
+            cdf_check_stream_offset(sst, sd, sizeof(*sd), __LINE__) == -1)
+                return -1;
+        ssi->si_byte_order = CDF_TOLE2(si->si_byte_order);
+        ssi->si_os_version = CDF_TOLE2(si->si_os_version);
+        ssi->si_os = CDF_TOLE2(si->si_os);
+        ssi->si_class = si->si_class;
+        cdf_swap_class(&ssi->si_class);
+        ssi->si_count = CDF_TOLE2(si->si_count);
+        *count = 0;
+        maxcount = 0;
+        *info = NULL;
+        for (i = 0; i < CDF_TOLE4(si->si_count); i++) {
+                if (i >= CDF_LOOP_LIMIT) {
+                        DPRINTF(("Unpack summary info loop limit"));
+                        errno = EFTYPE;
+                        return -1;
+                }
+                if (cdf_read_property_info(sst, CDF_TOLE4(sd->sd_offset),
+                    info, count, &maxcount) == -1)
+                        return -1;
+        }
+        return 0;
 }
 
 
@@ -900,83 +903,83 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi,
 int
 cdf_print_classid(char *buf, size_t buflen, const cdf_classid_t *id)
 {
-       return snprintf(buf, buflen, "%.8x-%.4x-%.4x-%.2x%.2x-"
-           "%.2x%.2x%.2x%.2x%.2x%.2x", id->cl_dword, id->cl_word[0],
-           id->cl_word[1], id->cl_two[0], id->cl_two[1], id->cl_six[0],
-           id->cl_six[1], id->cl_six[2], id->cl_six[3], id->cl_six[4],
-           id->cl_six[5]);
+        return snprintf(buf, buflen, "%.8x-%.4x-%.4x-%.2x%.2x-"
+            "%.2x%.2x%.2x%.2x%.2x%.2x", id->cl_dword, id->cl_word[0],
+            id->cl_word[1], id->cl_two[0], id->cl_two[1], id->cl_six[0],
+            id->cl_six[1], id->cl_six[2], id->cl_six[3], id->cl_six[4],
+            id->cl_six[5]);
 }
 
 static const struct {
-       uint32_t v;
-       const char *n;
+        uint32_t v;
+        const char *n;
 } vn[] = {
-       { CDF_PROPERTY_CODE_PAGE, "Code page" },
-       { CDF_PROPERTY_TITLE, "Title" },
-       { CDF_PROPERTY_SUBJECT, "Subject" },
-       { CDF_PROPERTY_AUTHOR, "Author" },
-       { CDF_PROPERTY_KEYWORDS, "Keywords" },
-       { CDF_PROPERTY_COMMENTS, "Comments" },
-       { CDF_PROPERTY_TEMPLATE, "Template" },
-       { CDF_PROPERTY_LAST_SAVED_BY, "Last Saved By" },
-       { CDF_PROPERTY_REVISION_NUMBER, "Revision Number" },
-       { CDF_PROPERTY_TOTAL_EDITING_TIME, "Total Editing Time" },
-       { CDF_PROPERTY_LAST_PRINTED, "Last Printed" },
-       { CDF_PROPERTY_CREATE_TIME, "Create Time/Date" },
-       { CDF_PROPERTY_LAST_SAVED_TIME, "Last Saved Time/Date" },
-       { CDF_PROPERTY_NUMBER_OF_PAGES, "Number of Pages" },
-       { CDF_PROPERTY_NUMBER_OF_WORDS, "Number of Words" },
-       { CDF_PROPERTY_NUMBER_OF_CHARACTERS, "Number of Characters" },
-       { CDF_PROPERTY_THUMBNAIL, "Thumbnail" },
-       { CDF_PROPERTY_NAME_OF_APPLICATION, "Name of Creating Application" },
-       { CDF_PROPERTY_SECURITY, "Security" },
-       { CDF_PROPERTY_LOCALE_ID, "Locale ID" },
+        { CDF_PROPERTY_CODE_PAGE, "Code page" },
+        { CDF_PROPERTY_TITLE, "Title" },
+        { CDF_PROPERTY_SUBJECT, "Subject" },
+        { CDF_PROPERTY_AUTHOR, "Author" },
+        { CDF_PROPERTY_KEYWORDS, "Keywords" },
+        { CDF_PROPERTY_COMMENTS, "Comments" },
+        { CDF_PROPERTY_TEMPLATE, "Template" },
+        { CDF_PROPERTY_LAST_SAVED_BY, "Last Saved By" },
+        { CDF_PROPERTY_REVISION_NUMBER, "Revision Number" },
+        { CDF_PROPERTY_TOTAL_EDITING_TIME, "Total Editing Time" },
+        { CDF_PROPERTY_LAST_PRINTED, "Last Printed" },
+        { CDF_PROPERTY_CREATE_TIME, "Create Time/Date" },
+        { CDF_PROPERTY_LAST_SAVED_TIME, "Last Saved Time/Date" },
+        { CDF_PROPERTY_NUMBER_OF_PAGES, "Number of Pages" },
+        { CDF_PROPERTY_NUMBER_OF_WORDS, "Number of Words" },
+        { CDF_PROPERTY_NUMBER_OF_CHARACTERS, "Number of Characters" },
+        { CDF_PROPERTY_THUMBNAIL, "Thumbnail" },
+        { CDF_PROPERTY_NAME_OF_APPLICATION, "Name of Creating Application" },
+        { CDF_PROPERTY_SECURITY, "Security" },
+        { CDF_PROPERTY_LOCALE_ID, "Locale ID" },
 };
 
 int
 cdf_print_property_name(char *buf, size_t bufsiz, uint32_t p)
 {
-       size_t i;
+        size_t i;
 
-       for (i = 0; i < __arraycount(vn); i++)
-               if (vn[i].v == p)
-                       return snprintf(buf, bufsiz, "%s", vn[i].n);
-       return snprintf(buf, bufsiz, "0x%x", p);
+        for (i = 0; i < __arraycount(vn); i++)
+                if (vn[i].v == p)
+                        return snprintf(buf, bufsiz, "%s", vn[i].n);
+        return snprintf(buf, bufsiz, "0x%x", p);
 }
 
 int
 cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts)
 {
-       int len = 0;
-       int days, hours, mins, secs;
-
-       ts /= CDF_TIME_PREC;
-       secs = (int)(ts % 60);
-       ts /= 60;
-       mins = (int)(ts % 60);
-       ts /= 60;
-       hours = (int)(ts % 24);
-       ts /= 24;
-       days = (int)ts;
-
-       if (days) {
-               len += snprintf(buf + len, bufsiz - len, "%dd+", days);
-               if ((size_t)len >= bufsiz)
-                       return len;
-       }
-
-       if (days || hours) {
-               len += snprintf(buf + len, bufsiz - len, "%.2d:", hours);
-               if ((size_t)len >= bufsiz)
-                       return len;
-       }
-
-       len += snprintf(buf + len, bufsiz - len, "%.2d:", mins);
-       if ((size_t)len >= bufsiz)
-               return len;
-
-       len += snprintf(buf + len, bufsiz - len, "%.2d", secs);
-       return len;
+        int len = 0;
+        int days, hours, mins, secs;
+
+        ts /= CDF_TIME_PREC;
+        secs = (int)(ts % 60);
+        ts /= 60;
+        mins = (int)(ts % 60);
+        ts /= 60;
+        hours = (int)(ts % 24);
+        ts /= 24;
+        days = (int)ts;
+
+        if (days) {
+                len += snprintf(buf + len, bufsiz - len, "%dd+", days);
+                if ((size_t)len >= bufsiz)
+                        return len;
+        }
+
+        if (days || hours) {
+                len += snprintf(buf + len, bufsiz - len, "%.2d:", hours);
+                if ((size_t)len >= bufsiz)
+                        return len;
+        }
+
+        len += snprintf(buf + len, bufsiz - len, "%.2d:", mins);
+        if ((size_t)len >= bufsiz)
+                return len;
+
+        len += snprintf(buf + len, bufsiz - len, "%.2d", secs);
+        return len;
 }
 
 
@@ -984,74 +987,74 @@ cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts)
 void
 cdf_dump_header(const cdf_header_t *h)
 {
-       size_t i;
+        size_t i;
 
 #define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b)
 #define DUMP2(a, b) (void)fprintf(stderr, "%40.40s = " a " (" a ")\n", # b, \
     h->h_ ## b, 1 << h->h_ ## b)
-       DUMP("%d", revision);
-       DUMP("%d", version);
-       DUMP("0x%x", byte_order);
-       DUMP2("%d", sec_size_p2);
-       DUMP2("%d", short_sec_size_p2);
-       DUMP("%d", num_sectors_in_sat);
-       DUMP("%d", secid_first_directory);
-       DUMP("%d", min_size_standard_stream);
-       DUMP("%d", secid_first_sector_in_short_sat);
-       DUMP("%d", num_sectors_in_short_sat);
-       DUMP("%d", secid_first_sector_in_master_sat);
-       DUMP("%d", num_sectors_in_master_sat);
-       for (i = 0; i < __arraycount(h->h_master_sat); i++) {
-               if (h->h_master_sat[i] == CDF_SECID_FREE)
-                       break;
-               (void)fprintf(stderr, "%35.35s[%.3zu] = %d\n",
-                   "master_sat", i, h->h_master_sat[i]);
-       }
+        DUMP("%d", revision);
+        DUMP("%d", version);
+        DUMP("0x%x", byte_order);
+        DUMP2("%d", sec_size_p2);
+        DUMP2("%d", short_sec_size_p2);
+        DUMP("%d", num_sectors_in_sat);
+        DUMP("%d", secid_first_directory);
+        DUMP("%d", min_size_standard_stream);
+        DUMP("%d", secid_first_sector_in_short_sat);
+        DUMP("%d", num_sectors_in_short_sat);
+        DUMP("%d", secid_first_sector_in_master_sat);
+        DUMP("%d", num_sectors_in_master_sat);
+        for (i = 0; i < __arraycount(h->h_master_sat); i++) {
+                if (h->h_master_sat[i] == CDF_SECID_FREE)
+                        break;
+                (void)fprintf(stderr, "%35.35s[%.3zu] = %d\n",
+                    "master_sat", i, h->h_master_sat[i]);
+        }
 }
 
 void
 cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size)
 {
-       size_t i, j, s = size / sizeof(cdf_secid_t);
-
-       for (i = 0; i < sat->sat_len; i++) {
-               (void)fprintf(stderr, "%s[%zu]:\n%.6d: ", prefix, i, i * s);
-               for (j = 0; j < s; j++) {
-                       (void)fprintf(stderr, "%5d, ",
-                           CDF_TOLE4(sat->sat_tab[s * i + j]));
-                       if ((j + 1) % 10 == 0)
-                               (void)fprintf(stderr, "\n%.6d: ",
-                                   i * s + j + 1);
-               }
-               (void)fprintf(stderr, "\n");
-       }
+        size_t i, j, s = size / sizeof(cdf_secid_t);
+
+        for (i = 0; i < sat->sat_len; i++) {
+                (void)fprintf(stderr, "%s[%zu]:\n%.6d: ", prefix, i, i * s);
+                for (j = 0; j < s; j++) {
+                        (void)fprintf(stderr, "%5d, ",
+                            CDF_TOLE4(sat->sat_tab[s * i + j]));
+                        if ((j + 1) % 10 == 0)
+                                (void)fprintf(stderr, "\n%.6d: ",
+                                    i * s + j + 1);
+                }
+                (void)fprintf(stderr, "\n");
+        }
 }
 
 void
 cdf_dump(void *v, size_t len)
 {
-       size_t i, j;
-       unsigned char *p = v;
-       char abuf[16];
-       (void)fprintf(stderr, "%.4x: ", 0);
-       for (i = 0, j = 0; i < len; i++, p++) {
-               (void)fprintf(stderr, "%.2x ", *p);
-               abuf[j++] = isprint(*p) ? *p : '.';
-               if (j == 16) {
-                       j = 0;
-                       abuf[15] = '\0';
-                       (void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1);
-               }
-       }
-       (void)fprintf(stderr, "\n");
+        size_t i, j;
+        unsigned char *p = v;
+        char abuf[16];
+        (void)fprintf(stderr, "%.4x: ", 0);
+        for (i = 0, j = 0; i < len; i++, p++) {
+                (void)fprintf(stderr, "%.2x ", *p);
+                abuf[j++] = isprint(*p) ? *p : '.';
+                if (j == 16) {
+                        j = 0;
+                        abuf[15] = '\0';
+                        (void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1);
+                }
+        }
+        (void)fprintf(stderr, "\n");
 }
 
 void
 cdf_dump_stream(const cdf_header_t *h, const cdf_stream_t *sst)
 {
-       size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ?
-           CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h);
-       cdf_dump(sst->sst_tab, ss * sst->sst_len);
+        size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ?
+            CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h);
+        cdf_dump(sst->sst_tab, ss * sst->sst_len);
 }
 
 void
@@ -1059,139 +1062,139 @@ cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
     const cdf_dir_t *dir)
 {
-       size_t i, j;
-       cdf_directory_t *d;
-       char name[__arraycount(d->d_name)];
-       cdf_stream_t scn;
-       struct timespec ts;
-
-       static const char *types[] = { "empty", "user storage",
-           "user stream", "lockbytes", "property", "root storage" };
-
-       for (i = 0; i < dir->dir_len; i++) {
-               d = &dir->dir_tab[i];
-               for (j = 0; j < sizeof(name); j++)
-                       name[j] = (char)CDF_TOLE2(d->d_name[j]);
-               (void)fprintf(stderr, "Directory %zu: %s\n", i, name);
-               if (d->d_type < __arraycount(types))
-                       (void)fprintf(stderr, "Type: %s\n", types[d->d_type]);
-               else
-                       (void)fprintf(stderr, "Type: %d\n", d->d_type);
-               (void)fprintf(stderr, "Color: %s\n",
-                   d->d_color ? "black" : "red");
-               (void)fprintf(stderr, "Left child: %d\n", d->d_left_child);
-               (void)fprintf(stderr, "Right child: %d\n", d->d_right_child);
-               (void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags);
-               cdf_timestamp_to_timespec(&ts, d->d_created);
-               (void)fprintf(stderr, "Created %s", ctime(&ts.tv_sec));
-               cdf_timestamp_to_timespec(&ts, d->d_modified);
-               (void)fprintf(stderr, "Modified %s", ctime(&ts.tv_sec));
-               (void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector);
-               (void)fprintf(stderr, "Size %d\n", d->d_size);
-               switch (d->d_type) {
-               case CDF_DIR_TYPE_USER_STORAGE:
-                       (void)fprintf(stderr, "Storage: %d\n", d->d_storage);
-                       break;
-               case CDF_DIR_TYPE_USER_STREAM:
-                       if (sst == NULL)
-                               break;
-                       if (cdf_read_sector_chain(info, h, sat, ssat, sst,
-                           d->d_stream_first_sector, d->d_size, &scn) == -1) {
-                               warn("Can't read stream for %s at %d len %d",
-                                   name, d->d_stream_first_sector, d->d_size);
-                               break;
-                       }
-                       cdf_dump_stream(h, &scn);
-                       free(scn.sst_tab);
-                       break;
-               default:
-                       break;
-               }
-                       
-       }
+        size_t i, j;
+        cdf_directory_t *d;
+        char name[__arraycount(d->d_name)];
+        cdf_stream_t scn;
+        struct timespec ts;
+
+        static const char *types[] = { "empty", "user storage",
+            "user stream", "lockbytes", "property", "root storage" };
+
+        for (i = 0; i < dir->dir_len; i++) {
+                d = &dir->dir_tab[i];
+                for (j = 0; j < sizeof(name); j++)
+                        name[j] = (char)CDF_TOLE2(d->d_name[j]);
+                (void)fprintf(stderr, "Directory %zu: %s\n", i, name);
+                if (d->d_type < __arraycount(types))
+                        (void)fprintf(stderr, "Type: %s\n", types[d->d_type]);
+                else
+                        (void)fprintf(stderr, "Type: %d\n", d->d_type);
+                (void)fprintf(stderr, "Color: %s\n",
+                    d->d_color ? "black" : "red");
+                (void)fprintf(stderr, "Left child: %d\n", d->d_left_child);
+                (void)fprintf(stderr, "Right child: %d\n", d->d_right_child);
+                (void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags);
+                cdf_timestamp_to_timespec(&ts, d->d_created);
+                (void)fprintf(stderr, "Created %s", ctime(&ts.tv_sec));
+                cdf_timestamp_to_timespec(&ts, d->d_modified);
+                (void)fprintf(stderr, "Modified %s", ctime(&ts.tv_sec));
+                (void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector);
+                (void)fprintf(stderr, "Size %d\n", d->d_size);
+                switch (d->d_type) {
+                case CDF_DIR_TYPE_USER_STORAGE:
+                        (void)fprintf(stderr, "Storage: %d\n", d->d_storage);
+                        break;
+                case CDF_DIR_TYPE_USER_STREAM:
+                        if (sst == NULL)
+                                break;
+                        if (cdf_read_sector_chain(info, h, sat, ssat, sst,
+                            d->d_stream_first_sector, d->d_size, &scn) == -1) {
+                                warn("Can't read stream for %s at %d len %d",
+                                    name, d->d_stream_first_sector, d->d_size);
+                                break;
+                        }
+                        cdf_dump_stream(h, &scn);
+                        free(scn.sst_tab);
+                        break;
+                default:
+                        break;
+                }
+
+        }
 }
 
 void
 cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
 {
-       cdf_timestamp_t tp;
-       struct timespec ts;
-       char buf[64];
-       size_t i, j;
-
-       for (i = 0; i < count; i++) {
-               cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
-               (void)fprintf(stderr, "%zu) %s: ", i, buf); 
-               switch (info[i].pi_type) {
-               case CDF_NULL:
-                       break;
-               case CDF_SIGNED16:
-                       (void)fprintf(stderr, "signed 16 [%hd]\n",
-                           info[i].pi_s16);
-                       break;
-               case CDF_SIGNED32:
-                       (void)fprintf(stderr, "signed 32 [%d]\n",
-                           info[i].pi_s32);
-                       break;
-               case CDF_UNSIGNED32:
-                       (void)fprintf(stderr, "unsigned 32 [%u]\n",
-                           info[i].pi_u32);
-                       break;
-               case CDF_LENGTH32_STRING:
-                       (void)fprintf(stderr, "string %u [%.*s]\n",
-                           info[i].pi_str.s_len,
-                           info[i].pi_str.s_len, info[i].pi_str.s_buf);
-                       break;
-               case CDF_LENGTH32_WSTRING:
-                       (void)fprintf(stderr, "string %u [", 
-                           info[i].pi_str.s_len);
-                       for (j = 0; j < info[i].pi_str.s_len - 1; j++)
-                           (void)fputc(info[i].pi_str.s_buf[j << 1], stderr);
-                       (void)fprintf(stderr, "]\n"); 
-                       break;
-               case CDF_FILETIME:
-                       tp = info[i].pi_tp;
-                       if (tp < 1000000000000000LL) {
-                               cdf_print_elapsed_time(buf, sizeof(buf), tp);
-                               (void)fprintf(stderr, "timestamp %s\n", buf);
-                       } else {
-                               cdf_timestamp_to_timespec(&ts, tp);
-                               (void)fprintf(stderr, "timestamp %s",
-                                   ctime(&ts.tv_sec));
-                       }
-                       break;
-               case CDF_CLIPBOARD:
-                       (void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32);
-                       break;
-               default:
-                       DPRINTF(("Don't know how to deal with %x\n",
-                           info[i].pi_type));
-                       break;
-               }
-       }
+        cdf_timestamp_t tp;
+        struct timespec ts;
+        char buf[64];
+        size_t i, j;
+
+        for (i = 0; i < count; i++) {
+                cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
+                (void)fprintf(stderr, "%zu) %s: ", i, buf);
+                switch (info[i].pi_type) {
+                case CDF_NULL:
+                        break;
+                case CDF_SIGNED16:
+                        (void)fprintf(stderr, "signed 16 [%hd]\n",
+                            info[i].pi_s16);
+                        break;
+                case CDF_SIGNED32:
+                        (void)fprintf(stderr, "signed 32 [%d]\n",
+                            info[i].pi_s32);
+                        break;
+                case CDF_UNSIGNED32:
+                        (void)fprintf(stderr, "unsigned 32 [%u]\n",
+                            info[i].pi_u32);
+                        break;
+                case CDF_LENGTH32_STRING:
+                        (void)fprintf(stderr, "string %u [%.*s]\n",
+                            info[i].pi_str.s_len,
+                            info[i].pi_str.s_len, info[i].pi_str.s_buf);
+                        break;
+                case CDF_LENGTH32_WSTRING:
+                        (void)fprintf(stderr, "string %u [",
+                            info[i].pi_str.s_len);
+                        for (j = 0; j < info[i].pi_str.s_len - 1; j++)
+                            (void)fputc(info[i].pi_str.s_buf[j << 1], stderr);
+                        (void)fprintf(stderr, "]\n");
+                        break;
+                case CDF_FILETIME:
+                        tp = info[i].pi_tp;
+                        if (tp < 1000000000000000LL) {
+                                cdf_print_elapsed_time(buf, sizeof(buf), tp);
+                                (void)fprintf(stderr, "timestamp %s\n", buf);
+                        } else {
+                                cdf_timestamp_to_timespec(&ts, tp);
+                                (void)fprintf(stderr, "timestamp %s",
+                                    ctime(&ts.tv_sec));
+                        }
+                        break;
+                case CDF_CLIPBOARD:
+                        (void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32);
+                        break;
+                default:
+                        DPRINTF(("Don't know how to deal with %x\n",
+                            info[i].pi_type));
+                        break;
+                }
+        }
 }
 
 
 void
 cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
 {
-       char buf[128];
-       cdf_summary_info_header_t ssi;
-       cdf_property_info_t *info;
-       size_t count;
-
-       (void)&h;
-       if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1)
-               return;
-       (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order);
-       (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
-               ssi.si_os_version >> 8);
-       (void)fprintf(stderr, "Os %d\n", ssi.si_os);
-       cdf_print_classid(buf, sizeof(buf), &ssi.si_class);
-       (void)fprintf(stderr, "Class %s\n", buf);
-       (void)fprintf(stderr, "Count %d\n", ssi.si_count);
-       cdf_dump_property_info(info, count);
-       free(info);
+        char buf[128];
+        cdf_summary_info_header_t ssi;
+        cdf_property_info_t *info;
+        size_t count;
+
+        (void)&h;
+        if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1)
+                return;
+        (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order);
+        (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
+                ssi.si_os_version >> 8);
+        (void)fprintf(stderr, "Os %d\n", ssi.si_os);
+        cdf_print_classid(buf, sizeof(buf), &ssi.si_class);
+        (void)fprintf(stderr, "Class %s\n", buf);
+        (void)fprintf(stderr, "Count %d\n", ssi.si_count);
+        cdf_dump_property_info(info, count);
+        free(info);
 }
 
 #endif
@@ -1200,66 +1203,66 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
 int
 main(int argc, char *argv[])
 {
-       int i;
-       cdf_header_t h;
-       cdf_sat_t sat, ssat;
-       cdf_stream_t sst, scn;
-       cdf_dir_t dir;
-       cdf_info_t info;
-
-       if (argc < 2) {
-               (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
-               return -1;
-       }
-
-       info.i_buf = NULL;
-       info.i_len = 0;
-       for (i = 1; i < argc; i++) {
-               if ((info.i_fd = open(argv[1], O_RDONLY)) == -1)
-                       err(1, "Cannot open `%s'", argv[1]);
-
-               if (cdf_read_header(&info, &h) == -1)
-                       err(1, "Cannot read header");
+        int i;
+        cdf_header_t h;
+        cdf_sat_t sat, ssat;
+        cdf_stream_t sst, scn;
+        cdf_dir_t dir;
+        cdf_info_t info;
+
+        if (argc < 2) {
+                (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
+                return -1;
+        }
+
+        info.i_buf = NULL;
+        info.i_len = 0;
+        for (i = 1; i < argc; i++) {
+                if ((info.i_fd = open(argv[1], O_RDONLY)) == -1)
+                        err(1, "Cannot open `%s'", argv[1]);
+
+                if (cdf_read_header(&info, &h) == -1)
+                        err(1, "Cannot read header");
 #ifdef CDF_DEBUG
-               cdf_dump_header(&h);
+                cdf_dump_header(&h);
 #endif
 
-               if (cdf_read_sat(&info, &h, &sat) == -1)
-                       err(1, "Cannot read sat");
+                if (cdf_read_sat(&info, &h, &sat) == -1)
+                        err(1, "Cannot read sat");
 #ifdef CDF_DEBUG
-               cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
+                cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
 #endif
 
-               if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1)
-                       err(1, "Cannot read ssat");
+                if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1)
+                        err(1, "Cannot read ssat");
 #ifdef CDF_DEBUG
-               cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
+                cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
 #endif
 
-               if (cdf_read_dir(&info, &h, &sat, &dir) == -1)
-                       err(1, "Cannot read dir");
+                if (cdf_read_dir(&info, &h, &sat, &dir) == -1)
+                        err(1, "Cannot read dir");
 
-               if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1)
-                       err(1, "Cannot read short stream");
+                if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1)
+                        err(1, "Cannot read short stream");
 #ifdef CDF_DEBUG
-               cdf_dump_stream(&h, &sst);
+                cdf_dump_stream(&h, &sst);
 #endif
 
 #ifdef CDF_DEBUG
-               cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
+                cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
 #endif
 
 
-               if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
-                   &scn) == -1)
-                       err(1, "Cannot read summary info");
+                if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
+                    &scn) == -1)
+                        err(1, "Cannot read summary info");
 #ifdef CDF_DEBUG
-               cdf_dump_summary_info(&h, &scn);
+                cdf_dump_summary_info(&h, &scn);
 #endif
 
-               (void)close(info.i_fd);
-       }
+                (void)close(info.i_fd);
+        }
 
-       return 0;
+        return 0;
 }
 #endif
index 6fa3fc6939175787326ed9e1b53a922685f5f8c7..16314e97cc9f3f9deec7d4a0b9e6abe8b4783a5f 100644 (file)
--- a/src/cdf.h
+++ b/src/cdf.h
  * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
- * Info from: http://sc.openoffice.org/compdocfileformat.pdf 
+ * Parse Composite Document Files, the format used in Microsoft Office
+ * document files before they switched to zipped XML.
+ * Info from: http://sc.openoffice.org/compdocfileformat.pdf
+ *
+ * N.B. This is the "Composite Document File" format, and not the
+ * "Compound Document Format", nor the "Channel Definition Format".
  */
 
 #ifndef _H_CDF_
@@ -41,24 +46,24 @@ typedef int32_t cdf_secid_t;
 #define CDF_SECID_MASTER_SECTOR_ALLOCATION_TABLE       -4
 
 typedef struct {
-       uint64_t        h_magic;
+        uint64_t       h_magic;
 #define CDF_MAGIC      0xE11AB1A1E011CFD0LL
-       uint64_t        h_uuid[2];
-       uint16_t        h_revision;
-       uint16_t        h_version;
-       uint16_t        h_byte_order;
-       uint16_t        h_sec_size_p2;
-       uint16_t        h_short_sec_size_p2;
-       uint8_t         h_unused0[10];
-       uint32_t        h_num_sectors_in_sat;
-       uint32_t        h_secid_first_directory;
-       uint8_t         h_unused1[4];
-       uint32_t        h_min_size_standard_stream;
-       cdf_secid_t     h_secid_first_sector_in_short_sat;
-       uint32_t        h_num_sectors_in_short_sat;
-       cdf_secid_t     h_secid_first_sector_in_master_sat;
-       uint32_t        h_num_sectors_in_master_sat;
-       cdf_secid_t     h_master_sat[436/4];
+        uint64_t       h_uuid[2];
+        uint16_t       h_revision;
+        uint16_t       h_version;
+        uint16_t       h_byte_order;
+        uint16_t       h_sec_size_p2;
+        uint16_t       h_short_sec_size_p2;
+        uint8_t                h_unused0[10];
+        uint32_t       h_num_sectors_in_sat;
+        uint32_t       h_secid_first_directory;
+        uint8_t                h_unused1[4];
+        uint32_t       h_min_size_standard_stream;
+        cdf_secid_t    h_secid_first_sector_in_short_sat;
+        uint32_t       h_num_sectors_in_short_sat;
+        cdf_secid_t    h_secid_first_sector_in_master_sat;
+        uint32_t       h_num_sectors_in_master_sat;
+        cdf_secid_t    h_master_sat[436/4];
 } cdf_header_t;
 
 #define CDF_SEC_SIZE(h)        (1 << (h)->h_sec_size_p2)
@@ -74,92 +79,92 @@ typedef int64_t     cdf_timestamp_t;
 #define CDF_TIME_PREC  10000000
 
 typedef struct {
-       uint16_t        d_name[32];
-       uint16_t        d_namelen;
-       uint8_t         d_type;
+        uint16_t       d_name[32];
+        uint16_t       d_namelen;
+        uint8_t                d_type;
 #define CDF_DIR_TYPE_EMPTY             0
 #define        CDF_DIR_TYPE_USER_STORAGE       1
 #define        CDF_DIR_TYPE_USER_STREAM        2
 #define        CDF_DIR_TYPE_LOCKBYTES          3
 #define        CDF_DIR_TYPE_PROPERTY           4
 #define        CDF_DIR_TYPE_ROOT_STORAGE       5
-       uint8_t         d_color;
+        uint8_t                d_color;
 #define CDF_DIR_COLOR_READ     0
 #define CDF_DIR_COLOR_BLACK    1
-       cdf_dirid_t     d_left_child;
-       cdf_dirid_t     d_right_child;
-       cdf_dirid_t     d_storage;
-       uint64_t        d_storage_uuid[2];
-       uint32_t        d_flags;
-       cdf_timestamp_t d_created;
-       cdf_timestamp_t d_modified;
-       cdf_secid_t     d_stream_first_sector;
-       uint32_t        d_size;
-       uint32_t        d_unused0;
+        cdf_dirid_t    d_left_child;
+        cdf_dirid_t    d_right_child;
+        cdf_dirid_t    d_storage;
+        uint64_t       d_storage_uuid[2];
+        uint32_t       d_flags;
+        cdf_timestamp_t        d_created;
+        cdf_timestamp_t        d_modified;
+        cdf_secid_t    d_stream_first_sector;
+        uint32_t       d_size;
+        uint32_t       d_unused0;
 } cdf_directory_t;
 
 #define CDF_DIRECTORY_SIZE     128
 
 typedef struct {
-       cdf_secid_t *sat_tab;
-       size_t sat_len;
+        cdf_secid_t *sat_tab;
+        size_t sat_len;
 } cdf_sat_t;
 
 typedef struct {
-       cdf_directory_t *dir_tab;
-       size_t dir_len;
+        cdf_directory_t *dir_tab;
+        size_t dir_len;
 } cdf_dir_t;
 
 typedef struct {
-       void *sst_tab;
-       size_t sst_len;
-       size_t sst_dirlen;
+        void *sst_tab;
+        size_t sst_len;
+        size_t sst_dirlen;
 } cdf_stream_t;
 
 typedef struct {
-       uint32_t        cl_dword;
-       uint16_t        cl_word[2];
-       uint8_t         cl_two[2];
-       uint8_t         cl_six[6];
+        uint32_t       cl_dword;
+        uint16_t       cl_word[2];
+        uint8_t                cl_two[2];
+        uint8_t                cl_six[6];
 } cdf_classid_t;
 
 typedef struct {
-       uint16_t        si_byte_order;
-       uint16_t        si_zero;
-       uint16_t        si_os_version;
-       uint16_t        si_os;
-       cdf_classid_t   si_class;
-       uint32_t        si_count;
+        uint16_t       si_byte_order;
+        uint16_t       si_zero;
+        uint16_t       si_os_version;
+        uint16_t       si_os;
+        cdf_classid_t  si_class;
+        uint32_t       si_count;
 } cdf_summary_info_header_t;
 
 #define CDF_SECTION_DECLARATION_OFFSET 0x1c
 
 typedef struct {
-       cdf_classid_t   sd_class;
-       uint32_t        sd_offset;
+        cdf_classid_t  sd_class;
+        uint32_t       sd_offset;
 } cdf_section_declaration_t;
 
 typedef struct {
-       uint32_t        sh_len;
-       uint32_t        sh_properties;
+        uint32_t       sh_len;
+        uint32_t       sh_properties;
 } cdf_section_header_t;
 
 typedef struct {
-       uint32_t        pi_id;
-       uint32_t        pi_type;
-       union {
-               uint16_t        _pi_u16;
-               int16_t         _pi_s16;
-               uint32_t        _pi_u32;
-               int32_t         _pi_s32;
-               uint64_t        _pi_u64;
-               int64_t         _pi_s64;
-               cdf_timestamp_t _pi_tp;
-               struct {
-                       uint32_t s_len;
-                       const char *s_buf;
-               } _pi_str;
-       } pi_val;
+        uint32_t       pi_id;
+        uint32_t       pi_type;
+        union {
+                uint16_t       _pi_u16;
+                int16_t                _pi_s16;
+                uint32_t       _pi_u32;
+                int32_t                _pi_s32;
+                uint64_t       _pi_u64;
+                int64_t                _pi_s64;
+                cdf_timestamp_t        _pi_tp;
+                struct {
+                        uint32_t s_len;
+                        const char *s_buf;
+                } _pi_str;
+        } pi_val;
 #define pi_u64 pi_val._pi_u64
 #define pi_s64 pi_val._pi_s64
 #define pi_u32 pi_val._pi_u32
@@ -226,7 +231,7 @@ typedef struct {
 #define CDF_PROPERTY_SUBJECT                   0x00000003
 #define CDF_PROPERTY_AUTHOR                    0x00000004
 #define CDF_PROPERTY_KEYWORDS                  0x00000005
-#define CDF_PROPERTY_COMMENTS                  0x00000006
+#define CDF_PROPERTY_COMMENTS                   0x00000006
 #define CDF_PROPERTY_TEMPLATE                  0x00000007
 #define CDF_PROPERTY_LAST_SAVED_BY             0x00000008
 #define CDF_PROPERTY_REVISION_NUMBER           0x00000009
@@ -243,9 +248,9 @@ typedef struct {
 #define CDF_PROPERTY_LOCALE_ID                 0x80000000
 
 typedef struct {
-       int i_fd;
-       const unsigned char *i_buf;
-       size_t i_len;
+        int i_fd;
+        const unsigned char *i_buf;
+        size_t i_len;
 } cdf_info_t;
 
 struct timespec;
index 312d7c3239794f2a29220cc85a09709e3f7e8707..67b47d0e010ce792fe2f0add6be686a2d250ddff 100644 (file)
@@ -26,7 +26,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.21 2009/09/13 23:23:31 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.22 2010/01/20 01:36:55 christos Exp $")
 #endif
 
 #include <stdlib.h>
@@ -44,241 +44,241 @@ private int
 cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
     size_t count)
 {
-       size_t i;
-       cdf_timestamp_t tp;
-       struct timespec ts;
-       char buf[64];
-       const char *str = "vnd.ms-office";
-       const char *s;
-       int len;
+        size_t i;
+        cdf_timestamp_t tp;
+        struct timespec ts;
+        char buf[64];
+        const char *str = "vnd.ms-office";
+        const char *s;
+        int len;
 
-       for (i = 0; i < count; i++) {
-               cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
-               switch (info[i].pi_type) {
-               case CDF_NULL:
-                       break;
-               case CDF_SIGNED16:
-                       if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
-                           info[i].pi_s16) == -1)
-                               return -1;
-                       break;
-               case CDF_SIGNED32:
-                       if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
-                           info[i].pi_s32) == -1)
-                               return -1;
-                       break;
-               case CDF_UNSIGNED32:
-                       if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
-                           info[i].pi_u32) == -1)
-                               return -1;
-                       break;
-               case CDF_LENGTH32_STRING:
-               case CDF_LENGTH32_WSTRING:
-                       len = info[i].pi_str.s_len;
-                       if (len > 1) {
-                               char vbuf[1024];
-                               size_t j, k = 1;
+        for (i = 0; i < count; i++) {
+                cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
+                switch (info[i].pi_type) {
+                case CDF_NULL:
+                        break;
+                case CDF_SIGNED16:
+                        if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
+                            info[i].pi_s16) == -1)
+                                return -1;
+                        break;
+                case CDF_SIGNED32:
+                        if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
+                            info[i].pi_s32) == -1)
+                                return -1;
+                        break;
+                case CDF_UNSIGNED32:
+                        if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
+                            info[i].pi_u32) == -1)
+                                return -1;
+                        break;
+                case CDF_LENGTH32_STRING:
+                case CDF_LENGTH32_WSTRING:
+                        len = info[i].pi_str.s_len;
+                        if (len > 1) {
+                                char vbuf[1024];
+                                size_t j, k = 1;
 
-                               if (info[i].pi_type == CDF_LENGTH32_WSTRING)
-                                   k++;
-                               s = info[i].pi_str.s_buf;
-                               for (j = 0; j < sizeof(vbuf) && len--;
-                                   j++, s += k) {
-                                       if (*s == '\0')
-                                               break;
-                                       if (isprint((unsigned char)*s))
-                                               vbuf[j] = *s;
-                               }
-                               if (j == sizeof(vbuf))
-                                       --j;
-                               vbuf[j] = '\0';
-                               if (NOTMIME(ms)) {
-                                       if (vbuf[0]) {
-                                               if (file_printf(ms, ", %s: %s",
-                                                   buf, vbuf) == -1)
-                                                       return -1;
-                                       }
-                               } else if (info[i].pi_id == 
-                                       CDF_PROPERTY_NAME_OF_APPLICATION) {
-                                       if (strstr(vbuf, "Word"))
-                                               str = "msword";
-                                       else if (strstr(vbuf, "Excel"))
-                                               str = "vnd.ms-excel";
-                                       else if (strstr(vbuf, "Powerpoint"))
-                                               str = "vnd.ms-powerpoint";
-                                       else if (strstr(vbuf,
-                                           "Crystal Reports"))
-                                               str = "x-rpt";
-                               }
-                       }
-                       break;
-               case CDF_FILETIME:
-                       tp = info[i].pi_tp;
-                       if (tp != 0) {
-                               if (tp < 1000000000000000LL) {
-                                       char tbuf[64];
-                                       cdf_print_elapsed_time(tbuf,
-                                           sizeof(tbuf), tp);
-                                       if (NOTMIME(ms) && file_printf(ms,
-                                           ", %s: %s", buf, tbuf) == -1)
-                                               return -1;
-                               } else {
-                                       char *c, *ec;
-                                       cdf_timestamp_to_timespec(&ts, tp);
-                                       c = ctime(&ts.tv_sec);
-                                       if ((ec = strchr(c, '\n')) != NULL)
-                                               *ec = '\0';
+                                if (info[i].pi_type == CDF_LENGTH32_WSTRING)
+                                    k++;
+                                s = info[i].pi_str.s_buf;
+                                for (j = 0; j < sizeof(vbuf) && len--;
+                                    j++, s += k) {
+                                        if (*s == '\0')
+                                                break;
+                                        if (isprint((unsigned char)*s))
+                                                vbuf[j] = *s;
+                                }
+                                if (j == sizeof(vbuf))
+                                        --j;
+                                vbuf[j] = '\0';
+                                if (NOTMIME(ms)) {
+                                        if (vbuf[0]) {
+                                                if (file_printf(ms, ", %s: %s",
+                                                    buf, vbuf) == -1)
+                                                        return -1;
+                                        }
+                                } else if (info[i].pi_id ==
+                                        CDF_PROPERTY_NAME_OF_APPLICATION) {
+                                        if (strstr(vbuf, "Word"))
+                                                str = "msword";
+                                        else if (strstr(vbuf, "Excel"))
+                                                str = "vnd.ms-excel";
+                                        else if (strstr(vbuf, "Powerpoint"))
+                                                str = "vnd.ms-powerpoint";
+                                        else if (strstr(vbuf,
+                                            "Crystal Reports"))
+                                                str = "x-rpt";
+                                }
+                        }
+                        break;
+                case CDF_FILETIME:
+                        tp = info[i].pi_tp;
+                        if (tp != 0) {
+                                if (tp < 1000000000000000LL) {
+                                        char tbuf[64];
+                                        cdf_print_elapsed_time(tbuf,
+                                            sizeof(tbuf), tp);
+                                        if (NOTMIME(ms) && file_printf(ms,
+                                            ", %s: %s", buf, tbuf) == -1)
+                                                return -1;
+                                } else {
+                                        char *c, *ec;
+                                        cdf_timestamp_to_timespec(&ts, tp);
+                                        c = ctime(&ts.tv_sec);
+                                        if ((ec = strchr(c, '\n')) != NULL)
+                                                *ec = '\0';
 
-                                       if (NOTMIME(ms) && file_printf(ms,
-                                           ", %s: %s", buf, c) == -1)
-                                               return -1;
-                               }
-                       }
-                       break;
-               case CDF_CLIPBOARD:
-                       break;
-               default:
-                       return -1;
-               }
-       }
-       if (!NOTMIME(ms)) {
-               if (file_printf(ms, "application/%s", str) == -1)
-                       return -1;
-       }
-       return 1;
+                                        if (NOTMIME(ms) && file_printf(ms,
+                                            ", %s: %s", buf, c) == -1)
+                                                return -1;
+                                }
+                        }
+                        break;
+                case CDF_CLIPBOARD:
+                        break;
+                default:
+                        return -1;
+                }
+        }
+        if (!NOTMIME(ms)) {
+                if (file_printf(ms, "application/%s", str) == -1)
+                        return -1;
+        }
+        return 1;
 }
 
 private int
 cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst)
 {
-       cdf_summary_info_header_t si;
-       cdf_property_info_t *info;
-       size_t count;
-       int m;
+        cdf_summary_info_header_t si;
+        cdf_property_info_t *info;
+        size_t count;
+        int m;
 
-       if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1)
-               return -1;
+        if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1)
+                return -1;
 
-       if (NOTMIME(ms)) {
-               if (file_printf(ms, "CDF V2 Document") == -1)
-                       return -1;
+        if (NOTMIME(ms)) {
+                if (file_printf(ms, "Composite Document File V2 Document") == -1)
+                        return -1;
 
-               if (file_printf(ms, ", %s Endian",
-                   si.si_byte_order == 0xfffe ?  "Little" : "Big") == -1)
-                       return -1;
-               switch (si.si_os) {
-               case 2:
-                       if (file_printf(ms, ", Os: Windows, Version %d.%d",
-                           si.si_os_version & 0xff,
-                           (uint32_t)si.si_os_version >> 8) == -1)
-                               return -1;
-                       break;
-               case 1:
-                       if (file_printf(ms, ", Os: MacOS, Version %d.%d",
-                           (uint32_t)si.si_os_version >> 8,
-                           si.si_os_version & 0xff) == -1)
-                               return -1;
-                       break;
-               default:
-                       if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
-                           si.si_os_version & 0xff,
-                           (uint32_t)si.si_os_version >> 8) == -1)
-                               return -1;
-                       break;
-               }
-       }
+                if (file_printf(ms, ", %s Endian",
+                    si.si_byte_order == 0xfffe ?  "Little" : "Big") == -1)
+                        return -1;
+                switch (si.si_os) {
+                case 2:
+                        if (file_printf(ms, ", Os: Windows, Version %d.%d",
+                            si.si_os_version & 0xff,
+                            (uint32_t)si.si_os_version >> 8) == -1)
+                                return -1;
+                        break;
+                case 1:
+                        if (file_printf(ms, ", Os: MacOS, Version %d.%d",
+                            (uint32_t)si.si_os_version >> 8,
+                            si.si_os_version & 0xff) == -1)
+                                return -1;
+                        break;
+                default:
+                        if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
+                            si.si_os_version & 0xff,
+                            (uint32_t)si.si_os_version >> 8) == -1)
+                                return -1;
+                        break;
+                }
+        }
 
-       m = cdf_file_property_info(ms, info, count);
-       free(info);
+        m = cdf_file_property_info(ms, info, count);
+        free(info);
 
-       return m;
+        return m;
 }
 
 protected int
 file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
     size_t nbytes)
 {
-       cdf_info_t info;
-       cdf_header_t h;
-       cdf_sat_t sat, ssat;
-       cdf_stream_t sst, scn;
-       cdf_dir_t dir;
-       int i;
-       const char *expn = "";
-       const char *corrupt = "corrupt: ";
+        cdf_info_t info;
+        cdf_header_t h;
+        cdf_sat_t sat, ssat;
+        cdf_stream_t sst, scn;
+        cdf_dir_t dir;
+        int i;
+        const char *expn = "";
+        const char *corrupt = "corrupt: ";
 
-       info.i_fd = fd;
-       info.i_buf = buf;
-       info.i_len = nbytes;
-       if (ms->flags & MAGIC_APPLE)
-               return 0;
-       if (cdf_read_header(&info, &h) == -1)
-               return 0;
+        info.i_fd = fd;
+        info.i_buf = buf;
+        info.i_len = nbytes;
+        if (ms->flags & MAGIC_APPLE)
+                return 0;
+        if (cdf_read_header(&info, &h) == -1)
+                return 0;
 #ifdef CDF_DEBUG
-       cdf_dump_header(&h);
+        cdf_dump_header(&h);
 #endif
 
-       if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
-               expn = "Can't read SAT";
-               goto out0;
-       }
+        if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
+                expn = "Can't read SAT";
+                goto out0;
+        }
 #ifdef CDF_DEBUG
-       cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
+        cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
 #endif
 
-       if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
-               expn = "Can't read SSAT";
-               goto out1;
-       }
+        if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
+                expn = "Can't read SSAT";
+                goto out1;
+        }
 #ifdef CDF_DEBUG
-       cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
+        cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
 #endif
 
-       if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
-               expn = "Can't read directory";
-               goto out2;
-       }
+        if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
+                expn = "Can't read directory";
+                goto out2;
+        }
 
-       if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
-               expn = "Cannot read short stream";
-               goto out3;
-       }
+        if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
+                expn = "Cannot read short stream";
+                goto out3;
+        }
 #ifdef CDF_DEBUG
-       cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
+        cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
 #endif
 
-       if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
-           &scn)) == -1) {
-               if (errno == ESRCH) {
-                       corrupt = expn;
-                       expn = "No summary info";
-               } else {
-                       expn = "Cannot read summary info";
-               }
-               goto out4;
-       }
+        if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
+            &scn)) == -1) {
+                if (errno == ESRCH) {
+                        corrupt = expn;
+                        expn = "No summary info";
+                } else {
+                        expn = "Cannot read summary info";
+                }
+                goto out4;
+        }
 #ifdef CDF_DEBUG
-       cdf_dump_summary_info(&h, &scn);
+        cdf_dump_summary_info(&h, &scn);
 #endif
-       if ((i = cdf_file_summary_info(ms, &scn)) == -1)
-               expn = "Can't expand summary_info";
-       free(scn.sst_tab);
+        if ((i = cdf_file_summary_info(ms, &scn)) == -1)
+                expn = "Can't expand summary_info";
+        free(scn.sst_tab);
 out4:
-       free(sst.sst_tab);
+        free(sst.sst_tab);
 out3:
-       free(dir.dir_tab);
+        free(dir.dir_tab);
 out2:
-       free(ssat.sat_tab);
+        free(ssat.sat_tab);
 out1:
-       free(sat.sat_tab);
+        free(sat.sat_tab);
 out0:
-       if (i != 1) {
-               if (file_printf(ms, "CDF V2 Document") == -1)
-                       return -1;
-               if (*expn)
-                       if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
-                               return -1;
-               i = 1;
-       }
-       return i;
+        if (i != 1) {
+                if (file_printf(ms, "Composite Document File V2 Document") == -1)
+                        return -1;
+                if (*expn)
+                        if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
+                                return -1;
+                i = 1;
+        }
+        return i;
 }