]> granicus.if.org Git - file/commitdiff
try to read more types [does not work yet]
authorChristos Zoulas <christos@zoulas.com>
Thu, 16 Oct 2008 16:29:56 +0000 (16:29 +0000)
committerChristos Zoulas <christos@zoulas.com>
Thu, 16 Oct 2008 16:29:56 +0000 (16:29 +0000)
src/cdf.c
src/cdf.h

index 0b53e315e090252d607bfa44f591094e507e640c..5620e7897b0b1caa423b29dc89193f56453734db 100644 (file)
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -542,12 +542,14 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
        int32_t s32;
        uint32_t u32;
        cdf_timestamp_t tp;
-       size_t i, len;
+       size_t i, len, o, nelements, j;
        cdf_property_info_t *inp;
 
        shp = (const void *)((const char *)sst->sst_tab + offs);
        sh.sh_len = CDF_TOLE4(shp->sh_len);
        sh.sh_properties = CDF_TOLE4(shp->sh_properties);
+       DPRINTF(("section len: %d properties %d\n", sh.sh_len,
+           sh.sh_properties));
        if (*maxcount) {
                *maxcount += sh.sh_properties;
                inp = realloc(*info, *maxcount * sizeof(*inp));
@@ -565,45 +567,84 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
        e = (const void *)(((const char *)shp) + sh.sh_len);
        for (i = 0; i < sh.sh_properties; i++) {
                inp[i].pi_id = CDF_TOLE4(p[i << 1]);
-               switch (inp[i].pi_type = CDF_TOLE4(q[0])) {
+               inp[i].pi_type = CDF_TOLE4(q[0]);
+               DPRINTF(("%d) id=%x type=%x\n", i, inp[i].pi_id,
+                   inp[i].pi_type));
+               if (inp[i].pi_type & CDF_VECTOR) {
+                       nelements = CDF_TOLE4(q[1]);
+                       o = 2;
+                       len = 12;
+               } else {
+                       nelements = 1;
+                       o = 1;
+                       len = 4;
+               }
+               if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED))
+                       goto out;
+               switch (inp[i].pi_type & CDF_TYPEMASK) {
                case CDF_SIGNED16:
-                       (void)memcpy(&s16, &q[1], sizeof(s16));
+                       if (inp[i].pi_type & CDF_VECTOR)
+                               goto out;
+                       (void)memcpy(&s16, &q[o], sizeof(s16));
                        inp[i].pi_s16 = CDF_TOLE2(s16);
-                       len = 2;
+                       len += 4;
                        break;
                case CDF_SIGNED32:
-                       (void)memcpy(&s32, &q[1], sizeof(s32));
+                       if (inp[i].pi_type & CDF_VECTOR)
+                               goto out;
+                       (void)memcpy(&s32, &q[o], sizeof(s32));
                        inp[i].pi_s32 = CDF_TOLE4(s32);
-                       len = 4;
+                       len += 4;
                        break;
+               case CDF_BOOL:
                case CDF_UNSIGNED32:
-                       (void)memcpy(&u32, &q[1], sizeof(u32));
+                       if (inp[i].pi_type & CDF_VECTOR)
+                               goto out;
+                       (void)memcpy(&u32, &q[o], sizeof(u32));
                        inp[i].pi_u32 = CDF_TOLE4(u32);
-                       len = 4;
+                       len += 4;
                        break;
                case CDF_LENGTH32_STRING:
-                       inp[i].pi_str.s_len = CDF_TOLE4(q[1]);
-                       inp[i].pi_str.s_buf = (const char *)(&q[2]);
-                       len = 4 + CDF_TOLE4(q[1]);
+                       if (nelements > 1) {
+                               *maxcount += nelements;
+                               inp = realloc(*info, *maxcount * sizeof(*inp));
+                               if (inp == NULL)
+                                       return -1;
+                       }
+                       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 *)(&q[o+1]);
+                               DPRINTF(("l = %d, s = %s\n", l,
+                                   inp[i].pi_str.s_buf));
+                               l = 4 + CDF_ROUND(l, sizeof(l));
+                               o += l >> 2;
+                               len += l;
+                       }
+                       i--;
                        break;
                case CDF_FILETIME:
-                       (void)memcpy(&tp, &q[1], sizeof(tp));
+                       if (inp[i].pi_type & CDF_VECTOR)
+                               goto out;
+                       (void)memcpy(&tp, &q[o], sizeof(tp));
                        inp[i].pi_tp = CDF_TOLE8(tp);
-                       len = 8;
+                       len += 8;
                        break;
                case CDF_CLIPBOARD:
