cdf-cert-bff-crashes 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364
  1. Index: git/src/cdf.c
  2. ===================================================================
  3. --- git.orig/src/cdf.c 2012-02-29 20:13:05.341191429 +0100
  4. +++ git/src/cdf.c 2012-02-29 20:13:19.726010338 +0100
  5. @@ -24,15 +24,18 @@
  6. * POSSIBILITY OF SUCH DAMAGE.
  7. */
  8. /*
  9. - * Parse composite document files, the format used in Microsoft Office
  10. - * document files before they switched to zipped xml.
  11. + * Parse Composite Document Files, the format used in Microsoft Office
  12. + * document files before they switched to zipped XML.
  13. * Info from: http://sc.openoffice.org/compdocfileformat.pdf
  14. + *
  15. + * N.B. This is the "Composite Document File" format, and not the
  16. + * "Compound Document Format", nor the "Channel Definition Format".
  17. */
  18. #include "file.h"
  19. #ifndef lint
  20. -FILE_RCSID("@(#)$File: cdf.c,v 1.36 2010/01/22 20:56:26 christos Exp $")
  21. +FILE_RCSID("@(#)$File: cdf.c,v 1.49 2012/02/20 20:04:37 christos Exp $")
  22. #endif
  23. #include <assert.h>
  24. @@ -54,10 +57,6 @@
  25. #include "cdf.h"
  26. -#ifndef __arraycount
  27. -#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
  28. -#endif
  29. -
  30. #ifdef CDF_DEBUG
  31. #define DPRINTF(a) printf a, fflush(stdout)
  32. #else
  33. @@ -71,19 +70,21 @@
  34. #define NEED_SWAP (cdf_bo.u == (uint32_t)0x01020304)
  35. -#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? cdf_tole8(x) : (uint64_t)(x)))
  36. -#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? cdf_tole4(x) : (uint32_t)(x)))
  37. -#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? cdf_tole2(x) : (uint16_t)(x)))
  38. +#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x)))
  39. +#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x)))
  40. +#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x)))
  41. +#define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
  42. +
  43. /*
  44. * swap a short
  45. */
  46. -uint16_t
  47. -cdf_tole2(uint16_t sv)
  48. +static uint16_t
  49. +_cdf_tole2(uint16_t sv)
  50. {
  51. uint16_t rv;
  52. - uint8_t *s = (uint8_t *)(void *)&sv;
  53. - uint8_t *d = (uint8_t *)(void *)&rv;
  54. + uint8_t *s = (uint8_t *)(void *)&sv;
  55. + uint8_t *d = (uint8_t *)(void *)&rv;
  56. d[0] = s[1];
  57. d[1] = s[0];
  58. return rv;
  59. @@ -92,12 +93,12 @@
  60. /*
  61. * swap an int
  62. */
  63. -uint32_t
  64. -cdf_tole4(uint32_t sv)
  65. +static uint32_t
  66. +_cdf_tole4(uint32_t sv)
  67. {
  68. uint32_t rv;
  69. - uint8_t *s = (uint8_t *)(void *)&sv;
  70. - uint8_t *d = (uint8_t *)(void *)&rv;
  71. + uint8_t *s = (uint8_t *)(void *)&sv;
  72. + uint8_t *d = (uint8_t *)(void *)&rv;
  73. d[0] = s[3];
  74. d[1] = s[2];
  75. d[2] = s[1];
  76. @@ -108,12 +109,12 @@
  77. /*
  78. * swap a quad
  79. */
  80. -uint64_t
  81. -cdf_tole8(uint64_t sv)
  82. +static uint64_t
  83. +_cdf_tole8(uint64_t sv)
  84. {
  85. uint64_t rv;
  86. - uint8_t *s = (uint8_t *)(void *)&sv;
  87. - uint8_t *d = (uint8_t *)(void *)&rv;
  88. + uint8_t *s = (uint8_t *)(void *)&sv;
  89. + uint8_t *d = (uint8_t *)(void *)&rv;
  90. d[0] = s[7];
  91. d[1] = s[6];
  92. d[2] = s[5];
  93. @@ -125,11 +126,41 @@
  94. return rv;
  95. }
  96. +/*
  97. + * grab a uint32_t from a possibly unaligned address, and return it in
  98. + * the native host order.
  99. + */
  100. +static uint32_t
  101. +cdf_getuint32(const uint8_t *p, size_t offs)
  102. +{
  103. + uint32_t rv;
  104. + (void)memcpy(&rv, p + offs * sizeof(uint32_t), sizeof(rv));
  105. + return CDF_TOLE4(rv);
  106. +}
  107. +
  108. #define CDF_UNPACK(a) \
  109. (void)memcpy(&(a), &buf[len], sizeof(a)), len += sizeof(a)
  110. #define CDF_UNPACKA(a) \
  111. (void)memcpy((a), &buf[len], sizeof(a)), len += sizeof(a)
  112. +uint16_t
  113. +cdf_tole2(uint16_t sv)
  114. +{
  115. + return CDF_TOLE2(sv);
  116. +}
  117. +
  118. +uint32_t
  119. +cdf_tole4(uint32_t sv)
  120. +{
  121. + return CDF_TOLE4(sv);
  122. +}
  123. +
  124. +uint64_t
  125. +cdf_tole8(uint64_t sv)
  126. +{
  127. + return CDF_TOLE8(sv);
  128. +}
  129. +
  130. void
  131. cdf_swap_header(cdf_header_t *h)
  132. {
  133. @@ -231,17 +262,18 @@
  134. }
  135. static int
  136. -cdf_check_stream_offset(const cdf_stream_t *sst, const void *p, size_t tail,
  137. - int line)
  138. +cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
  139. + const void *p, size_t tail, int line)
  140. {
  141. const char *b = (const char *)sst->sst_tab;
  142. const char *e = ((const char *)p) + tail;
  143. (void)&line;
  144. - if (e >= b && (size_t)(e - b) < sst->sst_dirlen * sst->sst_len)
  145. + if (e >= b && (size_t)(e - b) < CDF_SEC_SIZE(h) * sst->sst_len)
  146. return 0;
  147. - DPRINTF(("%d: offset begin %p end %p %zu >= %zu [%zu %zu]\n",
  148. - line, b, e, (size_t)(e - b), sst->sst_dirlen * sst->sst_len,
  149. - sst->sst_dirlen, sst->sst_len));
  150. + DPRINTF(("%d: offset begin %p end %p %" SIZE_T_FORMAT "u"
  151. + " >= %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %"
  152. + SIZE_T_FORMAT "u]\n", line, b, e, (size_t)(e - b),
  153. + CDF_SEC_SIZE(h) * sst->sst_len, CDF_SEC_SIZE(h), sst->sst_len));
  154. errno = EFTYPE;
  155. return -1;
  156. }
  157. @@ -284,7 +316,8 @@
  158. cdf_unpack_header(h, buf);
  159. cdf_swap_header(h);
  160. if (h->h_magic != CDF_MAGIC) {
  161. - DPRINTF(("Bad magic 0x%llx != 0x%llx\n",
  162. + DPRINTF(("Bad magic 0x%" INT64_T_FORMAT "x != 0x%"
  163. + INT64_T_FORMAT "x\n",
  164. (unsigned long long)h->h_magic,
  165. (unsigned long long)CDF_MAGIC));
  166. goto out;
  167. @@ -309,18 +342,27 @@
  168. cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
  169. const cdf_header_t *h, cdf_secid_t id)
  170. {
  171. - assert((size_t)CDF_SEC_SIZE(h) == len);
  172. - return cdf_read(info, (off_t)CDF_SEC_POS(h, id),
  173. - ((char *)buf) + offs, len);
  174. + size_t ss = CDF_SEC_SIZE(h);
  175. + size_t pos = CDF_SEC_POS(h, id);
  176. + assert(ss == len);
  177. + return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len);
  178. }
  179. ssize_t
  180. cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
  181. size_t len, const cdf_header_t *h, cdf_secid_t id)
  182. {
  183. - assert((size_t)CDF_SHORT_SEC_SIZE(h) == len);
  184. + size_t ss = CDF_SHORT_SEC_SIZE(h);
  185. + size_t pos = CDF_SHORT_SEC_POS(h, id);
  186. + assert(ss == len);
  187. + if (pos > CDF_SEC_SIZE(h) * sst->sst_len) {
  188. + DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %"
  189. + SIZE_T_FORMAT "u\n",
  190. + pos, CDF_SEC_SIZE(h) * sst->sst_len));
  191. + return -1;
  192. + }
  193. (void)memcpy(((char *)buf) + offs,
  194. - ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len);
  195. + ((const char *)sst->sst_tab) + pos, len);
  196. return len;
  197. }
  198. @@ -340,16 +382,18 @@
  199. break;
  200. #define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss))
  201. - if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec ||
  202. + if ((nsatpersec > 0 &&
  203. + h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec) ||
  204. i > CDF_SEC_LIMIT) {
  205. - DPRINTF(("Number of sectors in master SAT too big %u %zu\n",
  206. - h->h_num_sectors_in_master_sat, i));
  207. + DPRINTF(("Number of sectors in master SAT too big %u %"
  208. + SIZE_T_FORMAT "u\n", h->h_num_sectors_in_master_sat, i));
  209. errno = EFTYPE;
  210. return -1;
  211. }
  212. sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i;
  213. - DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss));
  214. + DPRINTF(("sat_len = %" SIZE_T_FORMAT "u ss = %" SIZE_T_FORMAT "u\n",
  215. + sat->sat_len, ss));
  216. if ((sat->sat_tab = CAST(cdf_secid_t *, calloc(sat->sat_len, ss)))
  217. == NULL)
  218. return -1;
  219. @@ -385,8 +429,8 @@
  220. if (sec < 0)
  221. goto out;
  222. if (i >= sat->sat_len) {
  223. - DPRINTF(("Out of bounds reading MSA %u >= %u",
  224. - i, sat->sat_len));
  225. + DPRINTF(("Out of bounds reading MSA %" SIZE_T_FORMAT
  226. + "u >= %" SIZE_T_FORMAT "u", i, sat->sat_len));
  227. errno = EFTYPE;
  228. goto out2;
  229. }
  230. @@ -459,7 +503,8 @@
  231. }
  232. if (i >= scn->sst_len) {
  233. DPRINTF(("Out of bounds reading long sector chain "
  234. - "%u > %u\n", i, scn->sst_len));
  235. + "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", i,
  236. + scn->sst_len));
  237. errno = EFTYPE;
  238. goto out;
  239. }
  240. @@ -504,7 +549,8 @@
  241. }
  242. if (i >= scn->sst_len) {
  243. DPRINTF(("Out of bounds reading short sector chain "
  244. - "%u > %u\n", i, scn->sst_len));
  245. + "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n",
  246. + i, scn->sst_len));
  247. errno = EFTYPE;
  248. goto out;
  249. }
  250. @@ -550,7 +596,7 @@
  251. nd = ss / CDF_DIRECTORY_SIZE;
  252. dir->dir_len = ns * nd;
  253. - dir->dir_tab = CAST(cdf_directory_t *,
  254. + dir->dir_tab = CAST(cdf_directory_t *,
  255. calloc(dir->dir_len, sizeof(dir->dir_tab[0])));
  256. if (dir->dir_tab == NULL)
  257. return -1;
  258. @@ -612,7 +658,8 @@
  259. }
  260. if (i >= ssat->sat_len) {
  261. DPRINTF(("Out of bounds reading short sector chain "
  262. - "%u > %u\n", i, ssat->sat_len));
  263. + "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", i,
  264. + ssat->sat_len));
  265. errno = EFTYPE;
  266. goto out;
  267. }
  268. @@ -649,7 +696,7 @@
  269. if (d->d_stream_first_sector < 0)
  270. goto out;
  271. - return cdf_read_long_sector_chain(info, h, sat,
  272. + return cdf_read_long_sector_chain(info, h, sat,
  273. d->d_stream_first_sector, d->d_size, scn);
  274. out:
  275. scn->sst_tab = NULL;
  276. @@ -693,19 +740,19 @@
  277. }
  278. int
  279. -cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
  280. - cdf_property_info_t **info, size_t *count, size_t *maxcount)
  281. +cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
  282. + uint32_t offs, cdf_property_info_t **info, size_t *count, size_t *maxcount)
  283. {
  284. const cdf_section_header_t *shp;
  285. cdf_section_header_t sh;
  286. - const uint32_t *p, *q, *e;
  287. + const uint8_t *p, *q, *e;
  288. int16_t s16;
  289. int32_t s32;
  290. uint32_t u32;
  291. int64_t s64;
  292. uint64_t u64;
  293. cdf_timestamp_t tp;
  294. - size_t i, o, nelements, j;
  295. + size_t i, o, o4, nelements, j;
  296. cdf_property_info_t *inp;
  297. if (offs > UINT32_MAX / 4) {
  298. @@ -714,7 +761,7 @@
  299. }
  300. shp = CAST(const cdf_section_header_t *, (const void *)
  301. ((const char *)sst->sst_tab + offs));
  302. - if (cdf_check_stream_offset(sst, shp, sizeof(*shp), __LINE__) == -1)
  303. + if (cdf_check_stream_offset(sst, h, shp, sizeof(*shp), __LINE__) == -1)
  304. goto out;
  305. sh.sh_len = CDF_TOLE4(shp->sh_len);
  306. #define CDF_SHLEN_LIMIT (UINT32_MAX / 8)
  307. @@ -744,32 +791,34 @@
  308. *info = inp;
  309. inp += *count;
  310. *count += sh.sh_properties;
  311. - p = CAST(const uint32_t *, (const void *)
  312. + p = CAST(const uint8_t *, (const void *)
  313. ((const char *)(const void *)sst->sst_tab +
  314. offs + sizeof(sh)));
  315. - e = CAST(const uint32_t *, (const void *)
  316. + e = CAST(const uint8_t *, (const void *)
  317. (((const char *)(const void *)shp) + sh.sh_len));
  318. - if (cdf_check_stream_offset(sst, e, 0, __LINE__) == -1)
  319. + if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1)
  320. goto out;
  321. for (i = 0; i < sh.sh_properties; i++) {
  322. - q = (const uint32_t *)(const void *)
  323. - ((const char *)(const void *)p +
  324. - CDF_TOLE4(p[(i << 1) + 1])) - 2;
  325. + size_t ofs = CDF_GETUINT32(p, (i << 1) + 1);
  326. + q = (const uint8_t *)(const void *)
  327. + ((const char *)(const void *)p + ofs
  328. + - 2 * sizeof(uint32_t));
  329. if (q > e) {
  330. DPRINTF(("Ran of the end %p > %p\n", q, e));
  331. goto out;
  332. }
  333. - inp[i].pi_id = CDF_TOLE4(p[i << 1]);
  334. - inp[i].pi_type = CDF_TOLE4(q[0]);
  335. - DPRINTF(("%d) id=%x type=%x offs=%x\n", i, inp[i].pi_id,
  336. - inp[i].pi_type, (const char *)q - (const char *)p));
  337. + inp[i].pi_id = CDF_GETUINT32(p, i << 1);
  338. + inp[i].pi_type = CDF_GETUINT32(q, 0);
  339. + DPRINTF(("%" SIZE_T_FORMAT "u) id=%x type=%x offs=0x%tx,0x%x\n",
  340. + i, inp[i].pi_id, inp[i].pi_type, q - p, offs));
  341. if (inp[i].pi_type & CDF_VECTOR) {
  342. - nelements = CDF_TOLE4(q[1]);
  343. + nelements = CDF_GETUINT32(q, 1);
  344. o = 2;
  345. } else {
  346. nelements = 1;
  347. o = 1;
  348. }
  349. + o4 = o * sizeof(uint32_t);
  350. if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED))
  351. goto unknown;
  352. switch (inp[i].pi_type & CDF_TYPEMASK) {
  353. @@ -779,34 +828,48 @@
  354. case CDF_SIGNED16:
  355. if (inp[i].pi_type & CDF_VECTOR)
  356. goto unknown;
  357. - (void)memcpy(&s16, &q[o], sizeof(s16));
  358. + (void)memcpy(&s16, &q[o4], sizeof(s16));
  359. inp[i].pi_s16 = CDF_TOLE2(s16);
  360. break;
  361. case CDF_SIGNED32:
  362. if (inp[i].pi_type & CDF_VECTOR)
  363. goto unknown;
  364. - (void)memcpy(&s32, &q[o], sizeof(s32));
  365. + (void)memcpy(&s32, &q[o4], sizeof(s32));
  366. inp[i].pi_s32 = CDF_TOLE4((uint32_t)s32);
  367. break;
  368. case CDF_BOOL:
  369. case CDF_UNSIGNED32:
  370. if (inp[i].pi_type & CDF_VECTOR)
  371. goto unknown;
  372. - (void)memcpy(&u32, &q[o], sizeof(u32));
  373. + (void)memcpy(&u32, &q[o4], sizeof(u32));
  374. inp[i].pi_u32 = CDF_TOLE4(u32);
  375. break;
  376. case CDF_SIGNED64:
  377. if (inp[i].pi_type & CDF_VECTOR)
  378. goto unknown;
  379. - (void)memcpy(&s64, &q[o], sizeof(s64));
  380. + (void)memcpy(&s64, &q[o4], sizeof(s64));
  381. inp[i].pi_s64 = CDF_TOLE8((uint64_t)s64);
  382. break;
  383. case CDF_UNSIGNED64:
  384. if (inp[i].pi_type & CDF_VECTOR)
  385. goto unknown;
  386. - (void)memcpy(&u64, &q[o], sizeof(u64));
  387. + (void)memcpy(&u64, &q[o4], sizeof(u64));
  388. inp[i].pi_u64 = CDF_TOLE8((uint64_t)u64);
  389. break;
  390. + case CDF_FLOAT:
  391. + if (inp[i].pi_type & CDF_VECTOR)
  392. + goto unknown;
  393. + (void)memcpy(&u32, &q[o4], sizeof(u32));
  394. + u32 = CDF_TOLE4(u32);
  395. + memcpy(&inp[i].pi_f, &u32, sizeof(inp[i].pi_f));
  396. + break;
  397. + case CDF_DOUBLE:
  398. + if (inp[i].pi_type & CDF_VECTOR)
  399. + goto unknown;
  400. + (void)memcpy(&u64, &q[o4], sizeof(u64));
  401. + u64 = CDF_TOLE8((uint64_t)u64);
  402. + memcpy(&inp[i].pi_d, &u64, sizeof(inp[i].pi_d));
  403. + break;
  404. case CDF_LENGTH32_STRING:
  405. case CDF_LENGTH32_WSTRING:
  406. if (nelements > 1) {
  407. @@ -822,24 +885,30 @@
  408. *info = inp;
  409. inp = *info + nelem;
  410. }
  411. - DPRINTF(("nelements = %d\n", nelements));
  412. + DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
  413. + nelements));
  414. for (j = 0; j < nelements; j++, i++) {
  415. - uint32_t l = CDF_TOLE4(q[o]);
  416. + uint32_t l = CDF_GETUINT32(q, o);
  417. inp[i].pi_str.s_len = l;
  418. - inp[i].pi_str.s_buf =
  419. - (const char *)(const void *)(&q[o+1]);
  420. - DPRINTF(("l = %d, r = %d, s = %s\n", l,
  421. + inp[i].pi_str.s_buf = (const char *)
  422. + (const void *)(&q[o4 + sizeof(l)]);
  423. + DPRINTF(("l = %d, r = %" SIZE_T_FORMAT
  424. + "u, s = %s\n", l,
  425. CDF_ROUND(l, sizeof(l)),
  426. inp[i].pi_str.s_buf));
  427. - l = 4 + (uint32_t)CDF_ROUND(l, sizeof(l));
  428. - o += l >> 2;
  429. + if (l & 1)
  430. + l++;
  431. + o += l >> 1;
  432. + if (q + o >= e)
  433. + goto out;
  434. + o4 = o * sizeof(uint32_t);
  435. }
  436. i--;
  437. break;
  438. case CDF_FILETIME:
  439. if (inp[i].pi_type & CDF_VECTOR)
  440. goto unknown;
  441. - (void)memcpy(&tp, &q[o], sizeof(tp));
  442. + (void)memcpy(&tp, &q[o4], sizeof(tp));
  443. inp[i].pi_tp = CDF_TOLE8((uint64_t)tp);
  444. break;
  445. case CDF_CLIPBOARD:
  446. @@ -850,7 +919,7 @@
  447. unknown:
  448. DPRINTF(("Don't know how to deal with %x\n",
  449. inp[i].pi_type));
  450. - goto out;
  451. + break;
  452. }
  453. }
  454. return 0;
  455. @@ -860,8 +929,8 @@
  456. }
  457. int
  458. -cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi,
  459. - cdf_property_info_t **info, size_t *count)
  460. +cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
  461. + cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count)
  462. {
  463. size_t i, maxcount;
  464. const cdf_summary_info_header_t *si =
  465. @@ -870,8 +939,8 @@
  466. CAST(const cdf_section_declaration_t *, (const void *)
  467. ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET));
  468. - if (cdf_check_stream_offset(sst, si, sizeof(*si), __LINE__) == -1 ||
  469. - cdf_check_stream_offset(sst, sd, sizeof(*sd), __LINE__) == -1)
  470. + if (cdf_check_stream_offset(sst, h, si, sizeof(*si), __LINE__) == -1 ||
  471. + cdf_check_stream_offset(sst, h, sd, sizeof(*sd), __LINE__) == -1)
  472. return -1;
  473. ssi->si_byte_order = CDF_TOLE2(si->si_byte_order);
  474. ssi->si_os_version = CDF_TOLE2(si->si_os_version);
  475. @@ -888,9 +957,10 @@
  476. errno = EFTYPE;
  477. return -1;
  478. }
  479. - if (cdf_read_property_info(sst, CDF_TOLE4(sd->sd_offset),
  480. - info, count, &maxcount) == -1)
  481. + if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset),
  482. + info, count, &maxcount) == -1) {
  483. return -1;
  484. + }
  485. }
  486. return 0;
  487. }
  488. @@ -1015,13 +1085,14 @@
  489. size_t i, j, s = size / sizeof(cdf_secid_t);
  490. for (i = 0; i < sat->sat_len; i++) {
  491. - (void)fprintf(stderr, "%s[%zu]:\n%.6d: ", prefix, i, i * s);
  492. + (void)fprintf(stderr, "%s[%" SIZE_T_FORMAT "u]:\n%.6"
  493. + SIZE_T_FORMAT "u: ", prefix, i, i * s);
  494. for (j = 0; j < s; j++) {
  495. (void)fprintf(stderr, "%5d, ",
  496. CDF_TOLE4(sat->sat_tab[s * i + j]));
  497. if ((j + 1) % 10 == 0)
  498. - (void)fprintf(stderr, "\n%.6d: ",
  499. - i * s + j + 1);
  500. + (void)fprintf(stderr, "\n%.6" SIZE_T_FORMAT
  501. + "u: ", i * s + j + 1);
  502. }
  503. (void)fprintf(stderr, "\n");
  504. }
  505. @@ -1040,7 +1111,8 @@
  506. if (j == 16) {
  507. j = 0;
  508. abuf[15] = '\0';
  509. - (void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1);
  510. + (void)fprintf(stderr, "%s\n%.4" SIZE_T_FORMAT "x: ",
  511. + abuf, i + 1);
  512. }
  513. }
  514. (void)fprintf(stderr, "\n");
  515. @@ -1072,7 +1144,8 @@
  516. d = &dir->dir_tab[i];
  517. for (j = 0; j < sizeof(name); j++)
  518. name[j] = (char)CDF_TOLE2(d->d_name[j]);
  519. - (void)fprintf(stderr, "Directory %zu: %s\n", i, name);
  520. + (void)fprintf(stderr, "Directory %" SIZE_T_FORMAT "u: %s\n",
  521. + i, name);
  522. if (d->d_type < __arraycount(types))
  523. (void)fprintf(stderr, "Type: %s\n", types[d->d_type]);
  524. else
  525. @@ -1083,9 +1156,9 @@
  526. (void)fprintf(stderr, "Right child: %d\n", d->d_right_child);
  527. (void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags);
  528. cdf_timestamp_to_timespec(&ts, d->d_created);
  529. - (void)fprintf(stderr, "Created %s", ctime(&ts.tv_sec));
  530. + (void)fprintf(stderr, "Created %s", cdf_ctime(&ts.tv_sec));
  531. cdf_timestamp_to_timespec(&ts, d->d_modified);
  532. - (void)fprintf(stderr, "Modified %s", ctime(&ts.tv_sec));
  533. + (void)fprintf(stderr, "Modified %s", cdf_ctime(&ts.tv_sec));
  534. (void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector);
  535. (void)fprintf(stderr, "Size %d\n", d->d_size);
  536. switch (d->d_type) {
  537. @@ -1107,7 +1180,7 @@
  538. default:
  539. break;
  540. }
  541. -
  542. +
  543. }
  544. }
  545. @@ -1121,7 +1194,7 @@
  546. for (i = 0; i < count; i++) {
  547. cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
  548. - (void)fprintf(stderr, "%zu) %s: ", i, buf);
  549. + (void)fprintf(stderr, "%" SIZE_T_FORMAT "u) %s: ", i, buf);
  550. switch (info[i].pi_type) {
  551. case CDF_NULL:
  552. break;
  553. @@ -1137,17 +1210,25 @@
  554. (void)fprintf(stderr, "unsigned 32 [%u]\n",
  555. info[i].pi_u32);
  556. break;
  557. + case CDF_FLOAT:
  558. + (void)fprintf(stderr, "float [%g]\n",
  559. + info[i].pi_f);
  560. + break;
  561. + case CDF_DOUBLE:
  562. + (void)fprintf(stderr, "double [%g]\n",
  563. + info[i].pi_d);
  564. + break;
  565. case CDF_LENGTH32_STRING:
  566. (void)fprintf(stderr, "string %u [%.*s]\n",
  567. info[i].pi_str.s_len,
  568. info[i].pi_str.s_len, info[i].pi_str.s_buf);
  569. break;
  570. case CDF_LENGTH32_WSTRING:
  571. - (void)fprintf(stderr, "string %u [",
  572. + (void)fprintf(stderr, "string %u [",
  573. info[i].pi_str.s_len);
  574. for (j = 0; j < info[i].pi_str.s_len - 1; j++)
  575. (void)fputc(info[i].pi_str.s_buf[j << 1], stderr);
  576. - (void)fprintf(stderr, "]\n");
  577. + (void)fprintf(stderr, "]\n");
  578. break;
  579. case CDF_FILETIME:
  580. tp = info[i].pi_tp;
  581. @@ -1157,7 +1238,7 @@
  582. } else {
  583. cdf_timestamp_to_timespec(&ts, tp);
  584. (void)fprintf(stderr, "timestamp %s",
  585. - ctime(&ts.tv_sec));
  586. + cdf_ctime(&ts.tv_sec));
  587. }
  588. break;
  589. case CDF_CLIPBOARD:
  590. @@ -1181,7 +1262,7 @@
  591. size_t count;
  592. (void)&h;
  593. - if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1)
  594. + if (cdf_unpack_summary_info(sst, h, &ssi, &info, &count) == -1)
  595. return;
  596. (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order);
  597. (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
  598. Index: git/src/cdf.h
  599. ===================================================================
  600. --- git.orig/src/cdf.h 2012-02-29 20:13:05.341191429 +0100
  601. +++ git/src/cdf.h 2012-02-29 20:13:19.726010338 +0100
  602. @@ -24,20 +24,35 @@
  603. * POSSIBILITY OF SUCH DAMAGE.
  604. */
  605. /*
  606. - * Info from: http://sc.openoffice.org/compdocfileformat.pdf
  607. + * Parse Composite Document Files, the format used in Microsoft Office
  608. + * document files before they switched to zipped XML.
  609. + * Info from: http://sc.openoffice.org/compdocfileformat.pdf
  610. + *
  611. + * N.B. This is the "Composite Document File" format, and not the
  612. + * "Compound Document Format", nor the "Channel Definition Format".
  613. */
  614. #ifndef _H_CDF_
  615. #define _H_CDF_
  616. +#ifdef WIN32
  617. +#include <winsock2.h>
  618. +#define timespec timeval
  619. +#define tv_nsec tv_usec
  620. +#endif
  621. +#ifdef __DJGPP__
  622. +#define timespec timeval
  623. +#define tv_nsec tv_usec
  624. +#endif
  625. +
  626. typedef int32_t cdf_secid_t;
  627. #define CDF_LOOP_LIMIT 10000
  628. #define CDF_SECID_NULL 0
  629. #define CDF_SECID_FREE -1
  630. -#define CDF_SECID_END_OF_CHAIN -2
  631. -#define CDF_SECID_SECTOR_ALLOCATION_TABLE -3
  632. +#define CDF_SECID_END_OF_CHAIN -2
  633. +#define CDF_SECID_SECTOR_ALLOCATION_TABLE -3
  634. #define CDF_SECID_MASTER_SECTOR_ALLOCATION_TABLE -4
  635. typedef struct {
  636. @@ -61,15 +76,15 @@
  637. cdf_secid_t h_master_sat[436/4];
  638. } cdf_header_t;
  639. -#define CDF_SEC_SIZE(h) (1 << (h)->h_sec_size_p2)
  640. +#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2))
  641. #define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h))
  642. -#define CDF_SHORT_SEC_SIZE(h) (1 << (h)->h_short_sec_size_p2)
  643. +#define CDF_SHORT_SEC_SIZE(h) ((size_t)(1 << (h)->h_short_sec_size_p2))
  644. #define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h))
  645. -typedef int32_t cdf_dirid_t;
  646. +typedef int32_t cdf_dirid_t;
  647. #define CDF_DIRID_NULL -1
  648. -typedef int64_t cdf_timestamp_t;
  649. +typedef int64_t cdf_timestamp_t;
  650. #define CDF_BASE_YEAR 1601
  651. #define CDF_TIME_PREC 10000000
  652. @@ -78,11 +93,11 @@
  653. uint16_t d_namelen;
  654. uint8_t d_type;
  655. #define CDF_DIR_TYPE_EMPTY 0
  656. -#define CDF_DIR_TYPE_USER_STORAGE 1
  657. -#define CDF_DIR_TYPE_USER_STREAM 2
  658. -#define CDF_DIR_TYPE_LOCKBYTES 3
  659. -#define CDF_DIR_TYPE_PROPERTY 4
  660. -#define CDF_DIR_TYPE_ROOT_STORAGE 5
  661. +#define CDF_DIR_TYPE_USER_STORAGE 1
  662. +#define CDF_DIR_TYPE_USER_STREAM 2
  663. +#define CDF_DIR_TYPE_LOCKBYTES 3
  664. +#define CDF_DIR_TYPE_PROPERTY 4
  665. +#define CDF_DIR_TYPE_ROOT_STORAGE 5
  666. uint8_t d_color;
  667. #define CDF_DIR_COLOR_READ 0
  668. #define CDF_DIR_COLOR_BLACK 1
  669. @@ -91,8 +106,8 @@
  670. cdf_dirid_t d_storage;
  671. uint64_t d_storage_uuid[2];
  672. uint32_t d_flags;
  673. - cdf_timestamp_t d_created;
  674. - cdf_timestamp_t d_modified;
  675. + cdf_timestamp_t d_created;
  676. + cdf_timestamp_t d_modified;
  677. cdf_secid_t d_stream_first_sector;
  678. uint32_t d_size;
  679. uint32_t d_unused0;
  680. @@ -154,7 +169,9 @@
  681. int32_t _pi_s32;
  682. uint64_t _pi_u64;
  683. int64_t _pi_s64;
  684. - cdf_timestamp_t _pi_tp;
  685. + cdf_timestamp_t _pi_tp;
  686. + float _pi_f;
  687. + double _pi_d;
  688. struct {
  689. uint32_t s_len;
  690. const char *s_buf;
  691. @@ -166,6 +183,8 @@
  692. #define pi_s32 pi_val._pi_s32
  693. #define pi_u16 pi_val._pi_u16
  694. #define pi_s16 pi_val._pi_s16
  695. +#define pi_f pi_val._pi_f
  696. +#define pi_d pi_val._pi_d
  697. #define pi_tp pi_val._pi_tp
  698. #define pi_str pi_val._pi_str
  699. } cdf_property_info_t;
  700. @@ -174,13 +193,13 @@
  701. /* Variant type definitions */
  702. #define CDF_EMPTY 0x00000000
  703. -#define CDF_NULL 0x00000001
  704. +#define CDF_NULL 0x00000001
  705. #define CDF_SIGNED16 0x00000002
  706. #define CDF_SIGNED32 0x00000003
  707. #define CDF_FLOAT 0x00000004
  708. #define CDF_DOUBLE 0x00000005
  709. #define CDF_CY 0x00000006
  710. -#define CDF_DATE 0x00000007
  711. +#define CDF_DATE 0x00000007
  712. #define CDF_BSTR 0x00000008
  713. #define CDF_DISPATCH 0x00000009
  714. #define CDF_ERROR 0x0000000a
  715. @@ -191,7 +210,7 @@
  716. #define CDF_SIGNED8 0x00000010
  717. #define CDF_UNSIGNED8 0x00000011
  718. #define CDF_UNSIGNED16 0x00000012
  719. -#define CDF_UNSIGNED32 0x00000013
  720. +#define CDF_UNSIGNED32 0x00000013
  721. #define CDF_SIGNED64 0x00000014
  722. #define CDF_UNSIGNED64 0x00000015
  723. #define CDF_INT 0x00000016
  724. @@ -226,7 +245,7 @@
  725. #define CDF_PROPERTY_SUBJECT 0x00000003
  726. #define CDF_PROPERTY_AUTHOR 0x00000004
  727. #define CDF_PROPERTY_KEYWORDS 0x00000005
  728. -#define CDF_PROPERTY_COMMENTS 0x00000006
  729. +#define CDF_PROPERTY_COMMENTS 0x00000006
  730. #define CDF_PROPERTY_TEMPLATE 0x00000007
  731. #define CDF_PROPERTY_LAST_SAVED_BY 0x00000008
  732. #define CDF_PROPERTY_REVISION_NUMBER 0x00000009
  733. @@ -276,19 +295,20 @@
  734. cdf_sat_t *);
  735. int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *,
  736. const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *);
  737. -int cdf_read_property_info(const cdf_stream_t *, uint32_t,
  738. +int cdf_read_property_info(const cdf_stream_t *, const cdf_header_t *, uint32_t,
  739. cdf_property_info_t **, size_t *, size_t *);
  740. int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *,
  741. const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
  742. const cdf_dir_t *, cdf_stream_t *);
  743. -int cdf_unpack_summary_info(const cdf_stream_t *, cdf_summary_info_header_t *,
  744. - cdf_property_info_t **, size_t *);
  745. +int cdf_unpack_summary_info(const cdf_stream_t *, const cdf_header_t *,
  746. + cdf_summary_info_header_t *, cdf_property_info_t **, size_t *);
  747. int cdf_print_classid(char *, size_t, const cdf_classid_t *);
  748. int cdf_print_property_name(char *, size_t, uint32_t);
  749. int cdf_print_elapsed_time(char *, size_t, cdf_timestamp_t);
  750. uint16_t cdf_tole2(uint16_t);
  751. uint32_t cdf_tole4(uint32_t);
  752. uint64_t cdf_tole8(uint64_t);
  753. +char *cdf_ctime(const time_t *);
  754. #ifdef CDF_DEBUG
  755. void cdf_dump_header(const cdf_header_t *);
  756. Index: git/src/cdf_time.c
  757. ===================================================================
  758. --- git.orig/src/cdf_time.c 2012-02-29 20:13:05.341191429 +0100
  759. +++ git/src/cdf_time.c 2012-02-29 20:13:19.726010338 +0100
  760. @@ -27,7 +27,7 @@
  761. #include "file.h"
  762. #ifndef lint
  763. -FILE_RCSID("@(#)$File: cdf_time.c,v 1.8 2009/06/20 20:47:30 christos Exp $")
  764. +FILE_RCSID("@(#)$File: cdf_time.c,v 1.10 2011/02/10 17:03:16 christos Exp $")
  765. #endif
  766. #include <time.h>
  767. @@ -45,12 +45,6 @@
  768. 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  769. };
  770. -#ifdef __DJGPP__
  771. -#define timespec timeval
  772. -#define tv_nsec tv_usec
  773. -#endif
  774. -
  775. -
  776. /*
  777. * Return the number of days between jan 01 1601 and jan 01 of year.
  778. */
  779. @@ -127,7 +121,7 @@
  780. tm.tm_year = (int)(CDF_BASE_YEAR + (t / 365));
  781. rdays = cdf_getdays(tm.tm_year);
  782. - t -= rdays;
  783. + t -= rdays - 1;
  784. tm.tm_mday = cdf_getday(tm.tm_year, (int)t);
  785. tm.tm_mon = cdf_getmonth(tm.tm_year, (int)t);
  786. tm.tm_wday = 0;
  787. @@ -171,6 +165,18 @@
  788. return 0;
  789. }
  790. +char *
  791. +cdf_ctime(const time_t *sec)
  792. +{
  793. + static char ctbuf[26];
  794. + char *ptr = ctime(sec);
  795. + if (ptr != NULL)
  796. + return ptr;
  797. + (void)snprintf(ctbuf, sizeof(ctbuf), "*Bad* 0x%16.16llx\n",
  798. + (long long)*sec);
  799. + return ctbuf;
  800. +}
  801. +
  802. #ifdef TEST
  803. int
  804. @@ -182,7 +188,7 @@
  805. char *p, *q;
  806. cdf_timestamp_to_timespec(&ts, tst);
  807. - p = ctime(&ts.tv_sec);
  808. + p = cdf_ctime(&ts.tv_sec);
  809. if ((q = strchr(p, '\n')) != NULL)
  810. *q = '\0';
  811. if (strcmp(ref, p) != 0)
  812. Index: git/src/readcdf.c
  813. ===================================================================
  814. --- git.orig/src/readcdf.c 2012-02-29 20:13:05.341191429 +0100
  815. +++ git/src/readcdf.c 2012-02-29 20:13:19.726010338 +0100
  816. @@ -26,7 +26,7 @@
  817. #include "file.h"
  818. #ifndef lint
  819. -FILE_RCSID("@(#)$File: readcdf.c,v 1.22 2010/01/20 01:36:55 christos Exp $")
  820. +FILE_RCSID("@(#)$File: readcdf.c,v 1.28 2012/02/17 05:27:45 christos Exp $")
  821. #endif
  822. #include <stdlib.h>
  823. @@ -44,241 +44,275 @@
  824. cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
  825. size_t count)
  826. {
  827. - size_t i;
  828. - cdf_timestamp_t tp;
  829. - struct timespec ts;
  830. - char buf[64];
  831. - const char *str = "vnd.ms-office";
  832. - const char *s;
  833. - int len;
  834. -
  835. - for (i = 0; i < count; i++) {
  836. - cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
  837. - switch (info[i].pi_type) {
  838. - case CDF_NULL:
  839. - break;
  840. - case CDF_SIGNED16:
  841. - if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
  842. - info[i].pi_s16) == -1)
  843. - return -1;
  844. - break;
  845. - case CDF_SIGNED32:
  846. - if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
  847. - info[i].pi_s32) == -1)
  848. - return -1;
  849. - break;
  850. - case CDF_UNSIGNED32:
  851. - if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
  852. - info[i].pi_u32) == -1)
  853. - return -1;
  854. - break;
  855. - case CDF_LENGTH32_STRING:
  856. - case CDF_LENGTH32_WSTRING:
  857. - len = info[i].pi_str.s_len;
  858. - if (len > 1) {
  859. - char vbuf[1024];
  860. - size_t j, k = 1;
  861. -
  862. - if (info[i].pi_type == CDF_LENGTH32_WSTRING)
  863. - k++;
  864. - s = info[i].pi_str.s_buf;
  865. - for (j = 0; j < sizeof(vbuf) && len--;
  866. - j++, s += k) {
  867. - if (*s == '\0')
  868. - break;
  869. - if (isprint((unsigned char)*s))
  870. - vbuf[j] = *s;
  871. - }
  872. - if (j == sizeof(vbuf))
  873. - --j;
  874. - vbuf[j] = '\0';
  875. - if (NOTMIME(ms)) {
  876. - if (vbuf[0]) {
  877. - if (file_printf(ms, ", %s: %s",
  878. - buf, vbuf) == -1)
  879. - return -1;
  880. - }
  881. - } else if (info[i].pi_id ==
  882. - CDF_PROPERTY_NAME_OF_APPLICATION) {
  883. - if (strstr(vbuf, "Word"))
  884. - str = "msword";
  885. - else if (strstr(vbuf, "Excel"))
  886. - str = "vnd.ms-excel";
  887. - else if (strstr(vbuf, "Powerpoint"))
  888. - str = "vnd.ms-powerpoint";
  889. - else if (strstr(vbuf,
  890. - "Crystal Reports"))
  891. - str = "x-rpt";
  892. - }
  893. - }
  894. - break;
  895. - case CDF_FILETIME:
  896. - tp = info[i].pi_tp;
  897. - if (tp != 0) {
  898. - if (tp < 1000000000000000LL) {
  899. - char tbuf[64];
  900. - cdf_print_elapsed_time(tbuf,
  901. - sizeof(tbuf), tp);
  902. - if (NOTMIME(ms) && file_printf(ms,
  903. - ", %s: %s", buf, tbuf) == -1)
  904. - return -1;
  905. - } else {
  906. - char *c, *ec;
  907. - cdf_timestamp_to_timespec(&ts, tp);
  908. - c = ctime(&ts.tv_sec);
  909. - if ((ec = strchr(c, '\n')) != NULL)
  910. - *ec = '\0';
  911. -
  912. - if (NOTMIME(ms) && file_printf(ms,
  913. - ", %s: %s", buf, c) == -1)
  914. - return -1;
  915. - }
  916. - }
  917. - break;
  918. - case CDF_CLIPBOARD:
  919. - break;
  920. - default:
  921. - return -1;
  922. - }
  923. - }
  924. - if (!NOTMIME(ms)) {
  925. - if (file_printf(ms, "application/%s", str) == -1)
  926. - return -1;
  927. - }
  928. - return 1;
  929. + size_t i;
  930. + cdf_timestamp_t tp;
  931. + struct timespec ts;
  932. + char buf[64];
  933. + const char *str = NULL;
  934. + const char *s;
  935. + int len;
  936. +
  937. + for (i = 0; i < count; i++) {
  938. + cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
  939. + switch (info[i].pi_type) {
  940. + case CDF_NULL:
  941. + break;
  942. + case CDF_SIGNED16:
  943. + if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
  944. + info[i].pi_s16) == -1)
  945. + return -1;
  946. + break;
  947. + case CDF_SIGNED32:
  948. + if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
  949. + info[i].pi_s32) == -1)
  950. + return -1;
  951. + break;
  952. + case CDF_UNSIGNED32:
  953. + if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
  954. + info[i].pi_u32) == -1)
  955. + return -1;
  956. + break;
  957. + case CDF_FLOAT:
  958. + if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
  959. + info[i].pi_f) == -1)
  960. + return -1;
  961. + break;
  962. + case CDF_DOUBLE:
  963. + if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
  964. + info[i].pi_d) == -1)
  965. + return -1;
  966. + break;
  967. + case CDF_LENGTH32_STRING:
  968. + case CDF_LENGTH32_WSTRING:
  969. + len = info[i].pi_str.s_len;
  970. + if (len > 1) {
  971. + char vbuf[1024];
  972. + size_t j, k = 1;
  973. +
  974. + if (info[i].pi_type == CDF_LENGTH32_WSTRING)
  975. + k++;
  976. + s = info[i].pi_str.s_buf;
  977. + for (j = 0; j < sizeof(vbuf) && len--;
  978. + j++, s += k) {
  979. + if (*s == '\0')
  980. + break;
  981. + if (isprint((unsigned char)*s))
  982. + vbuf[j] = *s;
  983. + }
  984. + if (j == sizeof(vbuf))
  985. + --j;
  986. + vbuf[j] = '\0';
  987. + if (NOTMIME(ms)) {
  988. + if (vbuf[0]) {
  989. + if (file_printf(ms, ", %s: %s",
  990. + buf, vbuf) == -1)
  991. + return -1;
  992. + }
  993. + } else if (info[i].pi_id ==
  994. + CDF_PROPERTY_NAME_OF_APPLICATION) {
  995. + if (strstr(vbuf, "Word"))
  996. + str = "msword";
  997. + else if (strstr(vbuf, "Excel"))
  998. + str = "vnd.ms-excel";
  999. + else if (strstr(vbuf, "Powerpoint"))
  1000. + str = "vnd.ms-powerpoint";
  1001. + else if (strstr(vbuf,
  1002. + "Crystal Reports"))
  1003. + str = "x-rpt";
  1004. + }
  1005. + }
  1006. + break;
  1007. + case CDF_FILETIME:
  1008. + tp = info[i].pi_tp;
  1009. + if (tp != 0) {
  1010. + if (tp < 1000000000000000LL) {
  1011. + char tbuf[64];
  1012. + cdf_print_elapsed_time(tbuf,
  1013. + sizeof(tbuf), tp);
  1014. + if (NOTMIME(ms) && file_printf(ms,
  1015. + ", %s: %s", buf, tbuf) == -1)
  1016. + return -1;
  1017. + } else {
  1018. + char *c, *ec;
  1019. + cdf_timestamp_to_timespec(&ts, tp);
  1020. + c = cdf_ctime(&ts.tv_sec);
  1021. + if ((ec = strchr(c, '\n')) != NULL)
  1022. + *ec = '\0';
  1023. +
  1024. + if (NOTMIME(ms) && file_printf(ms,
  1025. + ", %s: %s", buf, c) == -1)
  1026. + return -1;
  1027. + }
  1028. + }
  1029. + break;
  1030. + case CDF_CLIPBOARD:
  1031. + break;
  1032. + default:
  1033. + return -1;
  1034. + }
  1035. + }
  1036. + if (!NOTMIME(ms)) {
  1037. + if (str == NULL)
  1038. + return 0;
  1039. + if (file_printf(ms, "application/%s", str) == -1)
  1040. + return -1;
  1041. + }
  1042. + return 1;
  1043. }
  1044. private int
  1045. -cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst)
  1046. +cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
  1047. + const cdf_stream_t *sst)
  1048. {
  1049. - cdf_summary_info_header_t si;
  1050. - cdf_property_info_t *info;
  1051. - size_t count;
  1052. - int m;
  1053. -
  1054. - if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1)
  1055. - return -1;
  1056. -
  1057. - if (NOTMIME(ms)) {
  1058. - if (file_printf(ms, "CDF V2 Document") == -1)
  1059. - return -1;
  1060. -
  1061. - if (file_printf(ms, ", %s Endian",
  1062. - si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
  1063. - return -1;
  1064. - switch (si.si_os) {
  1065. - case 2:
  1066. - if (file_printf(ms, ", Os: Windows, Version %d.%d",
  1067. - si.si_os_version & 0xff,
  1068. - (uint32_t)si.si_os_version >> 8) == -1)
  1069. - return -1;
  1070. - break;
  1071. - case 1:
  1072. - if (file_printf(ms, ", Os: MacOS, Version %d.%d",
  1073. - (uint32_t)si.si_os_version >> 8,
  1074. - si.si_os_version & 0xff) == -1)
  1075. - return -1;
  1076. - break;
  1077. - default:
  1078. - if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
  1079. - si.si_os_version & 0xff,
  1080. - (uint32_t)si.si_os_version >> 8) == -1)
  1081. - return -1;
  1082. - break;
  1083. - }
  1084. - }
  1085. + cdf_summary_info_header_t si;
  1086. + cdf_property_info_t *info;
  1087. + size_t count;
  1088. + int m;
  1089. +
  1090. + if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1)
  1091. + return -1;
  1092. +
  1093. + if (NOTMIME(ms)) {
  1094. + if (file_printf(ms, "Composite Document File V2 Document")
  1095. + == -1)
  1096. + return -1;
  1097. +
  1098. + if (file_printf(ms, ", %s Endian",
  1099. + si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
  1100. + return -2;
  1101. + switch (si.si_os) {
  1102. + case 2:
  1103. + if (file_printf(ms, ", Os: Windows, Version %d.%d",
  1104. + si.si_os_version & 0xff,
  1105. + (uint32_t)si.si_os_version >> 8) == -1)
  1106. + return -2;
  1107. + break;
  1108. + case 1:
  1109. + if (file_printf(ms, ", Os: MacOS, Version %d.%d",
  1110. + (uint32_t)si.si_os_version >> 8,
  1111. + si.si_os_version & 0xff) == -1)
  1112. + return -2;
  1113. + break;
  1114. + default:
  1115. + if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
  1116. + si.si_os_version & 0xff,
  1117. + (uint32_t)si.si_os_version >> 8) == -1)
  1118. + return -2;
  1119. + break;
  1120. + }
  1121. + }
  1122. - m = cdf_file_property_info(ms, info, count);
  1123. - free(info);
  1124. + m = cdf_file_property_info(ms, info, count);
  1125. + free(info);
  1126. - return m;
  1127. + return m == -1 ? -2 : m;
  1128. }
  1129. protected int
  1130. file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
  1131. size_t nbytes)
  1132. {
  1133. - cdf_info_t info;
  1134. - cdf_header_t h;
  1135. - cdf_sat_t sat, ssat;
  1136. - cdf_stream_t sst, scn;
  1137. - cdf_dir_t dir;
  1138. - int i;
  1139. - const char *expn = "";
  1140. - const char *corrupt = "corrupt: ";
  1141. -
  1142. - info.i_fd = fd;
  1143. - info.i_buf = buf;
  1144. - info.i_len = nbytes;
  1145. - if (ms->flags & MAGIC_APPLE)
  1146. - return 0;
  1147. - if (cdf_read_header(&info, &h) == -1)
  1148. - return 0;
  1149. + cdf_info_t info;
  1150. + cdf_header_t h;
  1151. + cdf_sat_t sat, ssat;
  1152. + cdf_stream_t sst, scn;
  1153. + cdf_dir_t dir;
  1154. + int i;
  1155. + const char *expn = "";
  1156. + const char *corrupt = "corrupt: ";
  1157. +
  1158. + info.i_fd = fd;
  1159. + info.i_buf = buf;
  1160. + info.i_len = nbytes;
  1161. + if (ms->flags & MAGIC_APPLE)
  1162. + return 0;
  1163. + if (cdf_read_header(&info, &h) == -1)
  1164. + return 0;
  1165. #ifdef CDF_DEBUG
  1166. - cdf_dump_header(&h);
  1167. + cdf_dump_header(&h);
  1168. #endif
  1169. - if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
  1170. - expn = "Can't read SAT";
  1171. - goto out0;
  1172. - }
  1173. + if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
  1174. + expn = "Can't read SAT";
  1175. + goto out0;
  1176. + }
  1177. #ifdef CDF_DEBUG
  1178. - cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
  1179. + cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
  1180. #endif
  1181. - if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
  1182. - expn = "Can't read SSAT";
  1183. - goto out1;
  1184. - }
  1185. + if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
  1186. + expn = "Can't read SSAT";
  1187. + goto out1;
  1188. + }
  1189. #ifdef CDF_DEBUG
  1190. - cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
  1191. + cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
  1192. #endif
  1193. - if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
  1194. - expn = "Can't read directory";
  1195. - goto out2;
  1196. - }
  1197. -
  1198. - if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
  1199. - expn = "Cannot read short stream";
  1200. - goto out3;
  1201. - }
  1202. + if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
  1203. + expn = "Can't read directory";
  1204. + goto out2;
  1205. + }
  1206. +
  1207. + if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
  1208. + expn = "Cannot read short stream";
  1209. + goto out3;
  1210. + }
  1211. #ifdef CDF_DEBUG
  1212. - cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
  1213. + cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
  1214. #endif
  1215. - if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
  1216. - &scn)) == -1) {
  1217. - if (errno == ESRCH) {
  1218. - corrupt = expn;
  1219. - expn = "No summary info";
  1220. - } else {
  1221. - expn = "Cannot read summary info";
  1222. - }
  1223. - goto out4;
  1224. - }
  1225. + if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
  1226. + &scn)) == -1) {
  1227. + if (errno == ESRCH) {
  1228. + corrupt = expn;
  1229. + expn = "No summary info";
  1230. + } else {
  1231. + expn = "Cannot read summary info";
  1232. + }
  1233. + goto out4;
  1234. + }
  1235. #ifdef CDF_DEBUG
  1236. - cdf_dump_summary_info(&h, &scn);
  1237. + cdf_dump_summary_info(&h, &scn);
  1238. #endif
  1239. - if ((i = cdf_file_summary_info(ms, &scn)) == -1)
  1240. - expn = "Can't expand summary_info";
  1241. - free(scn.sst_tab);
  1242. + if ((i = cdf_file_summary_info(ms, &h, &scn)) < 0)
  1243. + expn = "Can't expand summary_info";
  1244. + if (i == 0) {
  1245. + const char *str = "vnd.ms-office";
  1246. + cdf_directory_t *d;
  1247. + char name[__arraycount(d->d_name)];
  1248. + size_t j, k;
  1249. + for (j = 0; j < dir.dir_len; j++) {
  1250. + d = &dir.dir_tab[j];
  1251. + for (k = 0; k < sizeof(name); k++)
  1252. + name[k] = (char)cdf_tole2(d->d_name[k]);
  1253. + if (strstr(name, "WordDocument") == 0) {
  1254. + str = "msword";
  1255. + break;
  1256. + }
  1257. + }
  1258. + if (file_printf(ms, "application/%s", str) == -1)
  1259. + return -1;
  1260. + i = 1;
  1261. + }
  1262. + free(scn.sst_tab);
  1263. out4:
  1264. - free(sst.sst_tab);
  1265. + free(sst.sst_tab);
  1266. out3:
  1267. - free(dir.dir_tab);
  1268. + free(dir.dir_tab);
  1269. out2:
  1270. - free(ssat.sat_tab);
  1271. + free(ssat.sat_tab);
  1272. out1:
  1273. - free(sat.sat_tab);
  1274. + free(sat.sat_tab);
  1275. out0:
  1276. - if (i != 1) {
  1277. - if (file_printf(ms, "CDF V2 Document") == -1)
  1278. - return -1;
  1279. - if (*expn)
  1280. - if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
  1281. - return -1;
  1282. - i = 1;
  1283. - }
  1284. - return i;
  1285. + if (i != 1) {
  1286. + if (i == -1)
  1287. + if (file_printf(ms, "Composite Document File V2 Document")
  1288. + == -1)
  1289. + return -1;
  1290. + if (*expn)
  1291. + if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
  1292. + return -1;
  1293. + i = 1;
  1294. + }
  1295. + return i;
  1296. }
  1297. Index: git/src/file.h
  1298. ===================================================================
  1299. --- git.orig/src/file.h 2012-02-29 20:13:24.457968395 +0100
  1300. +++ git/src/file.h 2012-02-29 20:13:35.100966457 +0100
  1301. @@ -74,6 +74,10 @@
  1302. #endif
  1303. #define public
  1304. +#ifndef __arraycount
  1305. +#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
  1306. +#endif
  1307. +
  1308. #ifndef __GNUC_PREREQ__
  1309. #ifdef __GNUC__
  1310. #define __GNUC_PREREQ__(x, y) \