Annotation of embedaddon/php/ext/fileinfo/libmagic/readcdf.c, revision 1.1.1.2
1.1 misho 1: /*-
2: * Copyright (c) 2008 Christos Zoulas
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
15: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
18: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24: * POSSIBILITY OF SUCH DAMAGE.
25: */
26: #include "file.h"
27:
28: #ifndef lint
1.1.1.2 ! misho 29: FILE_RCSID("@(#)$File: readcdf.c,v 1.29 2012/02/20 20:04:58 christos Exp $")
1.1 misho 30: #endif
31:
32: #include <stdlib.h>
33: #ifdef PHP_WIN32
34: #include "win32/unistd.h"
35: #else
36: #include <unistd.h>
37: #endif
38: #include <string.h>
39: #include <time.h>
40: #include <ctype.h>
41:
42: #include "cdf.h"
43: #include "magic.h"
44:
45: #define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0)
46:
47: private int
48: cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
49: size_t count)
50: {
1.1.1.2 ! misho 51: size_t i;
! 52: cdf_timestamp_t tp;
! 53: struct timeval ts;
! 54: char buf[64];
! 55: const char *str = NULL;
! 56: const char *s;
! 57: int len;
! 58:
! 59: for (i = 0; i < count; i++) {
! 60: cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
! 61: switch (info[i].pi_type) {
! 62: case CDF_NULL:
! 63: break;
! 64: case CDF_SIGNED16:
! 65: if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
! 66: info[i].pi_s16) == -1)
! 67: return -1;
! 68: break;
! 69: case CDF_SIGNED32:
! 70: if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
! 71: info[i].pi_s32) == -1)
! 72: return -1;
! 73: break;
! 74: case CDF_UNSIGNED32:
! 75: if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
! 76: info[i].pi_u32) == -1)
! 77: return -1;
! 78: break;
! 79: case CDF_FLOAT:
! 80: if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
! 81: info[i].pi_f) == -1)
! 82: return -1;
! 83: break;
! 84: case CDF_DOUBLE:
! 85: if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
! 86: info[i].pi_d) == -1)
! 87: return -1;
! 88: break;
! 89: case CDF_LENGTH32_STRING:
! 90: case CDF_LENGTH32_WSTRING:
! 91: len = info[i].pi_str.s_len;
! 92: if (len > 1) {
! 93: char vbuf[1024];
! 94: size_t j, k = 1;
! 95:
! 96: if (info[i].pi_type == CDF_LENGTH32_WSTRING)
! 97: k++;
! 98: s = info[i].pi_str.s_buf;
! 99: for (j = 0; j < sizeof(vbuf) && len--;
! 100: j++, s += k) {
! 101: if (*s == '\0')
! 102: break;
! 103: if (isprint((unsigned char)*s))
! 104: vbuf[j] = *s;
! 105: }
! 106: if (j == sizeof(vbuf))
! 107: --j;
! 108: vbuf[j] = '\0';
! 109: if (NOTMIME(ms)) {
! 110: if (vbuf[0]) {
! 111: if (file_printf(ms, ", %s: %s",
! 112: buf, vbuf) == -1)
! 113: return -1;
! 114: }
! 115: } else if (info[i].pi_id ==
! 116: CDF_PROPERTY_NAME_OF_APPLICATION) {
! 117: if (strstr(vbuf, "Word"))
! 118: str = "msword";
! 119: else if (strstr(vbuf, "Excel"))
! 120: str = "vnd.ms-excel";
! 121: else if (strstr(vbuf, "Powerpoint"))
! 122: str = "vnd.ms-powerpoint";
! 123: else if (strstr(vbuf,
! 124: "Crystal Reports"))
! 125: str = "x-rpt";
! 126: }
! 127: }
! 128: break;
! 129: case CDF_FILETIME:
! 130: tp = info[i].pi_tp;
! 131: if (tp != 0) {
1.1 misho 132: #if defined(PHP_WIN32) && _MSC_VER <= 1500
1.1.1.2 ! misho 133: if (tp < 1000000000000000i64) {
1.1 misho 134: #else
1.1.1.2 ! misho 135: if (tp < 1000000000000000LL) {
1.1 misho 136: #endif
1.1.1.2 ! misho 137: char tbuf[64];
! 138: cdf_print_elapsed_time(tbuf,
! 139: sizeof(tbuf), tp);
! 140: if (NOTMIME(ms) && file_printf(ms,
! 141: ", %s: %s", buf, tbuf) == -1)
! 142: return -1;
! 143: } else {
! 144: char *c, *ec;
! 145: if (cdf_timestamp_to_timespec(&ts, tp) == -1) {
! 146: return -1;
! 147: }
! 148: c = cdf_ctime(&ts.tv_sec);
! 149: if ((ec = strchr(c, '\n')) != NULL)
! 150: *ec = '\0';
! 151:
! 152: if (NOTMIME(ms) && file_printf(ms,
! 153: ", %s: %s", buf, c) == -1)
! 154: return -1;
! 155: }
! 156: }
! 157: break;
! 158: case CDF_CLIPBOARD:
! 159: break;
! 160: default:
! 161: return -1;
! 162: }
! 163: }
! 164: if (!NOTMIME(ms)) {
! 165: if (str == NULL)
! 166: return 0;
! 167: if (file_printf(ms, "application/%s", str) == -1)
! 168: return -1;
! 169: }
! 170: return 1;
1.1 misho 171: }
172:
173: private int
1.1.1.2 ! misho 174: cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
! 175: const cdf_stream_t *sst)
1.1 misho 176: {
1.1.1.2 ! misho 177: cdf_summary_info_header_t si;
! 178: cdf_property_info_t *info;
! 179: size_t count;
! 180: int m;
! 181:
! 182: if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1)
! 183: return -1;
! 184:
! 185: if (NOTMIME(ms)) {
! 186: if (file_printf(ms, "Composite Document File V2 Document")
! 187: == -1)
! 188: return -1;
! 189:
! 190: if (file_printf(ms, ", %s Endian",
! 191: si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
! 192: return -2;
! 193: switch (si.si_os) {
! 194: case 2:
! 195: if (file_printf(ms, ", Os: Windows, Version %d.%d",
! 196: si.si_os_version & 0xff,
! 197: (uint32_t)si.si_os_version >> 8) == -1)
! 198: return -2;
! 199: break;
! 200: case 1:
! 201: if (file_printf(ms, ", Os: MacOS, Version %d.%d",
! 202: (uint32_t)si.si_os_version >> 8,
! 203: si.si_os_version & 0xff) == -1)
! 204: return -2;
! 205: break;
! 206: default:
! 207: if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
! 208: si.si_os_version & 0xff,
! 209: (uint32_t)si.si_os_version >> 8) == -1)
! 210: return -2;
! 211: break;
! 212: }
! 213: }
1.1 misho 214:
1.1.1.2 ! misho 215: m = cdf_file_property_info(ms, info, count);
! 216: free(info);
1.1 misho 217:
1.1.1.2 ! misho 218: return m == -1 ? -2 : m;
1.1 misho 219: }
220:
221: protected int
222: file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
223: size_t nbytes)
224: {
1.1.1.2 ! misho 225: cdf_info_t info;
! 226: cdf_header_t h;
! 227: cdf_sat_t sat, ssat;
! 228: cdf_stream_t sst, scn;
! 229: cdf_dir_t dir;
! 230: int i;
! 231: const char *expn = "";
! 232: const char *corrupt = "corrupt: ";
! 233:
! 234: info.i_fd = fd;
! 235: info.i_buf = buf;
! 236: info.i_len = nbytes;
! 237: if (ms->flags & MAGIC_APPLE)
! 238: return 0;
! 239: if (cdf_read_header(&info, &h) == -1)
! 240: return 0;
1.1 misho 241: #ifdef CDF_DEBUG
1.1.1.2 ! misho 242: cdf_dump_header(&h);
1.1 misho 243: #endif
244:
1.1.1.2 ! misho 245: if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
! 246: expn = "Can't read SAT";
! 247: goto out0;
! 248: }
1.1 misho 249: #ifdef CDF_DEBUG
1.1.1.2 ! misho 250: cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
1.1 misho 251: #endif
252:
1.1.1.2 ! misho 253: if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
! 254: expn = "Can't read SSAT";
! 255: goto out1;
! 256: }
1.1 misho 257: #ifdef CDF_DEBUG
1.1.1.2 ! misho 258: cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
1.1 misho 259: #endif
260:
1.1.1.2 ! misho 261: if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
! 262: expn = "Can't read directory";
! 263: goto out2;
! 264: }
! 265:
! 266: if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
! 267: expn = "Cannot read short stream";
! 268: goto out3;
! 269: }
1.1 misho 270: #ifdef CDF_DEBUG
1.1.1.2 ! misho 271: cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
1.1 misho 272: #endif
273:
1.1.1.2 ! misho 274: if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
! 275: &scn)) == -1) {
! 276: if (errno == ESRCH) {
! 277: corrupt = expn;
! 278: expn = "No summary info";
! 279: } else {
! 280: expn = "Cannot read summary info";
! 281: }
! 282: goto out4;
! 283: }
1.1 misho 284: #ifdef CDF_DEBUG
1.1.1.2 ! misho 285: cdf_dump_summary_info(&h, &scn);
1.1 misho 286: #endif
1.1.1.2 ! misho 287: if ((i = cdf_file_summary_info(ms, &h, &scn)) < 0)
! 288: expn = "Can't expand summary_info";
! 289: if (i == 0) {
! 290: const char *str = "vnd.ms-office";
! 291: cdf_directory_t *d;
! 292: char name[__arraycount(d->d_name)];
! 293: size_t j, k;
! 294: for (j = 0; j < dir.dir_len; j++) {
! 295: d = &dir.dir_tab[j];
! 296: for (k = 0; k < sizeof(name); k++)
! 297: name[k] = (char)cdf_tole2(d->d_name[k]);
! 298: if (strstr(name, "WordDocument") == 0) {
! 299: str = "msword";
! 300: break;
! 301: }
! 302: }
! 303: if (file_printf(ms, "application/%s", str) == -1)
! 304: return -1;
! 305: i = 1;
! 306: }
! 307: free(scn.sst_tab);
1.1 misho 308: out4:
1.1.1.2 ! misho 309: free(sst.sst_tab);
1.1 misho 310: out3:
1.1.1.2 ! misho 311: free(dir.dir_tab);
1.1 misho 312: out2:
1.1.1.2 ! misho 313: free(ssat.sat_tab);
1.1 misho 314: out1:
1.1.1.2 ! misho 315: free(sat.sat_tab);
1.1 misho 316: out0:
1.1.1.2 ! misho 317: if (i != 1) {
! 318: if (i == -1)
! 319: if (file_printf(ms, "Composite Document File V2 Document")
! 320: == -1)
! 321: return -1;
! 322: if (*expn)
! 323: if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
! 324: return -1;
! 325: i = 1;
! 326: }
! 327: return i;
1.1 misho 328: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>