-                       len = 4 + CDF_TOLE4(q[1]);
+                       if (inp[i].pi_type & CDF_VECTOR)
+                               goto out;
+                       len += 4 + CDF_ROUND(CDF_TOLE4(q[o]), 4);
                        break;
                default:
-                       len = 4;
+               out:
+                       len += 4;
                        DPRINTF(("Don't know how to deal with %x\n",
-                           CDF_TOLE4(q[0])));
+                           inp[i].pi_type));
                        free(*info);
                        return -1;
                }
-               q++;
-               q = (const void *)(((const char *)q) +
-                   CDF_ROUND(len, sizeof(*q)));
+               q = (const void *)(((const char *)q) + len);
                if (q > e) {
                        DPRINTF(("Ran of the end %p > %p\n", q, e));
                        free(*info);
@@ -960,16 +1001,17 @@ main(int argc, char *argv[])
                if (cdf_read_dir(fd, &h, &sat, &dir) == -1)
                        err(1, "Cannot read dir");
 
-#ifdef CDF_DEBUG
-               cdf_dump_dir(fd, &h, &sat, NULL, NULL, &dir);
-#endif
-
                if (cdf_read_short_stream(fd, &h, &sat, &dir, &sst) == -1)
                        err(1, "Cannot read short stream");
 #ifdef CDF_DEBUG
                cdf_dump_stream(&h, &sst);
 #endif
 
+#ifdef CDF_DEBUG
+               cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir);
+#endif
+
+
                if (cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir,
                    &scn) == -1)
                        err(1, "Cannot read summary info");
index 8c42d2ec724ef158c401578b57d72b986fcbcf51..15e37d4d792d8fa02c428710c013e045034e7227 100644 (file)
--- a/src/cdf.h
+++ b/src/cdf.h
@@ -166,12 +166,54 @@ typedef struct {
 
 #define CDF_ROUND(val, by)     (((val) + (by) - 1) & ~((by) - 1))
 
+/* Variant type definitions */
+#define CDF_EMPTY              0x00000000
+#define        CDF_NULL                0x00000001
 #define CDF_SIGNED16           0x00000002
 #define CDF_SIGNED32           0x00000003
+#define CDF_FLOAT              0x00000004
+#define CDF_DOUBLE             0x00000005
+#define CDF_CY                 0x00000006
+#define        CDF_DATE                0x00000007
+#define CDF_BSTR               0x00000008
+#define CDF_DISPATCH           0x00000009
+#define CDF_ERROR              0x0000000a
+#define CDF_BOOL               0x0000000b
+#define CDF_VARIANT            0x0000000c
+#define CDF_UNKNOWN            0x0000000d
+#define CDF_DECIMAL            0x0000000e
+#define CDF_SIGNED8            0x00000010
+#define CDF_UNSIGNED8          0x00000011
+#define CDF_UNSIGNED16         0x00000012
 #define        CDF_UNSIGNED32          0x00000013
+#define CDF_SIGNED64           0x00000014
+#define CDF_UNSIGNED64         0x00000015
+#define CDF_INT                        0x00000016
+#define CDF_UINT               0x00000017
+#define CDF_VOID               0x00000018
+#define CDF_HRESULT            0x00000019
+#define CDF_PTR                        0x0000001a
+#define CDF_SAFEARRAY          0x0000001b
+#define CDF_CARRAY             0x0000001c
+#define CDF_USERDEFINED                0x0000001d
 #define CDF_LENGTH32_STRING    0x0000001e
+#define CDF_LENGTH32_WSTRING   0x0000001f
 #define CDF_FILETIME           0x00000040
+#define CDF_BLOB               0x00000041
+#define CDF_STREAM             0x00000042
+#define CDF_STORAGE            0x00000043
+#define CDF_STREAMED_OBJECT    0x00000044
+#define CDF_STORED_OBJECT      0x00000045
+#define CDF_BLOB_OBJECT                0x00000046
 #define CDF_CLIPBOARD          0x00000047
+#define CDF_CLSID              0x00000048
+#define CDF_VECTOR             0x00001000
+#define CDF_ARRAY              0x00002000
+#define CDF_BYREF              0x00004000
+#define CDF_RESERVED           0x00008000
+#define CDF_ILLEGAL            0x0000ffff
+#define CDF_ILLEGALMASKED      0x00000fff
+#define CDF_TYPEMASK           0x00000fff
 
 #define CDF_PROPERTY_CODE_PAGE                 0x00000001
 #define CDF_PROPERTY_TITLE                     0x00000002