cdf.c (191739) | cdf.c (192348) |
---|---|
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 --- 18 unchanged lines hidden (view full) --- 27 * Parse composite document files, the format used in Microsoft Office 28 * document files before they switched to zipped xml. 29 * Info from: http://sc.openoffice.org/compdocfileformat.pdf 30 */ 31 32#include "file.h" 33 34#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 --- 18 unchanged lines hidden (view full) --- 27 * Parse composite document files, the format used in Microsoft Office 28 * document files before they switched to zipped xml. 29 * Info from: http://sc.openoffice.org/compdocfileformat.pdf 30 */ 31 32#include "file.h" 33 34#ifndef lint |
35FILE_RCSID("@(#)$File: cdf.c,v 1.17 2009/02/03 20:27:51 christos Exp $") | 35FILE_RCSID("@(#)$File: cdf.c,v 1.30 2009/05/06 14:29:47 christos Exp $") |
36#endif 37 38#include <assert.h> 39#ifdef CDF_DEBUG 40#include <err.h> 41#endif 42#include <stdlib.h> 43#include <unistd.h> --- 7 unchanged lines hidden (view full) --- 51 52#include "cdf.h" 53 54#ifndef __arraycount 55#define __arraycount(a) (sizeof(a) / sizeof(a[0])) 56#endif 57 58#ifdef CDF_DEBUG | 36#endif 37 38#include <assert.h> 39#ifdef CDF_DEBUG 40#include <err.h> 41#endif 42#include <stdlib.h> 43#include <unistd.h> --- 7 unchanged lines hidden (view full) --- 51 52#include "cdf.h" 53 54#ifndef __arraycount 55#define __arraycount(a) (sizeof(a) / sizeof(a[0])) 56#endif 57 58#ifdef CDF_DEBUG |
59#define DPRINTF(a) printf a | 59#define DPRINTF(a) printf a, fflush(stdout) |
60#else 61#define DPRINTF(a) 62#endif 63 64static union { 65 char s[4]; 66 uint32_t u; 67} cdf_bo; --- 154 unchanged lines hidden (view full) --- 222 CDF_UNPACK(d->d_flags); 223 CDF_UNPACK(d->d_created); 224 CDF_UNPACK(d->d_modified); 225 CDF_UNPACK(d->d_stream_first_sector); 226 CDF_UNPACK(d->d_size); 227 CDF_UNPACK(d->d_unused0); 228} 229 | 60#else 61#define DPRINTF(a) 62#endif 63 64static union { 65 char s[4]; 66 uint32_t u; 67} cdf_bo; --- 154 unchanged lines hidden (view full) --- 222 CDF_UNPACK(d->d_flags); 223 CDF_UNPACK(d->d_created); 224 CDF_UNPACK(d->d_modified); 225 CDF_UNPACK(d->d_stream_first_sector); 226 CDF_UNPACK(d->d_size); 227 CDF_UNPACK(d->d_unused0); 228} 229 |
230static int 231cdf_check_stream_offset(const cdf_stream_t *sst, const void *p, size_t tail) 232{ 233 const char *b = (const char *)sst->sst_tab; 234 const char *e = ((const char *)p) + tail; 235 if (e >= b && (size_t)(e - b) < sst->sst_dirlen * sst->sst_len) 236 return 0; 237 DPRINTF((stderr, "offset begin %p end %p %zu >= %zu\n", b, e, 238 (size_t)(e - b), sst->sst_dirlen * sst->sst_len)); 239 errno = EFTYPE; 240 return -1; 241} 242 243static ssize_t 244cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len) 245{ 246 size_t siz = (size_t)off + len; 247 248 if ((off_t)(off + len) != (off_t)siz) { 249 errno = EINVAL; 250 return -1; 251 } 252 253 if (info->i_buf != NULL && info->i_len >= siz) { 254 (void)memcpy(buf, &info->i_buf[off], len); 255 return (ssize_t)len; 256 } 257 258 if (info->i_fd == -1) 259 return -1; 260 261 if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1) 262 return -1; 263 264 if (read(info->i_fd, buf, len) != (ssize_t)len) 265 return -1; 266 267 return (ssize_t)len; 268} 269 |
|
230int | 270int |
231cdf_read_header(int fd, cdf_header_t *h) | 271cdf_read_header(const cdf_info_t *info, cdf_header_t *h) |
232{ | 272{ |
233 (void)memcpy(cdf_bo.s, "\01\02\03\04", 4); | |
234 char buf[512]; | 273 char buf[512]; |
235 if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) | 274 275 (void)memcpy(cdf_bo.s, "\01\02\03\04", 4); 276 if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1) |
236 return -1; | 277 return -1; |
237 if (read(fd, buf, sizeof(buf)) != sizeof(buf)) 238 return -1; | |
239 cdf_unpack_header(h, buf); 240 cdf_swap_header(h); 241 if (h->h_magic != CDF_MAGIC) { | 278 cdf_unpack_header(h, buf); 279 cdf_swap_header(h); 280 if (h->h_magic != CDF_MAGIC) { |
242 DPRINTF(("Bad magic 0x%x != 0x$x\n", h->h_magic, CDF_MAGIC)); 243 errno = EFTYPE; 244 return -1; | 281 DPRINTF(("Bad magic 0x%llx != 0x%llx\n", 282 (unsigned long long)h->h_magic, 283 (unsigned long long)CDF_MAGIC)); 284 goto out; |
245 } | 285 } |
286 if (h->h_sec_size_p2 > 20) { 287 DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2)); 288 goto out; 289 } 290 if (h->h_short_sec_size_p2 > 20) { 291 DPRINTF(("Bad short sector size 0x%u\n", 292 h->h_short_sec_size_p2)); 293 goto out; 294 } |
|
246 return 0; | 295 return 0; |
296out: 297 errno = EFTYPE; 298 return -1; |
|
247} 248 249 250ssize_t | 299} 300 301 302ssize_t |
251cdf_read_sector(int fd, void *buf, size_t offs, size_t len, | 303cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, |
252 const cdf_header_t *h, cdf_secid_t id) 253{ 254 assert((size_t)CDF_SEC_SIZE(h) == len); | 304 const cdf_header_t *h, cdf_secid_t id) 305{ 306 assert((size_t)CDF_SEC_SIZE(h) == len); |
255 if (lseek(fd, (off_t)CDF_SEC_POS(h, id), SEEK_SET) == (off_t)-1) 256 return -1; 257 return read(fd, ((char *)buf) + offs, len); | 307 return cdf_read(info, (off_t)CDF_SEC_POS(h, id), 308 ((char *)buf) + offs, len); |
258} 259 260ssize_t 261cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, 262 size_t len, const cdf_header_t *h, cdf_secid_t id) 263{ 264 assert((size_t)CDF_SHORT_SEC_SIZE(h) == len); 265 (void)memcpy(((char *)buf) + offs, 266 ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len); 267 return len; 268} 269 270/* 271 * Read the sector allocation table. 272 */ 273int | 309} 310 311ssize_t 312cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, 313 size_t len, const cdf_header_t *h, cdf_secid_t id) 314{ 315 assert((size_t)CDF_SHORT_SEC_SIZE(h) == len); 316 (void)memcpy(((char *)buf) + offs, 317 ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len); 318 return len; 319} 320 321/* 322 * Read the sector allocation table. 323 */ 324int |
274cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat) | 325cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) |
275{ 276 size_t i, j, k; 277 size_t ss = CDF_SEC_SIZE(h); | 326{ 327 size_t i, j, k; 328 size_t ss = CDF_SEC_SIZE(h); |
278 cdf_secid_t *msa, mid; | 329 cdf_secid_t *msa, mid, sec; 330 size_t nsatpersec = (ss / sizeof(mid)) - 1; |
279 280 for (i = 0; i < __arraycount(h->h_master_sat); i++) 281 if (h->h_master_sat[i] == CDF_SECID_FREE) 282 break; 283 | 331 332 for (i = 0; i < __arraycount(h->h_master_sat); i++) 333 if (h->h_master_sat[i] == CDF_SECID_FREE) 334 break; 335 |
284 sat->sat_len = (h->h_num_sectors_in_master_sat + i); | 336#define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss)) 337 if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec || 338 i > CDF_SEC_LIMIT) { 339 DPRINTF(("Number of sectors in master SAT too big %u %zu\n", 340 h->h_num_sectors_in_master_sat, i)); 341 errno = EFTYPE; 342 return -1; 343 } 344 345 sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i; 346 DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss)); |
285 if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL) 286 return -1; 287 288 for (i = 0; i < __arraycount(h->h_master_sat); i++) { 289 if (h->h_master_sat[i] < 0) 290 break; | 347 if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL) 348 return -1; 349 350 for (i = 0; i < __arraycount(h->h_master_sat); i++) { 351 if (h->h_master_sat[i] < 0) 352 break; |
291 if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h, | 353 if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h, |
292 h->h_master_sat[i]) != (ssize_t)ss) { 293 DPRINTF(("Reading sector %d", h->h_master_sat[i])); 294 goto out1; 295 } 296 } 297 298 if ((msa = calloc(1, ss)) == NULL) 299 goto out1; 300 301 mid = h->h_secid_first_sector_in_master_sat; 302 for (j = 0; j < h->h_num_sectors_in_master_sat; j++) { | 354 h->h_master_sat[i]) != (ssize_t)ss) { 355 DPRINTF(("Reading sector %d", h->h_master_sat[i])); 356 goto out1; 357 } 358 } 359 360 if ((msa = calloc(1, ss)) == NULL) 361 goto out1; 362 363 mid = h->h_secid_first_sector_in_master_sat; 364 for (j = 0; j < h->h_num_sectors_in_master_sat; j++) { |
365 if (mid < 0) 366 goto out; |
|
303 if (j >= CDF_LOOP_LIMIT) { 304 DPRINTF(("Reading master sector loop limit")); 305 errno = EFTYPE; 306 goto out2; 307 } | 367 if (j >= CDF_LOOP_LIMIT) { 368 DPRINTF(("Reading master sector loop limit")); 369 errno = EFTYPE; 370 goto out2; 371 } |
308 if (cdf_read_sector(fd, msa, 0, ss, h, mid) != (ssize_t)ss) { | 372 if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) { |
309 DPRINTF(("Reading master sector %d", mid)); 310 goto out2; 311 } | 373 DPRINTF(("Reading master sector %d", mid)); 374 goto out2; 375 } |
312 for (k = 0; k < (ss / sizeof(mid)) - 1; k++, i++) 313 if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h, 314 CDF_TOLE4(msa[k])) != (ssize_t)ss) { | 376 for (k = 0; k < nsatpersec; k++, i++) { 377 sec = CDF_TOLE4(msa[k]); 378 if (sec < 0) 379 goto out; 380 if (i >= sat->sat_len) { 381 DPRINTF(("Out of bounds reading MSA %u >= %u", 382 i, sat->sat_len)); 383 errno = EFTYPE; 384 goto out2; 385 } 386 if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h, 387 sec) != (ssize_t)ss) { |
315 DPRINTF(("Reading sector %d", 316 CDF_TOLE4(msa[k]))); 317 goto out2; 318 } | 388 DPRINTF(("Reading sector %d", 389 CDF_TOLE4(msa[k]))); 390 goto out2; 391 } |
319 mid = CDF_TOLE4(msa[(ss / sizeof(mid)) - 1]); | 392 } 393 mid = CDF_TOLE4(msa[nsatpersec]); |
320 } | 394 } |
395out: 396 sat->sat_len = i; |
|
321 free(msa); 322 return 0; 323out2: 324 free(msa); 325out1: 326 free(sat->sat_tab); 327 return -1; 328} 329 330size_t | 397 free(msa); 398 return 0; 399out2: 400 free(msa); 401out1: 402 free(sat->sat_tab); 403 return -1; 404} 405 406size_t |
331cdf_count_chain(const cdf_header_t *h, const cdf_sat_t *sat, 332 cdf_secid_t sid) | 407cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) |
333{ | 408{ |
334 size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t); 335 cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * s); | 409 size_t i, j; 410 cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size); |
336 337 DPRINTF(("Chain:")); 338 for (j = i = 0; sid >= 0; i++, j++) { 339 DPRINTF((" %d", sid)); 340 if (j >= CDF_LOOP_LIMIT) { 341 DPRINTF(("Counting chain loop limit")); 342 errno = EFTYPE; 343 return (size_t)-1; --- 5 unchanged lines hidden (view full) --- 349 } 350 sid = CDF_TOLE4(sat->sat_tab[sid]); 351 } 352 DPRINTF(("\n")); 353 return i; 354} 355 356int | 411 412 DPRINTF(("Chain:")); 413 for (j = i = 0; sid >= 0; i++, j++) { 414 DPRINTF((" %d", sid)); 415 if (j >= CDF_LOOP_LIMIT) { 416 DPRINTF(("Counting chain loop limit")); 417 errno = EFTYPE; 418 return (size_t)-1; --- 5 unchanged lines hidden (view full) --- 424 } 425 sid = CDF_TOLE4(sat->sat_tab[sid]); 426 } 427 DPRINTF(("\n")); 428 return i; 429} 430 431int |
357cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat, 358 cdf_secid_t sid, size_t len, cdf_stream_t *scn) | 432cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h, 433 const cdf_sat_t *sat, cdf_secid_t sid, size_t len, cdf_stream_t *scn) |
359{ 360 size_t ss = CDF_SEC_SIZE(h), i, j; 361 ssize_t nr; | 434{ 435 size_t ss = CDF_SEC_SIZE(h), i, j; 436 ssize_t nr; |
362 scn->sst_len = cdf_count_chain(h, sat, sid); | 437 scn->sst_len = cdf_count_chain(sat, sid, ss); |
363 scn->sst_dirlen = len; 364 365 if (scn->sst_len == (size_t)-1) 366 return -1; 367 368 scn->sst_tab = calloc(scn->sst_len, ss); 369 if (scn->sst_tab == NULL) 370 return -1; 371 372 for (j = i = 0; sid >= 0; i++, j++) { | 438 scn->sst_dirlen = len; 439 440 if (scn->sst_len == (size_t)-1) 441 return -1; 442 443 scn->sst_tab = calloc(scn->sst_len, ss); 444 if (scn->sst_tab == NULL) 445 return -1; 446 447 for (j = i = 0; sid >= 0; i++, j++) { |
373 if ((nr = cdf_read_sector(fd, scn->sst_tab, i * ss, ss, h, | 448 if (j >= CDF_LOOP_LIMIT) { 449 DPRINTF(("Read long sector chain loop limit")); 450 errno = EFTYPE; 451 goto out; 452 } 453 if (i >= scn->sst_len) { 454 DPRINTF(("Out of bounds reading long sector chain " 455 "%u > %u\n", i, scn->sst_len)); 456 errno = EFTYPE; 457 goto out; 458 } 459 if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h, |
374 sid)) != (ssize_t)ss) { 375 if (i == scn->sst_len - 1 && nr > 0) { 376 /* Last sector might be truncated */ 377 return 0; 378 } 379 DPRINTF(("Reading long sector chain %d", sid)); 380 goto out; 381 } 382 sid = CDF_TOLE4(sat->sat_tab[sid]); | 460 sid)) != (ssize_t)ss) { 461 if (i == scn->sst_len - 1 && nr > 0) { 462 /* Last sector might be truncated */ 463 return 0; 464 } 465 DPRINTF(("Reading long sector chain %d", sid)); 466 goto out; 467 } 468 sid = CDF_TOLE4(sat->sat_tab[sid]); |
383 if (j >= CDF_LOOP_LIMIT) { 384 DPRINTF(("Read long sector chain loop limit")); 385 errno = EFTYPE; 386 goto out; 387 } | |
388 } 389 return 0; 390out: 391 free(scn->sst_tab); | 469 } 470 return 0; 471out: 472 free(scn->sst_tab); |
392 return (size_t)-1; | 473 return -1; |
393} 394 395int 396cdf_read_short_sector_chain(const cdf_header_t *h, 397 const cdf_sat_t *ssat, const cdf_stream_t *sst, 398 cdf_secid_t sid, size_t len, cdf_stream_t *scn) 399{ 400 size_t ss = CDF_SHORT_SEC_SIZE(h), i, j; | 474} 475 476int 477cdf_read_short_sector_chain(const cdf_header_t *h, 478 const cdf_sat_t *ssat, const cdf_stream_t *sst, 479 cdf_secid_t sid, size_t len, cdf_stream_t *scn) 480{ 481 size_t ss = CDF_SHORT_SEC_SIZE(h), i, j; |
401 scn->sst_len = cdf_count_chain(h, ssat, sid); | 482 scn->sst_len = cdf_count_chain(ssat, sid, CDF_SEC_SIZE(h)); |
402 scn->sst_dirlen = len; 403 | 483 scn->sst_dirlen = len; 484 |
404 if (scn->sst_len == (size_t)-1) | 485 if (sst->sst_tab == NULL || scn->sst_len == (size_t)-1) |
405 return -1; 406 407 scn->sst_tab = calloc(scn->sst_len, ss); 408 if (scn->sst_tab == NULL) 409 return -1; 410 411 for (j = i = 0; sid >= 0; i++, j++) { 412 if (j >= CDF_LOOP_LIMIT) { 413 DPRINTF(("Read short sector chain loop limit")); 414 errno = EFTYPE; 415 goto out; 416 } | 486 return -1; 487 488 scn->sst_tab = calloc(scn->sst_len, ss); 489 if (scn->sst_tab == NULL) 490 return -1; 491 492 for (j = i = 0; sid >= 0; i++, j++) { 493 if (j >= CDF_LOOP_LIMIT) { 494 DPRINTF(("Read short sector chain loop limit")); 495 errno = EFTYPE; 496 goto out; 497 } |
498 if (i >= scn->sst_len) { 499 DPRINTF(("Out of bounds reading short sector chain " 500 "%u > %u\n", i, scn->sst_len)); 501 errno = EFTYPE; 502 goto out; 503 } |
|
417 if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h, 418 sid) != (ssize_t)ss) { 419 DPRINTF(("Reading short sector chain %d", sid)); 420 goto out; 421 } 422 sid = CDF_TOLE4(ssat->sat_tab[sid]); 423 } 424 return 0; 425out: 426 free(scn->sst_tab); | 504 if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h, 505 sid) != (ssize_t)ss) { 506 DPRINTF(("Reading short sector chain %d", sid)); 507 goto out; 508 } 509 sid = CDF_TOLE4(ssat->sat_tab[sid]); 510 } 511 return 0; 512out: 513 free(scn->sst_tab); |
427 return (size_t)-1; | 514 return -1; |
428} 429 430int | 515} 516 517int |
431cdf_read_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat, 432 const cdf_sat_t *ssat, const cdf_stream_t *sst, | 518cdf_read_sector_chain(const cdf_info_t *info, const cdf_header_t *h, 519 const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, |
433 cdf_secid_t sid, size_t len, cdf_stream_t *scn) 434{ 435 436 if (len < h->h_min_size_standard_stream) 437 return cdf_read_short_sector_chain(h, ssat, sst, sid, len, 438 scn); 439 else | 520 cdf_secid_t sid, size_t len, cdf_stream_t *scn) 521{ 522 523 if (len < h->h_min_size_standard_stream) 524 return cdf_read_short_sector_chain(h, ssat, sst, sid, len, 525 scn); 526 else |
440 return cdf_read_long_sector_chain(fd, h, sat, sid, len, scn); | 527 return cdf_read_long_sector_chain(info, h, sat, sid, len, scn); |
441} 442 443int | 528} 529 530int |
444cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat, 445 cdf_dir_t *dir) | 531cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h, 532 const cdf_sat_t *sat, cdf_dir_t *dir) |
446{ 447 size_t i, j; 448 size_t ss = CDF_SEC_SIZE(h), ns, nd; 449 char *buf; 450 cdf_secid_t sid = h->h_secid_first_directory; 451 | 533{ 534 size_t i, j; 535 size_t ss = CDF_SEC_SIZE(h), ns, nd; 536 char *buf; 537 cdf_secid_t sid = h->h_secid_first_directory; 538 |
452 ns = cdf_count_chain(h, sat, sid); | 539 ns = cdf_count_chain(sat, sid, ss); |
453 if (ns == (size_t)-1) 454 return -1; 455 456 nd = ss / CDF_DIRECTORY_SIZE; 457 458 dir->dir_len = ns * nd; 459 dir->dir_tab = calloc(dir->dir_len, sizeof(dir->dir_tab[0])); 460 if (dir->dir_tab == NULL) --- 5 unchanged lines hidden (view full) --- 466 } 467 468 for (j = i = 0; i < ns; i++, j++) { 469 if (j >= CDF_LOOP_LIMIT) { 470 DPRINTF(("Read dir loop limit")); 471 errno = EFTYPE; 472 goto out; 473 } | 540 if (ns == (size_t)-1) 541 return -1; 542 543 nd = ss / CDF_DIRECTORY_SIZE; 544 545 dir->dir_len = ns * nd; 546 dir->dir_tab = calloc(dir->dir_len, sizeof(dir->dir_tab[0])); 547 if (dir->dir_tab == NULL) --- 5 unchanged lines hidden (view full) --- 553 } 554 555 for (j = i = 0; i < ns; i++, j++) { 556 if (j >= CDF_LOOP_LIMIT) { 557 DPRINTF(("Read dir loop limit")); 558 errno = EFTYPE; 559 goto out; 560 } |
474 if (cdf_read_sector(fd, buf, 0, ss, h, sid) != (ssize_t)ss) { | 561 if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) { |
475 DPRINTF(("Reading directory sector %d", sid)); 476 goto out; 477 } 478 for (j = 0; j < nd; j++) { 479 cdf_unpack_dir(&dir->dir_tab[i * nd + j], 480 &buf[j * CDF_DIRECTORY_SIZE]); 481 } 482 sid = CDF_TOLE4(sat->sat_tab[sid]); --- 6 unchanged lines hidden (view full) --- 489out: 490 free(dir->dir_tab); 491 free(buf); 492 return -1; 493} 494 495 496int | 562 DPRINTF(("Reading directory sector %d", sid)); 563 goto out; 564 } 565 for (j = 0; j < nd; j++) { 566 cdf_unpack_dir(&dir->dir_tab[i * nd + j], 567 &buf[j * CDF_DIRECTORY_SIZE]); 568 } 569 sid = CDF_TOLE4(sat->sat_tab[sid]); --- 6 unchanged lines hidden (view full) --- 576out: 577 free(dir->dir_tab); 578 free(buf); 579 return -1; 580} 581 582 583int |
497cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat, 498 cdf_sat_t *ssat) | 584cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h, 585 const cdf_sat_t *sat, cdf_sat_t *ssat) |
499{ 500 size_t i, j; 501 size_t ss = CDF_SEC_SIZE(h); 502 cdf_secid_t sid = h->h_secid_first_sector_in_short_sat; 503 | 586{ 587 size_t i, j; 588 size_t ss = CDF_SEC_SIZE(h); 589 cdf_secid_t sid = h->h_secid_first_sector_in_short_sat; 590 |
504 ssat->sat_len = cdf_count_chain(h, sat, sid); | 591 ssat->sat_len = cdf_count_chain(sat, sid, CDF_SEC_SIZE(h)); |
505 if (ssat->sat_len == (size_t)-1) 506 return -1; 507 508 ssat->sat_tab = calloc(ssat->sat_len, ss); 509 if (ssat->sat_tab == NULL) 510 return -1; 511 512 for (j = i = 0; sid >= 0; i++, j++) { 513 if (j >= CDF_LOOP_LIMIT) { 514 DPRINTF(("Read short sat sector loop limit")); 515 errno = EFTYPE; 516 goto out; 517 } | 592 if (ssat->sat_len == (size_t)-1) 593 return -1; 594 595 ssat->sat_tab = calloc(ssat->sat_len, ss); 596 if (ssat->sat_tab == NULL) 597 return -1; 598 599 for (j = i = 0; sid >= 0; i++, j++) { 600 if (j >= CDF_LOOP_LIMIT) { 601 DPRINTF(("Read short sat sector loop limit")); 602 errno = EFTYPE; 603 goto out; 604 } |
518 if (cdf_read_sector(fd, ssat->sat_tab, i * ss, ss, h, sid) != | 605 if (i >= ssat->sat_len) { 606 DPRINTF(("Out of bounds reading short sector chain " 607 "%u > %u\n", i, ssat->sat_len)); 608 errno = EFTYPE; 609 goto out; 610 } 611 if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) != |
519 (ssize_t)ss) { 520 DPRINTF(("Reading short sat sector %d", sid)); 521 goto out; 522 } 523 sid = CDF_TOLE4(sat->sat_tab[sid]); 524 } 525 return 0; 526out: 527 free(ssat->sat_tab); 528 return -1; 529} 530 531int | 612 (ssize_t)ss) { 613 DPRINTF(("Reading short sat sector %d", sid)); 614 goto out; 615 } 616 sid = CDF_TOLE4(sat->sat_tab[sid]); 617 } 618 return 0; 619out: 620 free(ssat->sat_tab); 621 return -1; 622} 623 624int |
532cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat, 533 const cdf_dir_t *dir, cdf_stream_t *scn) | 625cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, 626 const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn) |
534{ 535 size_t i; 536 const cdf_directory_t *d; 537 538 for (i = 0; i < dir->dir_len; i++) 539 if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE) 540 break; 541 | 627{ 628 size_t i; 629 const cdf_directory_t *d; 630 631 for (i = 0; i < dir->dir_len; i++) 632 if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE) 633 break; 634 |
542 if (i == dir->dir_len) { 543 DPRINTF(("Cannot find root storage node\n")); 544 errno = EFTYPE; 545 return -1; 546 } | 635 /* If the it is not there, just fake it; some docs don't have it */ 636 if (i == dir->dir_len) 637 goto out; |
547 d = &dir->dir_tab[i]; 548 549 /* If the it is not there, just fake it; some docs don't have it */ | 638 d = &dir->dir_tab[i]; 639 640 /* If the it is not there, just fake it; some docs don't have it */ |
550 if (d->d_stream_first_sector < 0) { 551 scn->sst_tab = NULL; 552 scn->sst_len = 0; 553 return 0; 554 } | 641 if (d->d_stream_first_sector < 0) 642 goto out; |
555 | 643 |
556 return cdf_read_long_sector_chain(fd, h, sat, | 644 return cdf_read_long_sector_chain(info, h, sat, |
557 d->d_stream_first_sector, d->d_size, scn); | 645 d->d_stream_first_sector, d->d_size, scn); |
646out: 647 scn->sst_tab = NULL; 648 scn->sst_len = 0; 649 scn->sst_dirlen = 0; 650 return 0; |
|
558} 559 560static int 561cdf_namecmp(const char *d, const uint16_t *s, size_t l) 562{ 563 for (; l--; d++, s++) 564 if (*d != CDF_TOLE2(*s)) 565 return (unsigned char)*d - CDF_TOLE2(*s); 566 return 0; 567} 568 569int | 651} 652 653static int 654cdf_namecmp(const char *d, const uint16_t *s, size_t l) 655{ 656 for (; l--; d++, s++) 657 if (*d != CDF_TOLE2(*s)) 658 return (unsigned char)*d - CDF_TOLE2(*s); 659 return 0; 660} 661 662int |
570cdf_read_summary_info(int fd, const cdf_header_t *h, | 663cdf_read_summary_info(const cdf_info_t *info, const cdf_header_t *h, |
571 const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, 572 const cdf_dir_t *dir, cdf_stream_t *scn) 573{ 574 size_t i; 575 const cdf_directory_t *d; 576 static const char name[] = "\05SummaryInformation"; 577 578 for (i = 0; i < dir->dir_len; i++) 579 if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_USER_STREAM && 580 cdf_namecmp(name, dir->dir_tab[i].d_name, sizeof(name)) 581 == 0) 582 break; 583 584 if (i == dir->dir_len) { 585 DPRINTF(("Cannot find summary information section\n")); 586 errno = EFTYPE; 587 return -1; 588 } 589 d = &dir->dir_tab[i]; | 664 const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, 665 const cdf_dir_t *dir, cdf_stream_t *scn) 666{ 667 size_t i; 668 const cdf_directory_t *d; 669 static const char name[] = "\05SummaryInformation"; 670 671 for (i = 0; i < dir->dir_len; i++) 672 if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_USER_STREAM && 673 cdf_namecmp(name, dir->dir_tab[i].d_name, sizeof(name)) 674 == 0) 675 break; 676 677 if (i == dir->dir_len) { 678 DPRINTF(("Cannot find summary information section\n")); 679 errno = EFTYPE; 680 return -1; 681 } 682 d = &dir->dir_tab[i]; |
590 return cdf_read_sector_chain(fd, h, sat, ssat, sst, | 683 return cdf_read_sector_chain(info, h, sat, ssat, sst, |
591 d->d_stream_first_sector, d->d_size, scn); 592} 593 594int 595cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, 596 cdf_property_info_t **info, size_t *count, size_t *maxcount) 597{ 598 const cdf_section_header_t *shp; 599 cdf_section_header_t sh; 600 const uint32_t *p, *q, *e; 601 int16_t s16; 602 int32_t s32; 603 uint32_t u32; 604 int64_t s64; 605 uint64_t u64; 606 cdf_timestamp_t tp; 607 size_t i, o, nelements, j; 608 cdf_property_info_t *inp; 609 | 684 d->d_stream_first_sector, d->d_size, scn); 685} 686 687int 688cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, 689 cdf_property_info_t **info, size_t *count, size_t *maxcount) 690{ 691 const cdf_section_header_t *shp; 692 cdf_section_header_t sh; 693 const uint32_t *p, *q, *e; 694 int16_t s16; 695 int32_t s32; 696 uint32_t u32; 697 int64_t s64; 698 uint64_t u64; 699 cdf_timestamp_t tp; 700 size_t i, o, nelements, j; 701 cdf_property_info_t *inp; 702 |
703 if (offs > UINT32_MAX / 4) { 704 errno = EFTYPE; 705 goto out; 706 } |
|
610 shp = (const void *)((const char *)sst->sst_tab + offs); | 707 shp = (const void *)((const char *)sst->sst_tab + offs); |
708 if (cdf_check_stream_offset(sst, shp, sizeof(*shp)) == -1) 709 goto out; |
|
611 sh.sh_len = CDF_TOLE4(shp->sh_len); | 710 sh.sh_len = CDF_TOLE4(shp->sh_len); |
711#define CDF_SHLEN_LIMIT (UINT32_MAX / 8) 712 if (sh.sh_len > CDF_SHLEN_LIMIT) { 713 errno = EFTYPE; 714 goto out; 715 } |
|
612 sh.sh_properties = CDF_TOLE4(shp->sh_properties); | 716 sh.sh_properties = CDF_TOLE4(shp->sh_properties); |
613 DPRINTF(("section len: %d properties %d\n", sh.sh_len, | 717#define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(*inp))) 718 if (sh.sh_properties > CDF_PROP_LIMIT) 719 goto out; 720 DPRINTF(("section len: %u properties %u\n", sh.sh_len, |
614 sh.sh_properties)); 615 if (*maxcount) { | 721 sh.sh_properties)); 722 if (*maxcount) { |
723 if (*maxcount > CDF_PROP_LIMIT) 724 goto out; |
|
616 *maxcount += sh.sh_properties; 617 inp = realloc(*info, *maxcount * sizeof(*inp)); 618 } else { 619 *maxcount = sh.sh_properties; 620 inp = malloc(*maxcount * sizeof(*inp)); 621 } 622 if (inp == NULL) 623 goto out; 624 *info = inp; 625 inp += *count; 626 *count += sh.sh_properties; 627 p = (const void *)((const char *)sst->sst_tab + offs + sizeof(sh)); 628 e = (const void *)(((const char *)shp) + sh.sh_len); | 725 *maxcount += sh.sh_properties; 726 inp = realloc(*info, *maxcount * sizeof(*inp)); 727 } else { 728 *maxcount = sh.sh_properties; 729 inp = malloc(*maxcount * sizeof(*inp)); 730 } 731 if (inp == NULL) 732 goto out; 733 *info = inp; 734 inp += *count; 735 *count += sh.sh_properties; 736 p = (const void *)((const char *)sst->sst_tab + offs + sizeof(sh)); 737 e = (const void *)(((const char *)shp) + sh.sh_len); |
738 if (cdf_check_stream_offset(sst, e, 0) == -1) 739 goto out; |
|
629 for (i = 0; i < sh.sh_properties; i++) { 630 q = (const uint32_t *)((const char *)p + 631 CDF_TOLE4(p[(i << 1) + 1])) - 2; 632 if (q > e) { 633 DPRINTF(("Ran of the end %p > %p\n", q, e)); 634 goto out; 635 } 636 inp[i].pi_id = CDF_TOLE4(p[i << 1]); --- 41 unchanged lines hidden (view full) --- 678 if (inp[i].pi_type & CDF_VECTOR) 679 goto unknown; 680 (void)memcpy(&u64, &q[o], sizeof(u64)); 681 inp[i].pi_u64 = CDF_TOLE4(u64); 682 break; 683 case CDF_LENGTH32_STRING: 684 if (nelements > 1) { 685 size_t nelem = inp - *info; | 740 for (i = 0; i < sh.sh_properties; i++) { 741 q = (const uint32_t *)((const char *)p + 742 CDF_TOLE4(p[(i << 1) + 1])) - 2; 743 if (q > e) { 744 DPRINTF(("Ran of the end %p > %p\n", q, e)); 745 goto out; 746 } 747 inp[i].pi_id = CDF_TOLE4(p[i << 1]); --- 41 unchanged lines hidden (view full) --- 789 if (inp[i].pi_type & CDF_VECTOR) 790 goto unknown; 791 (void)memcpy(&u64, &q[o], sizeof(u64)); 792 inp[i].pi_u64 = CDF_TOLE4(u64); 793 break; 794 case CDF_LENGTH32_STRING: 795 if (nelements > 1) { 796 size_t nelem = inp - *info; |
797 if (*maxcount > CDF_PROP_LIMIT 798 || nelements > CDF_PROP_LIMIT) 799 goto out; |
|
686 *maxcount += nelements; 687 inp = realloc(*info, *maxcount * sizeof(*inp)); 688 if (inp == NULL) 689 goto out; 690 *info = inp; 691 inp = *info + nelem; 692 } 693 DPRINTF(("nelements = %d\n", nelements)); --- 36 unchanged lines hidden (view full) --- 730cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi, 731 cdf_property_info_t **info, size_t *count) 732{ 733 size_t i, maxcount; 734 const cdf_summary_info_header_t *si = sst->sst_tab; 735 const cdf_section_declaration_t *sd = (const void *) 736 ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET); 737 | 800 *maxcount += nelements; 801 inp = realloc(*info, *maxcount * sizeof(*inp)); 802 if (inp == NULL) 803 goto out; 804 *info = inp; 805 inp = *info + nelem; 806 } 807 DPRINTF(("nelements = %d\n", nelements)); --- 36 unchanged lines hidden (view full) --- 844cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi, 845 cdf_property_info_t **info, size_t *count) 846{ 847 size_t i, maxcount; 848 const cdf_summary_info_header_t *si = sst->sst_tab; 849 const cdf_section_declaration_t *sd = (const void *) 850 ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET); 851 |
852 if (cdf_check_stream_offset(sst, si, sizeof(*si)) == -1 || 853 cdf_check_stream_offset(sst, sd, sizeof(*sd)) == -1) 854 return -1; |
|
738 ssi->si_byte_order = CDF_TOLE2(si->si_byte_order); 739 ssi->si_os_version = CDF_TOLE2(si->si_os_version); 740 ssi->si_os = CDF_TOLE2(si->si_os); 741 ssi->si_class = si->si_class; 742 cdf_swap_class(&ssi->si_class); 743 ssi->si_count = CDF_TOLE2(si->si_count); 744 *count = 0; 745 maxcount = 0; --- 97 unchanged lines hidden (view full) --- 843 844 845#ifdef CDF_DEBUG 846void 847cdf_dump_header(const cdf_header_t *h) 848{ 849 size_t i; 850 | 855 ssi->si_byte_order = CDF_TOLE2(si->si_byte_order); 856 ssi->si_os_version = CDF_TOLE2(si->si_os_version); 857 ssi->si_os = CDF_TOLE2(si->si_os); 858 ssi->si_class = si->si_class; 859 cdf_swap_class(&ssi->si_class); 860 ssi->si_count = CDF_TOLE2(si->si_count); 861 *count = 0; 862 maxcount = 0; --- 97 unchanged lines hidden (view full) --- 960 961 962#ifdef CDF_DEBUG 963void 964cdf_dump_header(const cdf_header_t *h) 965{ 966 size_t i; 967 |
851#define DUMP(a, b) printf("%40.40s = " a "\n", # b, h->h_ ## b) | 968#define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b) 969#define DUMP2(a, b) (void)fprintf(stderr, "%40.40s = " a " (" a ")\n", # b, \ 970 h->h_ ## b, 1 << h->h_ ## b) |
852 DUMP("%d", revision); 853 DUMP("%d", version); 854 DUMP("0x%x", byte_order); | 971 DUMP("%d", revision); 972 DUMP("%d", version); 973 DUMP("0x%x", byte_order); |
855 DUMP("%d", sec_size_p2); 856 DUMP("%d", short_sec_size_p2); | 974 DUMP2("%d", sec_size_p2); 975 DUMP2("%d", short_sec_size_p2); |
857 DUMP("%d", num_sectors_in_sat); 858 DUMP("%d", secid_first_directory); 859 DUMP("%d", min_size_standard_stream); 860 DUMP("%d", secid_first_sector_in_short_sat); 861 DUMP("%d", num_sectors_in_short_sat); 862 DUMP("%d", secid_first_sector_in_master_sat); 863 DUMP("%d", num_sectors_in_master_sat); 864 for (i = 0; i < __arraycount(h->h_master_sat); i++) { 865 if (h->h_master_sat[i] == CDF_SECID_FREE) 866 break; | 976 DUMP("%d", num_sectors_in_sat); 977 DUMP("%d", secid_first_directory); 978 DUMP("%d", min_size_standard_stream); 979 DUMP("%d", secid_first_sector_in_short_sat); 980 DUMP("%d", num_sectors_in_short_sat); 981 DUMP("%d", secid_first_sector_in_master_sat); 982 DUMP("%d", num_sectors_in_master_sat); 983 for (i = 0; i < __arraycount(h->h_master_sat); i++) { 984 if (h->h_master_sat[i] == CDF_SECID_FREE) 985 break; |
867 printf("%35.35s[%.3zu] = %d\n", | 986 (void)fprintf(stderr, "%35.35s[%.3zu] = %d\n", |
868 "master_sat", i, h->h_master_sat[i]); 869 } 870} 871 872void | 987 "master_sat", i, h->h_master_sat[i]); 988 } 989} 990 991void |
873cdf_dump_sat(const char *prefix, const cdf_header_t *h, const cdf_sat_t *sat) | 992cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size) |
874{ | 993{ |
875 size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t); | 994 size_t i, j, s = size / sizeof(cdf_secid_t); |
876 877 for (i = 0; i < sat->sat_len; i++) { | 995 996 for (i = 0; i < sat->sat_len; i++) { |
878 printf("%s[%zu]:\n", prefix, i); | 997 (void)fprintf(stderr, "%s[%zu]:\n%.6d: ", prefix, i, i * s); |
879 for (j = 0; j < s; j++) { | 998 for (j = 0; j < s; j++) { |
880 printf("%5d, ", CDF_TOLE4(sat->sat_tab[s * i + j])); | 999 (void)fprintf(stderr, "%5d, ", 1000 CDF_TOLE4(sat->sat_tab[s * i + j])); |
881 if ((j + 1) % 10 == 0) | 1001 if ((j + 1) % 10 == 0) |
882 printf("\n"); | 1002 (void)fprintf(stderr, "\n%.6d: ", 1003 i * s + j + 1); |
883 } | 1004 } |
884 printf("\n"); | 1005 (void)fprintf(stderr, "\n"); |
885 } 886} 887 888void 889cdf_dump(void *v, size_t len) 890{ 891 size_t i, j; 892 unsigned char *p = v; 893 char abuf[16]; | 1006 } 1007} 1008 1009void 1010cdf_dump(void *v, size_t len) 1011{ 1012 size_t i, j; 1013 unsigned char *p = v; 1014 char abuf[16]; |
894 printf("%.4x: ", 0); | 1015 (void)fprintf(stderr, "%.4x: ", 0); |
895 for (i = 0, j = 0; i < len; i++, p++) { | 1016 for (i = 0, j = 0; i < len; i++, p++) { |
896 printf("%.2x ", *p); | 1017 (void)fprintf(stderr, "%.2x ", *p); |
897 abuf[j++] = isprint(*p) ? *p : '.'; 898 if (j == 16) { 899 j = 0; 900 abuf[15] = '\0'; | 1018 abuf[j++] = isprint(*p) ? *p : '.'; 1019 if (j == 16) { 1020 j = 0; 1021 abuf[15] = '\0'; |
901 printf("%s\n%.4x: ", abuf, i + 1); | 1022 (void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1); |
902 } 903 } | 1023 } 1024 } |
904 printf("\n"); | 1025 (void)fprintf(stderr, "\n"); |
905} 906 907void 908cdf_dump_stream(const cdf_header_t *h, const cdf_stream_t *sst) 909{ 910 size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? 911 CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); 912 cdf_dump(sst->sst_tab, ss * sst->sst_len); 913} 914 915void | 1026} 1027 1028void 1029cdf_dump_stream(const cdf_header_t *h, const cdf_stream_t *sst) 1030{ 1031 size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? 1032 CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); 1033 cdf_dump(sst->sst_tab, ss * sst->sst_len); 1034} 1035 1036void |
916cdf_dump_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat, 917 const cdf_sat_t *ssat, const cdf_stream_t *sst, | 1037cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h, 1038 const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, |
918 const cdf_dir_t *dir) 919{ 920 size_t i, j; 921 cdf_directory_t *d; 922 char name[__arraycount(d->d_name)]; 923 cdf_stream_t scn; 924 struct timespec ts; 925 926 static const char *types[] = { "empty", "user storage", 927 "user stream", "lockbytes", "property", "root storage" }; 928 929 for (i = 0; i < dir->dir_len; i++) { 930 d = &dir->dir_tab[i]; 931 for (j = 0; j < sizeof(name); j++) 932 name[j] = (char)CDF_TOLE2(d->d_name[j]); | 1039 const cdf_dir_t *dir) 1040{ 1041 size_t i, j; 1042 cdf_directory_t *d; 1043 char name[__arraycount(d->d_name)]; 1044 cdf_stream_t scn; 1045 struct timespec ts; 1046 1047 static const char *types[] = { "empty", "user storage", 1048 "user stream", "lockbytes", "property", "root storage" }; 1049 1050 for (i = 0; i < dir->dir_len; i++) { 1051 d = &dir->dir_tab[i]; 1052 for (j = 0; j < sizeof(name); j++) 1053 name[j] = (char)CDF_TOLE2(d->d_name[j]); |
933 printf("Directory %zu: %s\n", i, name); | 1054 (void)fprintf(stderr, "Directory %zu: %s\n", i, name); |
934 if (d->d_type < __arraycount(types)) | 1055 if (d->d_type < __arraycount(types)) |
935 printf("Type: %s\n", types[d->d_type]); | 1056 (void)fprintf(stderr, "Type: %s\n", types[d->d_type]); |
936 else | 1057 else |
937 printf("Type: %d\n", d->d_type); 938 printf("Color: %s\n", d->d_color ? "black" : "red"); 939 printf("Left child: %d\n", d->d_left_child); 940 printf("Right child: %d\n", d->d_right_child); 941 printf("Flags: 0x%x\n", d->d_flags); | 1058 (void)fprintf(stderr, "Type: %d\n", d->d_type); 1059 (void)fprintf(stderr, "Color: %s\n", 1060 d->d_color ? "black" : "red"); 1061 (void)fprintf(stderr, "Left child: %d\n", d->d_left_child); 1062 (void)fprintf(stderr, "Right child: %d\n", d->d_right_child); 1063 (void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags); |
942 cdf_timestamp_to_timespec(&ts, d->d_created); | 1064 cdf_timestamp_to_timespec(&ts, d->d_created); |
943 printf("Created %s", ctime(&ts.tv_sec)); | 1065 (void)fprintf(stderr, "Created %s", ctime(&ts.tv_sec)); |
944 cdf_timestamp_to_timespec(&ts, d->d_modified); | 1066 cdf_timestamp_to_timespec(&ts, d->d_modified); |
945 printf("Modified %s", ctime(&ts.tv_sec)); 946 printf("Stream %d\n", d->d_stream_first_sector); 947 printf("Size %d\n", d->d_size); | 1067 (void)fprintf(stderr, "Modified %s", ctime(&ts.tv_sec)); 1068 (void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector); 1069 (void)fprintf(stderr, "Size %d\n", d->d_size); |
948 switch (d->d_type) { 949 case CDF_DIR_TYPE_USER_STORAGE: | 1070 switch (d->d_type) { 1071 case CDF_DIR_TYPE_USER_STORAGE: |
950 printf("Storage: %d\n", d->d_storage); | 1072 (void)fprintf(stderr, "Storage: %d\n", d->d_storage); |
951 break; 952 case CDF_DIR_TYPE_USER_STREAM: 953 if (sst == NULL) 954 break; | 1073 break; 1074 case CDF_DIR_TYPE_USER_STREAM: 1075 if (sst == NULL) 1076 break; |
955 if (cdf_read_sector_chain(fd, h, sat, ssat, sst, | 1077 if (cdf_read_sector_chain(info, h, sat, ssat, sst, |
956 d->d_stream_first_sector, d->d_size, &scn) == -1) { 957 warn("Can't read stream for %s at %d len %d", 958 name, d->d_stream_first_sector, d->d_size); 959 break; 960 } 961 cdf_dump_stream(h, &scn); 962 free(scn.sst_tab); 963 break; --- 9 unchanged lines hidden (view full) --- 973{ 974 cdf_timestamp_t tp; 975 struct timespec ts; 976 char buf[64]; 977 size_t i; 978 979 for (i = 0; i < count; i++) { 980 cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); | 1078 d->d_stream_first_sector, d->d_size, &scn) == -1) { 1079 warn("Can't read stream for %s at %d len %d", 1080 name, d->d_stream_first_sector, d->d_size); 1081 break; 1082 } 1083 cdf_dump_stream(h, &scn); 1084 free(scn.sst_tab); 1085 break; --- 9 unchanged lines hidden (view full) --- 1095{ 1096 cdf_timestamp_t tp; 1097 struct timespec ts; 1098 char buf[64]; 1099 size_t i; 1100 1101 for (i = 0; i < count; i++) { 1102 cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); |
981 printf("%zu) %s: ", i, buf); | 1103 (void)fprintf(stderr, "%zu) %s: ", i, buf); |
982 switch (info[i].pi_type) { 983 case CDF_SIGNED16: | 1104 switch (info[i].pi_type) { 1105 case CDF_SIGNED16: |
984 printf("signed 16 [%hd]\n", info[i].pi_s16); | 1106 (void)fprintf(stderr, "signed 16 [%hd]\n", 1107 info[i].pi_s16); |
985 break; 986 case CDF_SIGNED32: | 1108 break; 1109 case CDF_SIGNED32: |
987 printf("signed 32 [%d]\n", info[i].pi_s32); | 1110 (void)fprintf(stderr, "signed 32 [%d]\n", 1111 info[i].pi_s32); |
988 break; 989 case CDF_UNSIGNED32: | 1112 break; 1113 case CDF_UNSIGNED32: |
990 printf("unsigned 32 [%u]\n", info[i].pi_u32); | 1114 (void)fprintf(stderr, "unsigned 32 [%u]\n", 1115 info[i].pi_u32); |
991 break; 992 case CDF_LENGTH32_STRING: | 1116 break; 1117 case CDF_LENGTH32_STRING: |
993 printf("string %u [%.*s]\n", info[i].pi_str.s_len, | 1118 (void)fprintf(stderr, "string %u [%.*s]\n", 1119 info[i].pi_str.s_len, |
994 info[i].pi_str.s_len, info[i].pi_str.s_buf); 995 break; 996 case CDF_FILETIME: 997 tp = info[i].pi_tp; 998 if (tp < 1000000000000000LL) { 999 cdf_print_elapsed_time(buf, sizeof(buf), tp); | 1120 info[i].pi_str.s_len, info[i].pi_str.s_buf); 1121 break; 1122 case CDF_FILETIME: 1123 tp = info[i].pi_tp; 1124 if (tp < 1000000000000000LL) { 1125 cdf_print_elapsed_time(buf, sizeof(buf), tp); |
1000 printf("timestamp %s\n", buf); | 1126 (void)fprintf(stderr, "timestamp %s\n", buf); |
1001 } else { 1002 cdf_timestamp_to_timespec(&ts, tp); | 1127 } else { 1128 cdf_timestamp_to_timespec(&ts, tp); |
1003 printf("timestamp %s", ctime(&ts.tv_sec)); | 1129 (void)fprintf(stderr, "timestamp %s", 1130 ctime(&ts.tv_sec)); |
1004 } 1005 break; 1006 case CDF_CLIPBOARD: | 1131 } 1132 break; 1133 case CDF_CLIPBOARD: |
1007 printf("CLIPBOARD %u\n", info[i].pi_u32); | 1134 (void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32); |
1008 break; 1009 default: 1010 DPRINTF(("Don't know how to deal with %x\n", 1011 info[i].pi_type)); 1012 break; 1013 } 1014 } 1015} --- 5 unchanged lines hidden (view full) --- 1021 char buf[128]; 1022 cdf_summary_info_header_t ssi; 1023 cdf_property_info_t *info; 1024 size_t count; 1025 1026 (void)&h; 1027 if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1) 1028 return; | 1135 break; 1136 default: 1137 DPRINTF(("Don't know how to deal with %x\n", 1138 info[i].pi_type)); 1139 break; 1140 } 1141 } 1142} --- 5 unchanged lines hidden (view full) --- 1148 char buf[128]; 1149 cdf_summary_info_header_t ssi; 1150 cdf_property_info_t *info; 1151 size_t count; 1152 1153 (void)&h; 1154 if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1) 1155 return; |
1029 printf("Endian: %x\n", ssi.si_byte_order); 1030 printf("Os Version %d.%d\n", ssi.si_os_version & 0xff, | 1156 (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order); 1157 (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff, |
1031 ssi.si_os_version >> 8); | 1158 ssi.si_os_version >> 8); |
1032 printf("Os %d\n", ssi.si_os); | 1159 (void)fprintf(stderr, "Os %d\n", ssi.si_os); |
1033 cdf_print_classid(buf, sizeof(buf), &ssi.si_class); | 1160 cdf_print_classid(buf, sizeof(buf), &ssi.si_class); |
1034 printf("Class %s\n", buf); 1035 printf("Count %d\n", ssi.si_count); | 1161 (void)fprintf(stderr, "Class %s\n", buf); 1162 (void)fprintf(stderr, "Count %d\n", ssi.si_count); |
1036 cdf_dump_property_info(info, count); 1037 free(info); 1038} 1039 1040#endif 1041 1042#ifdef TEST 1043int 1044main(int argc, char *argv[]) 1045{ | 1163 cdf_dump_property_info(info, count); 1164 free(info); 1165} 1166 1167#endif 1168 1169#ifdef TEST 1170int 1171main(int argc, char *argv[]) 1172{ |
1046 int fd, i; | 1173 int i; |
1047 cdf_header_t h; 1048 cdf_sat_t sat, ssat; 1049 cdf_stream_t sst, scn; 1050 cdf_dir_t dir; | 1174 cdf_header_t h; 1175 cdf_sat_t sat, ssat; 1176 cdf_stream_t sst, scn; 1177 cdf_dir_t dir; |
1178 cdf_info_t info; |
|
1051 1052 if (argc < 2) { 1053 (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname()); 1054 return -1; 1055 } 1056 | 1179 1180 if (argc < 2) { 1181 (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname()); 1182 return -1; 1183 } 1184 |
1185 info.i_buf = NULL; 1186 info.i_len = 0; |
|
1057 for (i = 1; i < argc; i++) { | 1187 for (i = 1; i < argc; i++) { |
1058 if ((fd = open(argv[1], O_RDONLY)) == -1) | 1188 if ((info.i_fd = open(argv[1], O_RDONLY)) == -1) |
1059 err(1, "Cannot open `%s'", argv[1]); 1060 | 1189 err(1, "Cannot open `%s'", argv[1]); 1190 |
1061 if (cdf_read_header(fd, &h) == -1) | 1191 if (cdf_read_header(&info, &h) == -1) |
1062 err(1, "Cannot read header"); 1063#ifdef CDF_DEBUG 1064 cdf_dump_header(&h); 1065#endif 1066 | 1192 err(1, "Cannot read header"); 1193#ifdef CDF_DEBUG 1194 cdf_dump_header(&h); 1195#endif 1196 |
1067 if (cdf_read_sat(fd, &h, &sat) == -1) | 1197 if (cdf_read_sat(&info, &h, &sat) == -1) |
1068 err(1, "Cannot read sat"); 1069#ifdef CDF_DEBUG | 1198 err(1, "Cannot read sat"); 1199#ifdef CDF_DEBUG |
1070 cdf_dump_sat("SAT", &h, &sat); | 1200 cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h)); |
1071#endif 1072 | 1201#endif 1202 |
1073 if (cdf_read_ssat(fd, &h, &sat, &ssat) == -1) | 1203 if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1) |
1074 err(1, "Cannot read ssat"); 1075#ifdef CDF_DEBUG | 1204 err(1, "Cannot read ssat"); 1205#ifdef CDF_DEBUG |
1076 cdf_dump_sat("SSAT", &h, &ssat); | 1206 cdf_dump_sat("SSAT", &h, &ssat, CDF_SHORT_SEC_SIZE(&h)); |
1077#endif 1078 | 1207#endif 1208 |
1079 if (cdf_read_dir(fd, &h, &sat, &dir) == -1) | 1209 if (cdf_read_dir(&info, &h, &sat, &dir) == -1) |
1080 err(1, "Cannot read dir"); 1081 | 1210 err(1, "Cannot read dir"); 1211 |
1082 if (cdf_read_short_stream(fd, &h, &sat, &dir, &sst) == -1) | 1212 if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1) |
1083 err(1, "Cannot read short stream"); 1084#ifdef CDF_DEBUG 1085 cdf_dump_stream(&h, &sst); 1086#endif 1087 1088#ifdef CDF_DEBUG | 1213 err(1, "Cannot read short stream"); 1214#ifdef CDF_DEBUG 1215 cdf_dump_stream(&h, &sst); 1216#endif 1217 1218#ifdef CDF_DEBUG |
1089 cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir); | 1219 cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); |
1090#endif 1091 1092 | 1220#endif 1221 1222 |
1093 if (cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir, | 1223 if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, |
1094 &scn) == -1) 1095 err(1, "Cannot read summary info"); 1096#ifdef CDF_DEBUG 1097 cdf_dump_summary_info(&h, &scn); 1098#endif 1099 | 1224 &scn) == -1) 1225 err(1, "Cannot read summary info"); 1226#ifdef CDF_DEBUG 1227 cdf_dump_summary_info(&h, &scn); 1228#endif 1229 |
1100 (void)close(fd); | 1230 (void)close(info.i_fd); |
1101 } 1102 1103 return 0; 1104} 1105#endif | 1231 } 1232 1233 return 0; 1234} 1235#endif |