Annotation of embedaddon/php/ext/fileinfo/libmagic/readcdf.c, revision 1.1.1.1
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
29: FILE_RCSID("@(#)$File: readcdf.c,v 1.18 2009/05/06 20:48:22 christos Exp $")
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: {
51: size_t i;
52: cdf_timestamp_t tp;
53: struct timeval ts;
54: char buf[64];
55: const char *str = "vnd.ms-office";
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_SIGNED16:
63: if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
64: info[i].pi_s16) == -1)
65: return -1;
66: break;
67: case CDF_SIGNED32:
68: if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
69: info[i].pi_s32) == -1)
70: return -1;
71: break;
72: case CDF_UNSIGNED32:
73: if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
74: info[i].pi_u32) == -1)
75: return -1;
76: break;
77: case CDF_LENGTH32_STRING:
78: len = info[i].pi_str.s_len;
79: if (len > 1) {
80: s = info[i].pi_str.s_buf;
81: if (NOTMIME(ms)) {
82: char vbuf[1024];
83: size_t j;
84: for (j = 0; j < sizeof(vbuf) && len--;
85: j++, s++) {
86: if (*s == '\0')
87: break;
88: if (isprint((unsigned char)*s))
89: vbuf[j] = *s;
90: }
91: if (j == sizeof(vbuf))
92: --j;
93: vbuf[j] = '\0';
94: if (vbuf[0]) {
95: if (file_printf(ms, ", %s: %s",
96: buf, vbuf) == -1)
97: return -1;
98: }
99: } else if (info[i].pi_id ==
100: CDF_PROPERTY_NAME_OF_APPLICATION) {
101: if (strstr(s, "Word"))
102: str = "msword";
103: else if (strstr(s, "Excel"))
104: str = "vnd.ms-excel";
105: else if (strstr(s, "Powerpoint"))
106: str = "vnd.ms-powerpoint";
107: }
108: }
109: break;
110: case CDF_FILETIME:
111: tp = info[i].pi_tp;
112: if (tp != 0) {
113: #if defined(PHP_WIN32) && _MSC_VER <= 1500
114: if (tp < 1000000000000000i64) {
115: #else
116: if (tp < 1000000000000000LL) {
117: #endif
118: char tbuf[64];
119: cdf_print_elapsed_time(tbuf,
120: sizeof(tbuf), tp);
121: if (NOTMIME(ms) && file_printf(ms,
122: ", %s: %s", buf, tbuf) == -1)
123: return -1;
124: } else {
125: char *c, *ec;
126:
127: if (cdf_timestamp_to_timespec(&ts, tp) == -1) {
128: return -1;
129: }
130: c = ctime(&ts.tv_sec);
131: if ((ec = strchr(c, '\n')) != NULL)
132: *ec = '\0';
133:
134: if (NOTMIME(ms) && file_printf(ms,
135: ", %s: %s", buf, c) == -1)
136: return -1;
137: }
138: }
139: break;
140: case CDF_CLIPBOARD:
141: break;
142: default:
143: return -1;
144: }
145: }
146: if (!NOTMIME(ms)) {
147: if (file_printf(ms, "application/%s", str) == -1)
148: return -1;
149: }
150: return 1;
151: }
152:
153: private int
154: cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst)
155: {
156: cdf_summary_info_header_t si;
157: cdf_property_info_t *info;
158: size_t count;
159: int m;
160:
161: if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1)
162: return -1;
163:
164: if (NOTMIME(ms)) {
165: if (file_printf(ms, "CDF V2 Document") == -1)
166: return -1;
167:
168: if (file_printf(ms, ", %s Endian",
169: si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
170: return -1;
171: switch (si.si_os) {
172: case 2:
173: if (file_printf(ms, ", Os: Windows, Version %d.%d",
174: si.si_os_version & 0xff, si.si_os_version >> 8)
175: == -1)
176: return -1;
177: break;
178: case 1:
179: if (file_printf(ms, ", Os: MacOS, Version %d.%d",
180: si.si_os_version >> 8, si.si_os_version & 0xff)
181: == -1)
182: return -1;
183: break;
184: default:
185: if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
186: si.si_os_version & 0xff, si.si_os_version >> 8)
187: == -1)
188: return -1;
189: break;
190: }
191: }
192:
193: m = cdf_file_property_info(ms, info, count);
194: free(info);
195:
196: return m;
197: }
198:
199: protected int
200: file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
201: size_t nbytes)
202: {
203: cdf_info_t info;
204: cdf_header_t h;
205: cdf_sat_t sat, ssat;
206: cdf_stream_t sst, scn;
207: cdf_dir_t dir;
208: int i;
209: const char *expn = "";
210:
211: info.i_fd = fd;
212: info.i_buf = buf;
213: info.i_len = nbytes;
214: if (ms->flags & MAGIC_APPLE)
215: return 0;
216: if (cdf_read_header(&info, &h) == -1)
217: return 0;
218: #ifdef CDF_DEBUG
219: cdf_dump_header(&h);
220: #endif
221:
222: if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
223: expn = "Can't read SAT";
224: goto out0;
225: }
226: #ifdef CDF_DEBUG
227: cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
228: #endif
229:
230: if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
231: expn = "Can't read SSAT";
232: goto out1;
233: }
234: #ifdef CDF_DEBUG
235: cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
236: #endif
237:
238: if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
239: expn = "Can't read directory";
240: goto out2;
241: }
242:
243: if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
244: expn = "Cannot read short stream";
245: goto out3;
246: }
247: #ifdef CDF_DEBUG
248: cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
249: #endif
250:
251: if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
252: &scn)) == -1) {
253: expn = "Cannot read summary info";
254: goto out4;
255: }
256: #ifdef CDF_DEBUG
257: cdf_dump_summary_info(&h, &scn);
258: #endif
259: if ((i = cdf_file_summary_info(ms, &scn)) == -1)
260: expn = "Can't expand summary_info";
261: free(scn.sst_tab);
262: out4:
263: free(sst.sst_tab);
264: out3:
265: free(dir.dir_tab);
266: out2:
267: free(ssat.sat_tab);
268: out1:
269: free(sat.sat_tab);
270: out0:
271: if (i != 1) {
272: if (file_printf(ms, "CDF V2 Document") == -1)
273: return -1;
274: if (*expn)
275: if (file_printf(ms, ", corrupt: %s", expn) == -1)
276: return -1;
277: i = 1;
278: }
279: return i;
280: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>