readcdf.c (267897) | readcdf.c (275698) |
---|---|
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 --- 12 unchanged lines hidden (view full) --- 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/*- 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 --- 12 unchanged lines hidden (view full) --- 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 |
29FILE_RCSID("@(#)$File: readcdf.c,v 1.44 2014/05/14 23:22:48 christos Exp $") | 29FILE_RCSID("@(#)$File: readcdf.c,v 1.49 2014/12/04 15:56:46 christos Exp $") |
30#endif 31 32#include <assert.h> 33#include <stdlib.h> 34#include <unistd.h> 35#include <string.h> 36#include <time.h> 37#include <ctype.h> | 30#endif 31 32#include <assert.h> 33#include <stdlib.h> 34#include <unistd.h> 35#include <string.h> 36#include <time.h> 37#include <ctype.h> |
38#if defined(HAVE_LOCALE_H) 39#include <locale.h> 40#endif | |
41 42#include "cdf.h" 43#include "magic.h" 44 45#define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0) 46 47static const struct nv { 48 const char *pattern; --- 21 unchanged lines hidden (view full) --- 70 { NULL, NULL, }, 71}; 72 73static const struct cv { 74 uint64_t clsid[2]; 75 const char *mime; 76} clsid2mime[] = { 77 { | 38 39#include "cdf.h" 40#include "magic.h" 41 42#define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0) 43 44static const struct nv { 45 const char *pattern; --- 21 unchanged lines hidden (view full) --- 67 { NULL, NULL, }, 68}; 69 70static const struct cv { 71 uint64_t clsid[2]; 72 const char *mime; 73} clsid2mime[] = { 74 { |
78 { 0x00000000000c1084LLU, 0x46000000000000c0LLU }, | 75 { 0x00000000000c1084ULL, 0x46000000000000c0ULL }, |
79 "x-msi", 80 }, 81 { { 0, 0 }, 82 NULL, 83 }, 84}, clsid2desc[] = { 85 { | 76 "x-msi", 77 }, 78 { { 0, 0 }, 79 NULL, 80 }, 81}, clsid2desc[] = { 82 { |
86 { 0x00000000000c1084LLU, 0x46000000000000c0LLU }, | 83 { 0x00000000000c1084ULL, 0x46000000000000c0ULL }, |
87 "MSI Installer", 88 }, 89 { { 0, 0 }, 90 NULL, 91 }, 92}; 93 94private const char * --- 7 unchanged lines hidden (view full) --- 102 return NULL; 103} 104 105private const char * 106cdf_app_to_mime(const char *vbuf, const struct nv *nv) 107{ 108 size_t i; 109 const char *rv = NULL; | 84 "MSI Installer", 85 }, 86 { { 0, 0 }, 87 NULL, 88 }, 89}; 90 91private const char * --- 7 unchanged lines hidden (view full) --- 99 return NULL; 100} 101 102private const char * 103cdf_app_to_mime(const char *vbuf, const struct nv *nv) 104{ 105 size_t i; 106 const char *rv = NULL; |
110 char *old_lc_ctype; | 107#ifdef USE_C_LOCALE 108 locale_t old_lc_ctype, c_lc_ctype; |
111 | 109 |
112 old_lc_ctype = setlocale(LC_CTYPE, NULL); | 110 c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0); 111 assert(c_lc_ctype != NULL); 112 old_lc_ctype = uselocale(c_lc_ctype); |
113 assert(old_lc_ctype != NULL); | 113 assert(old_lc_ctype != NULL); |
114 old_lc_ctype = strdup(old_lc_ctype); 115 assert(old_lc_ctype != NULL); 116 (void)setlocale(LC_CTYPE, "C"); | 114#endif |
117 for (i = 0; nv[i].pattern != NULL; i++) 118 if (strcasestr(vbuf, nv[i].pattern) != NULL) { 119 rv = nv[i].mime; 120 break; 121 } | 115 for (i = 0; nv[i].pattern != NULL; i++) 116 if (strcasestr(vbuf, nv[i].pattern) != NULL) { 117 rv = nv[i].mime; 118 break; 119 } |
122 (void)setlocale(LC_CTYPE, old_lc_ctype); 123 free(old_lc_ctype); | 120#ifdef USE_C_LOCALE 121 (void)uselocale(old_lc_ctype); 122 freelocale(c_lc_ctype); 123#endif |
124 return rv; 125} 126 127private int 128cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, 129 size_t count, const cdf_directory_t *root_storage) 130{ 131 size_t i; --- 104 unchanged lines hidden (view full) --- 236 return 0; 237 if (file_printf(ms, "application/%s", str) == -1) 238 return -1; 239 } 240 return 1; 241} 242 243private int | 124 return rv; 125} 126 127private int 128cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, 129 size_t count, const cdf_directory_t *root_storage) 130{ 131 size_t i; --- 104 unchanged lines hidden (view full) --- 236 return 0; 237 if (file_printf(ms, "application/%s", str) == -1) 238 return -1; 239 } 240 return 1; 241} 242 243private int |
244cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h, 245 const cdf_stream_t *sst) 246{ 247 cdf_catalog_t *cat; 248 size_t i; 249 char buf[256]; 250 cdf_catalog_entry_t *ce; 251 252 if (NOTMIME(ms)) { 253 if (file_printf(ms, "Microsoft Thumbs.db [") == -1) 254 return -1; 255 if (cdf_unpack_catalog(h, sst, &cat) == -1) 256 return -1; 257 ce = cat->cat_e; 258 /* skip first entry since it has a , or paren */ 259 for (i = 1; i < cat->cat_num; i++) 260 if (file_printf(ms, "%s%s", 261 cdf_u16tos8(buf, ce[i].ce_namlen, ce[i].ce_name), 262 i == cat->cat_num - 1 ? "]" : ", ") == -1) { 263 free(cat); 264 return -1; 265 } 266 free(cat); 267 } else { 268 if (file_printf(ms, "application/CDFV2") == -1) 269 return -1; 270 } 271 return 1; 272} 273 274private int |
|
244cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, 245 const cdf_stream_t *sst, const cdf_directory_t *root_storage) 246{ 247 cdf_summary_info_header_t si; 248 cdf_property_info_t *info; 249 size_t count; 250 int m; 251 --- 28 unchanged lines hidden (view full) --- 280 si.si_os_version & 0xff, 281 (uint32_t)si.si_os_version >> 8) == -1) 282 return -2; 283 break; 284 } 285 if (root_storage) { 286 str = cdf_clsid_to_mime(root_storage->d_storage_uuid, 287 clsid2desc); | 275cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, 276 const cdf_stream_t *sst, const cdf_directory_t *root_storage) 277{ 278 cdf_summary_info_header_t si; 279 cdf_property_info_t *info; 280 size_t count; 281 int m; 282 --- 28 unchanged lines hidden (view full) --- 311 si.si_os_version & 0xff, 312 (uint32_t)si.si_os_version >> 8) == -1) 313 return -2; 314 break; 315 } 316 if (root_storage) { 317 str = cdf_clsid_to_mime(root_storage->d_storage_uuid, 318 clsid2desc); |
288 if (str) | 319 if (str) { |
289 if (file_printf(ms, ", %s", str) == -1) 290 return -2; 291 } 292 } | 320 if (file_printf(ms, ", %s", str) == -1) 321 return -2; 322 } 323 } |
324 } |
|
293 294 m = cdf_file_property_info(ms, info, count, root_storage); 295 free(info); 296 297 return m == -1 ? -2 : m; 298} 299 300#ifdef notdef 301private char * 302format_clsid(char *buf, size_t len, const uint64_t uuid[2]) { 303 snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" 304 PRIx64 "-%.12" PRIx64, | 325 326 m = cdf_file_property_info(ms, info, count, root_storage); 327 free(info); 328 329 return m == -1 ? -2 : m; 330} 331 332#ifdef notdef 333private char * 334format_clsid(char *buf, size_t len, const uint64_t uuid[2]) { 335 snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" 336 PRIx64 "-%.12" PRIx64, |
305 (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffLLU, 306 (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffLLU, 307 (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffLLU, 308 (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffLLU, 309 (uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffLLU); | 337 (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL, 338 (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL, 339 (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL, 340 (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL, 341 (uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffULL); |
310 return buf; 311} 312#endif 313 314protected int 315file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, 316 size_t nbytes) 317{ 318 cdf_info_t info; 319 cdf_header_t h; 320 cdf_sat_t sat, ssat; 321 cdf_stream_t sst, scn; 322 cdf_dir_t dir; 323 int i; 324 const char *expn = ""; 325 const char *corrupt = "corrupt: "; | 342 return buf; 343} 344#endif 345 346protected int 347file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, 348 size_t nbytes) 349{ 350 cdf_info_t info; 351 cdf_header_t h; 352 cdf_sat_t sat, ssat; 353 cdf_stream_t sst, scn; 354 cdf_dir_t dir; 355 int i; 356 const char *expn = ""; 357 const char *corrupt = "corrupt: "; |
358 const cdf_directory_t *root_storage; |
|
326 327 info.i_fd = fd; 328 info.i_buf = buf; 329 info.i_len = nbytes; 330 if (ms->flags & MAGIC_APPLE) 331 return 0; 332 if (cdf_read_header(&info, &h) == -1) 333 return 0; --- 17 unchanged lines hidden (view full) --- 351 cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); 352#endif 353 354 if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) { 355 expn = "Can't read directory"; 356 goto out2; 357 } 358 | 359 360 info.i_fd = fd; 361 info.i_buf = buf; 362 info.i_len = nbytes; 363 if (ms->flags & MAGIC_APPLE) 364 return 0; 365 if (cdf_read_header(&info, &h) == -1) 366 return 0; --- 17 unchanged lines hidden (view full) --- 384 cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); 385#endif 386 387 if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) { 388 expn = "Can't read directory"; 389 goto out2; 390 } 391 |
359 const cdf_directory_t *root_storage; | |
360 if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst, 361 &root_storage)) == -1) { 362 expn = "Cannot read short stream"; 363 goto out3; 364 } 365#ifdef CDF_DEBUG 366 cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); 367#endif --- 31 unchanged lines hidden (view full) --- 399 scn.sst_len = 0; 400 scn.sst_dirlen = 0; 401 } 402 } 403 404 if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, 405 &scn)) == -1) { 406 if (errno == ESRCH) { | 392 if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst, 393 &root_storage)) == -1) { 394 expn = "Cannot read short stream"; 395 goto out3; 396 } 397#ifdef CDF_DEBUG 398 cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); 399#endif --- 31 unchanged lines hidden (view full) --- 431 scn.sst_len = 0; 432 scn.sst_dirlen = 0; 433 } 434 } 435 436 if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, 437 &scn)) == -1) { 438 if (errno == ESRCH) { |
407 corrupt = expn; 408 expn = "No summary info"; | 439 if ((i = cdf_read_catalog(&info, &h, &sat, &ssat, &sst, 440 &dir, &scn)) == -1) { 441 corrupt = expn; 442 if ((i = cdf_read_encrypted_package(&info, &h, 443 &sat, &ssat, &sst, &dir, &scn)) == -1) 444 expn = "No summary info"; 445 else { 446 expn = "Encrypted"; 447 i = -1; 448 } 449 goto out4; 450 } 451#ifdef CDF_DEBUG 452 cdf_dump_catalog(&h, &scn); 453#endif 454 if ((i = cdf_file_catalog(ms, &h, &scn)) 455 < 0) 456 expn = "Can't expand catalog"; |
409 } else { 410 expn = "Cannot read summary info"; 411 } 412 goto out4; 413 } 414#ifdef CDF_DEBUG 415 cdf_dump_summary_info(&h, &scn); 416#endif --- 42 unchanged lines hidden (view full) --- 459 if (NOTMIME(ms)) { 460 if (file_printf(ms, 461 "Composite Document File V2 Document") == -1) 462 return -1; 463 if (*expn) 464 if (file_printf(ms, ", %s%s", corrupt, expn) == -1) 465 return -1; 466 } else { | 457 } else { 458 expn = "Cannot read summary info"; 459 } 460 goto out4; 461 } 462#ifdef CDF_DEBUG 463 cdf_dump_summary_info(&h, &scn); 464#endif --- 42 unchanged lines hidden (view full) --- 507 if (NOTMIME(ms)) { 508 if (file_printf(ms, 509 "Composite Document File V2 Document") == -1) 510 return -1; 511 if (*expn) 512 if (file_printf(ms, ", %s%s", corrupt, expn) == -1) 513 return -1; 514 } else { |
467 if (file_printf(ms, "application/CDFV2-corrupt") == -1) | 515 if (file_printf(ms, "application/CDFV2-%s", 516 *corrupt ? "corrupt" : "encrypted") == -1) |
468 return -1; 469 } 470 i = 1; 471 } 472 return i; 473} | 517 return -1; 518 } 519 i = 1; 520 } 521 return i; 522} |