Virgin import of Christos Zoulas's FILE 5.03.

Security:	CVE-2009-1515
This commit is contained in:
delphij 2009-05-18 22:27:42 +00:00
parent 00d8dd21db
commit 862d9405b8
41 changed files with 4166 additions and 6723 deletions

View File

@ -1,3 +1,59 @@
2009-05-06 10:25 Christos Zoulas <christos@zoulas.com>
* Avoid null dereference in cdf code (Drew Yao)
* More cdf bounds checks and overflow checks
2009-05-01 18:37 Christos Zoulas <christos@zoulas.com>
* Buffer overflow fixes from Drew Yao
2009-04-30 17:10 Christos Zoulas <christos@zoulas.com>
* Fix more cdf lossage. All the documents I have
right now print the correct information.
2009-03-27 18:43 Christos Zoulas <christos@zoulas.com>
* don't print \012- separators in the same magic entry
if it consists of multiple magic printing lines.
2009-03-23 10:20 Christos Zoulas <christos@zoulas.com>
* Avoid file descriptor leak in compress code from
(Daniel Novotny)
2009-03-18 16:50 Christos Zoulas <christos@zoulas.com>
* Allow escaping of relation characters, so that we can say \^[A-Z]
and the ^ is not eaten as a relation char.
* Fix troff and fortran to their previous glory using
regex. This was broken since their removel from ascmagic.
2009-03-10 16:50 Christos Zoulas <christos@zoulas.com>
* don't use strlen in strndup() (Toby Peterson)
2009-03-10 7:45 Christos Zoulas <christos@zoulas.com>
* avoid c99 syntax.
2009-02-23 15:45 Christos Zoulas <christos@zoulas.com>
* make the cdf code use the buffer first if available,
and then the fd code.
2009-02-13 13:45 Christos Zoulas <christos@zoulas.com>
* look for struct option to determine if getopt.h is usable for IRIX.
* sanitize cdf document strings
2009-02-04 13:25 Christos Zoulas <christos@zoulas.com>
* fix OS/2 warnings.
2008-12-12 15:50 Christos Zoulas <christos@zoulas.com>
* fix initial offset calculation for non 4K sector files

View File

@ -17,6 +17,15 @@
>4 belong >30 compiled Java class data,
>>6 beshort x version %d.
>>4 beshort x \b%d
# Which is which?
#>>4 belong 0x032d (Java 1.0)
#>>4 belong 0x032d (Java 1.1)
>>4 belong 0x002e (Java 1.2)
>>4 belong 0x002f (Java 1.3)
>>4 belong 0x0030 (Java 1.4)
>>4 belong 0x0031 (Java 1.5)
>>4 belong 0x0032 (Java 1.6)
0 belong 0xcafebabe
>4 belong 1 Mach-O fat file with 1 architecture

View File

@ -195,6 +195,10 @@
# bug #364260)
#0 string ]\000\000\200\000 LZMA compressed data
# http://tukaani.org/xz/xz-file-format.txt
0 ustring \xFD7zXZ\x00 xz compressed data
!:mime application/x-xz
# AFX compressed files (Wolfram Kleff)
2 string -afx- AFX compressed file data
@ -208,3 +212,8 @@
>4 byte x - version %d
>5 byte x \b.%d
>6 belong x (%d bytes)
# Type: XZ
# URL: http://tukaani.org/xz/
0 string \xfd\x37\x7a\x58\x5a\x00 XZ compressed data
!:mime application/x-xz

View File

@ -242,3 +242,28 @@
# URL: http://www.grc.nasa.gov/WWW/cgns/adf/
# From: Nicolas Chauvat <nicolas.chauvat@logilab.fr>
0 string @(#)ADF\ Database CGNS Advanced Data Format
# Tokyo Cabinet magic data
# http://tokyocabinet.sourceforge.net/index.html
0 string ToKyO\ CaBiNeT\n Tokyo Cabinet
>14 string x \b (%s)
>32 byte 0 \b, Hash
!:mime application/x-tokyocabinet-hash
>32 byte 1 \b, B+ tree
!:mime application/x-tokyocabinet-btree
>32 byte 2 \b, Fixed-length
!:mime application/x-tokyocabinet-fixed
>32 byte 3 \b, Table
!:mime application/x-tokyocabinet-table
>33 byte &1 \b, [open]
>33 byte &2 \b, [fatal]
>34 byte x \b, apow=%d
>35 byte x \b, fpow=%d
>36 byte &0x01 \b, [large]
>36 byte &0x02 \b, [deflate]
>36 byte &0x04 \b, [bzip]
>36 byte &0x08 \b, [tcbs]
>36 byte &0x10 \b, [excodec]
>40 lequad x \b, bnum=%lld
>48 lequad x \b, rnum=%lld
>56 lequad x \b, fsiz=%lld

View File

@ -12,7 +12,7 @@
>8 string BEAM Erlang BEAM file
# 4.2 version may have a copyright notice!
4 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
79 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
4 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2
79 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2
4 string 1.0 Fri Feb 3 09:55:56 MET 1995 Erlang JAM file - version 4.3
4 string 1.0\ Fri\ Feb\ 3\ 09:55:56\ MET\ 1995 Erlang JAM file - version 4.3

View File

@ -891,7 +891,7 @@
0x410 leshort 0x2478 Minix filesystem, version 2, 30 char names
# romfs filesystems - Juan Cespedes <cespedes@debian.org>
0 string -rom1fs-\0 romfs filesystem, version 1
0 string -rom1fs- romfs filesystem, version 1
>8 belong x %d bytes,
>16 string x named %s.

View File

@ -6,8 +6,8 @@
0 short 017001 byte-swapped Berkeley vfont data
# PostScript fonts (must precede "printer" entries), quinlan@yggdrasil.com
0 search/1 %!PS-AdobeFont-1. PostScript Type 1 font text
>20 search/1 >\0 (%s)
0 string %!PS-AdobeFont-1. PostScript Type 1 font text
>20 string >\0 (%s)
6 string %!PS-AdobeFont-1. PostScript Type 1 font program data
# X11 font files in SNF (Server Natural Format) format
@ -55,6 +55,8 @@
0 string \007\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font
0 string \012\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font
0 string ttcf TrueType font collection data
# Opentype font data from Avi Bercovich
0 string OTTO OpenType font data

View File

@ -1,3 +1,3 @@
# FORTRAN source
0 string/c c\ FORTRAN program
0 regex/100 \^[Cc][\ \t] FORTRAN program
!:mime text/x-fortran

32
Magdir/kml Normal file
View File

@ -0,0 +1,32 @@
#------------------------------------------------------------------------------
# Type: Google KML, formerly Keyhole Markup Language
# Future development of this format has been handed
# over to the Open Geospatial Consortium.
# http://www.opengeospatial.org/standards/kml/
# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
0 string \<?xml
>20 search/400 \ xmlns=
>>&0 regex ['"]http://earth.google.com/kml Google KML document
!:mime application/vnd.google-earth.kml+xml
>>>&1 string 2.0' \b, version 2.0
>>>&1 string 2.1' \b, version 2.1
>>>&1 string 2.2' \b, version 2.2
#------------------------------------------------------------------------------
# Type: OpenGIS KML, formerly Keyhole Markup Language
# This standard is maintained by the
# Open Geospatial Consortium.
# http://www.opengeospatial.org/standards/kml/
# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
>>&0 regex ['"]http://www.opengis.net/kml OpenGIS KML document
!:mime application/vnd.google-earth.kml+xml
>>>&1 string 2.2 \b, version 2.2
#------------------------------------------------------------------------------
# Type: Google KML Archive (ZIP based)
# http://code.google.com/apis/kml/documentation/kml_tut.html
# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
0 string PK\003\004
>4 byte 0x14
>>30 string doc.kml Compressed Google KML Document, including resources.
!:mime application/vnd.google-earth.kmz

View File

@ -84,7 +84,7 @@
514 string HdrS Linux kernel
>510 leshort 0xAA55 x86 boot executable
>>518 leshort >0x1ff
>>529 byte 0 zImage,
>>>529 byte 0 zImage,
>>>529 byte 1 bzImage,
>>>(526.s+0x200) string >\0 version %s,
>>498 leshort 1 RO-rootFS,

View File

@ -8,22 +8,22 @@
#0 string ;;
# windows INF files often begin with semicolon and use CRLF as line end
# lisp files are mainly created on unix system with LF as line end
#>2 search/2048 !\r Lisp/Scheme program text
#>2 search/2048 \r Windows INF file
#>2 search/4096 !\r Lisp/Scheme program text
#>2 search/4096 \r Windows INF file
0 search/256 (if\ Lisp/Scheme program text
0 search/4096 (if\ Lisp/Scheme program text
!:mime text/x-lisp
0 search/256 (setq\ Lisp/Scheme program text
0 search/4096 (setq\ Lisp/Scheme program text
!:mime text/x-lisp
0 search/256 (defvar\ Lisp/Scheme program text
0 search/4096 (defvar\ Lisp/Scheme program text
!:mime text/x-lisp
0 search/256 (defparam\ Lisp/Scheme program text
0 search/4096 (defparam\ Lisp/Scheme program text
!:mime text/x-lisp
0 search/256 (defun\ Lisp/Scheme program text
0 search/4096 (defun\ Lisp/Scheme program text
!:mime text/x-lisp
0 search/256 (autoload\ Lisp/Scheme program text
0 search/4096 (autoload\ Lisp/Scheme program text
!:mime text/x-lisp
0 search/256 (custom-set-variables\ Lisp/Scheme program text
0 search/4096 (custom-set-variables\ Lisp/Scheme program text
!:mime text/x-lisp
# Emacs 18 - this is always correct, but not very magical.

View File

@ -14,6 +14,8 @@
0 belong 0x3bf20d0a python 2.3 byte-compiled
0 belong 0x6df20d0a python 2.4 byte-compiled
0 belong 0xb3f20d0a python 2.5 byte-compiled
0 belong 0xd1f20d0a python 2.6 byte-compiled
0 string/b #!\ /usr/bin/python python script text executable

View File

@ -14,6 +14,10 @@
!:mime text/troff
0 search/1 ''' troff or preprocessor input text
!:mime text/troff
0 regex/20 \^\\.[A-Za-z0-9][A-Za-z0-9][\ \t] troff or preprocessor input text
!:mime text/troff
0 regex/20 \^\\.[A-Za-z0-9][A-Za-z0-9]$ troff or preprocessor input text
!:mime text/troff
# ditroff intermediate output text
0 search/1 x\ T ditroff output text

View File

@ -113,3 +113,9 @@
0 string REGEDIT4\r\n\r\n Windows Registry text (Win95 or above)
0 string Windows\ Registry\ Editor\
>&0 string Version\ 5.00\r\n\r\n Windows Registry text (Win2K or above)
# From: Pal Tamas <folti@balabit.hu>
# Autorun File
0 string/c [autorun]\r\n Microsoft Windows Autorun file.
!:mime application/x-setupscript.

View File

@ -1,5 +1,5 @@
#
# $File: Makefile.am,v 1.44 2009/01/28 02:11:20 christos Exp $
# $File: Makefile.am,v 1.45 2009/03/05 22:40:59 christos Exp $
#
MAGIC_FRAGMENT_BASE = Magdir
MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE)
@ -97,6 +97,7 @@ $(MAGIC_FRAGMENT_DIR)/java \
$(MAGIC_FRAGMENT_DIR)/jpeg \
$(MAGIC_FRAGMENT_DIR)/karma \
$(MAGIC_FRAGMENT_DIR)/kde \
$(MAGIC_FRAGMENT_DIR)/kml \
$(MAGIC_FRAGMENT_DIR)/lecter \
$(MAGIC_FRAGMENT_DIR)/lex \
$(MAGIC_FRAGMENT_DIR)/lif \

View File

@ -15,7 +15,6 @@
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@ -54,6 +53,7 @@ am__installdirs = "$(DESTDIR)$(pkgdatadir)"
pkgdataDATA_INSTALL = $(INSTALL_DATA)
DATA = $(pkgdata_DATA)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgdatadir = @pkgdatadir@
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
@ -73,6 +73,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@ -95,6 +96,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@ -104,6 +106,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -163,7 +166,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
#
# $File: Makefile.am,v 1.44 2009/01/28 02:11:20 christos Exp $
# $File: Makefile.am,v 1.45 2009/03/05 22:40:59 christos Exp $
#
MAGIC_FRAGMENT_BASE = Magdir
MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE)
@ -259,6 +262,7 @@ $(MAGIC_FRAGMENT_DIR)/java \
$(MAGIC_FRAGMENT_DIR)/jpeg \
$(MAGIC_FRAGMENT_DIR)/karma \
$(MAGIC_FRAGMENT_DIR)/kde \
$(MAGIC_FRAGMENT_DIR)/kml \
$(MAGIC_FRAGMENT_DIR)/lecter \
$(MAGIC_FRAGMENT_DIR)/lex \
$(MAGIC_FRAGMENT_DIR)/lif \

7
README
View File

@ -1,15 +1,18 @@
** README for file(1) Command **
@(#) $File: README,v 1.41 2008/12/02 16:34:46 christos Exp $
@(#) $File: README,v 1.42 2009/02/14 15:16:24 christos Exp $
E-mail: christos@astron.com
Mailing List: file@mx.gw.com
Phone: Do not even think of telephoning me about this program. Send cash first!
This is Release 4.x of Ian Darwin's (copyright but distributable)
This is Release 5.x of Ian Darwin's (copyright but distributable)
file(1) command. This version is the standard "file" command for Linux,
*BSD, and other systems. (See "patchlevel.h" for the exact release number).
The major changes for 5.x are CDF file parsing, indirect magic, and
overhaul in mime and ascii encoding handling.
The major feature of 4.x is the refactoring of the code into a library,
and the re-write of the file command in terms of that library. The library
itself, libmagic can be used by 3rd party programs that wish to identify

View File

@ -9,6 +9,7 @@ AC_CACHE_CHECK([for tm_zone in struct tm], ac_cv_struct_tm_zone,
if test "$ac_cv_struct_tm_zone" = yes; then
AC_DEFINE(HAVE_TM_ZONE,1,[HAVE_TM_ZONE])
fi
AC_CACHE_CHECK(for tzname, ac_cv_var_tzname,
[AC_TRY_LINK(
changequote(<<, >>)dnl
@ -29,6 +30,7 @@ AC_CACHE_CHECK([for tm_isdst in struct tm], ac_cv_struct_tm_isdst,
if test "$ac_cv_struct_tm_isdst" = yes; then
AC_DEFINE(HAVE_TM_ISDST,1,[HAVE_TM_ISDST])
fi
AC_CACHE_CHECK(for daylight, ac_cv_var_daylight,
[AC_TRY_LINK(
changequote(<<, >>)dnl
@ -42,3 +44,12 @@ changequote([, ])dnl
AC_DEFINE(HAVE_DAYLIGHT,1,[HAVE_DAYLIGHT])
fi
])
AC_DEFUN([AC_STRUCT_OPTION_GETOPT_H],
[AC_CACHE_CHECK([for struct option in getopt], ac_cv_struct_option_getopt_h,
[AC_TRY_COMPILE([#include <getopt.h>], [struct option op; op.name;],
ac_cv_struct_option_getopt_h=yes, ac_cv_struct_option_getopt_h=no)])
if test "$ac_cv_struct_option_getopt_h" = yes; then
AC_DEFINE(HAVE_STRUCT_OPTION,1,[HAVE_STRUCT_OPTION])
fi
])

1562
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: apprentice.c,v 1.147 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: apprentice.c,v 1.151 2009/03/18 15:19:23 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -89,8 +89,8 @@ const size_t file_nnames = FILE_NAMES_SIZE;
private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
private int hextoint(int);
private const char *getstr(struct magic_set *, const char *, char *, int,
int *, int);
private const char *getstr(struct magic_set *, struct magic *, const char *,
int);
private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
const char *, size_t, int);
private void eatsize(const char **);
@ -324,11 +324,15 @@ file_delmagic(struct magic *p, int type, size_t entries)
if (p == NULL)
return;
switch (type) {
#ifdef QUICK
case 2:
#ifdef QUICK
p--;
(void)munmap((void *)p, sizeof(*p) * (entries + 1));
break;
#else
(void)&entries;
abort();
/*NOTREACHED*/
#endif
case 1:
p--;
@ -1712,8 +1716,7 @@ check_format(struct magic_set *ms, struct magic *m)
* string is not one character long
*/
file_magwarn(ms, "Printf format `%c' is not valid for type "
"`%s' in description `%s'",
ptr && *ptr ? *ptr : '?',
"`%s' in description `%s'", *ptr ? *ptr : '?',
file_names[m->type], m->desc);
return -1;
}
@ -1738,8 +1741,6 @@ check_format(struct magic_set *ms, struct magic *m)
private int
getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
{
int slen;
switch (m->type) {
case FILE_BESTRING16:
case FILE_LESTRING16:
@ -1747,16 +1748,13 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
case FILE_PSTRING:
case FILE_REGEX:
case FILE_SEARCH:
*p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen, action);
*p = getstr(ms, m, *p, action == FILE_COMPILE);
if (*p == NULL) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "cannot get string from `%s'",
m->value.s);
return -1;
}
m->vallen = slen;
if (m->type == FILE_PSTRING)
m->vallen++;
return 0;
case FILE_FLOAT:
case FILE_BEFLOAT:
@ -1795,13 +1793,15 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
/*
* Convert a string containing C character escapes. Stop at an unescaped
* space or tab.
* Copy the converted version to "p", returning its length in *slen.
* Return updated scan pointer as function result.
* Copy the converted version to "m->value.s", and the length in m->vallen.
* Return updated scan pointer as function result. Warn if set.
*/
private const char *
getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int action)
getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
{
const char *origs = s;
char *p = m->value.s;
size_t plen = sizeof(m->value.s);
char *origp = p;
char *pmax = p + plen - 1;
int c;
@ -1818,25 +1818,33 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int ac
switch(c = *s++) {
case '\0':
if (action == FILE_COMPILE)
if (warn)
file_magwarn(ms, "incomplete escape");
goto out;
case '\t':
if (action == FILE_COMPILE) {
if (warn) {
file_magwarn(ms,
"escaped tab found, use \\t instead");
action++;
warn = 0; /* already did */
}
/*FALLTHROUGH*/
default:
if (action == FILE_COMPILE) {
if (isprint((unsigned char)c))
file_magwarn(ms,
"no need to escape `%c'", c);
else
file_magwarn(ms,
"unknown escape sequence: \\%03o", c);
if (warn) {
if (isprint((unsigned char)c)) {
/* Allow escaping of
* ``relations'' */
if (strchr("<>&^=!", c)
== NULL) {
file_magwarn(ms, "no "
"need to escape "
"`%c'", c);
}
} else {
file_magwarn(ms,
"unknown escape sequence: "
"\\%03o", c);
}
}
/*FALLTHROUGH*/
/* space, perhaps force people to use \040? */
@ -1935,7 +1943,9 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int ac
}
out:
*p = '\0';
*slen = p - origp;
m->vallen = p - origp;
if (m->type == FILE_PSTRING)
m->vallen++;
return s;
}
@ -2084,7 +2094,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
file_oomem(ms, (size_t)st.st_size);
goto error1;
}
if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) {
if (read(fd, mm, (size_t)st.st_size) != (ssize_t)st.st_size) {
file_badread(ms);
goto error1;
}
@ -2107,7 +2117,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
else
version = ptr[1];
if (version != VERSIONNO) {
file_error(ms, 0, "File %d.%d supports only %d version magic "
file_error(ms, 0, "File %d.%d supports only version %d magic "
"files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
VERSIONNO, dbname, version);
goto error1;

View File

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: apptype.c,v 1.10 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: apptype.c,v 1.11 2009/02/04 18:24:32 christos Exp $")
#endif /* lint */
#include <stdlib.h>
@ -76,7 +76,7 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
}
(void)fclose(fp);
}
rc = DosQueryAppType(path, &type);
rc = DosQueryAppType((unsigned char *)path, &type);
if (fn == NULL) {
unlink(path);

374
cdf.c
View File

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: cdf.c,v 1.17 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: cdf.c,v 1.30 2009/05/06 14:29:47 christos Exp $")
#endif
#include <assert.h>
@ -56,7 +56,7 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.17 2009/02/03 20:27:51 christos Exp $")
#endif
#ifdef CDF_DEBUG
#define DPRINTF(a) printf a
#define DPRINTF(a) printf a, fflush(stdout)
#else
#define DPRINTF(a)
#endif
@ -227,34 +227,85 @@ cdf_unpack_dir(cdf_directory_t *d, char *buf)
CDF_UNPACK(d->d_unused0);
}
int
cdf_read_header(int fd, cdf_header_t *h)
static int
cdf_check_stream_offset(const cdf_stream_t *sst, const void *p, size_t tail)
{
(void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
char buf[512];
if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1)
const char *b = (const char *)sst->sst_tab;
const char *e = ((const char *)p) + tail;
if (e >= b && (size_t)(e - b) < sst->sst_dirlen * sst->sst_len)
return 0;
DPRINTF((stderr, "offset begin %p end %p %zu >= %zu\n", b, e,
(size_t)(e - b), sst->sst_dirlen * sst->sst_len));
errno = EFTYPE;
return -1;
}
static ssize_t
cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
{
size_t siz = (size_t)off + len;
if ((off_t)(off + len) != (off_t)siz) {
errno = EINVAL;
return -1;
if (read(fd, buf, sizeof(buf)) != sizeof(buf))
}
if (info->i_buf != NULL && info->i_len >= siz) {
(void)memcpy(buf, &info->i_buf[off], len);
return (ssize_t)len;
}
if (info->i_fd == -1)
return -1;
if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1)
return -1;
if (read(info->i_fd, buf, len) != (ssize_t)len)
return -1;
return (ssize_t)len;
}
int
cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
{
char buf[512];
(void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
return -1;
cdf_unpack_header(h, buf);
cdf_swap_header(h);
if (h->h_magic != CDF_MAGIC) {
DPRINTF(("Bad magic 0x%x != 0x$x\n", h->h_magic, CDF_MAGIC));
errno = EFTYPE;
return -1;
DPRINTF(("Bad magic 0x%llx != 0x%llx\n",
(unsigned long long)h->h_magic,
(unsigned long long)CDF_MAGIC));
goto out;
}
if (h->h_sec_size_p2 > 20) {
DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2));
goto out;
}
if (h->h_short_sec_size_p2 > 20) {
DPRINTF(("Bad short sector size 0x%u\n",
h->h_short_sec_size_p2));
goto out;
}
return 0;
out:
errno = EFTYPE;
return -1;
}
ssize_t
cdf_read_sector(int fd, void *buf, size_t offs, size_t len,
cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
const cdf_header_t *h, cdf_secid_t id)
{
assert((size_t)CDF_SEC_SIZE(h) == len);
if (lseek(fd, (off_t)CDF_SEC_POS(h, id), SEEK_SET) == (off_t)-1)
return -1;
return read(fd, ((char *)buf) + offs, len);
return cdf_read(info, (off_t)CDF_SEC_POS(h, id),
((char *)buf) + offs, len);
}
ssize_t
@ -271,24 +322,35 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
* Read the sector allocation table.
*/
int
cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat)
cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
{
size_t i, j, k;
size_t ss = CDF_SEC_SIZE(h);
cdf_secid_t *msa, mid;
cdf_secid_t *msa, mid, sec;
size_t nsatpersec = (ss / sizeof(mid)) - 1;
for (i = 0; i < __arraycount(h->h_master_sat); i++)
if (h->h_master_sat[i] == CDF_SECID_FREE)
break;
sat->sat_len = (h->h_num_sectors_in_master_sat + i);
#define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss))
if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec ||
i > CDF_SEC_LIMIT) {
DPRINTF(("Number of sectors in master SAT too big %u %zu\n",
h->h_num_sectors_in_master_sat, i));
errno = EFTYPE;
return -1;
}
sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i;
DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss));
if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL)
return -1;
for (i = 0; i < __arraycount(h->h_master_sat); i++) {
if (h->h_master_sat[i] < 0)
break;
if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h,
if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
h->h_master_sat[i]) != (ssize_t)ss) {
DPRINTF(("Reading sector %d", h->h_master_sat[i]));
goto out1;
@ -300,24 +362,38 @@ cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat)
mid = h->h_secid_first_sector_in_master_sat;
for (j = 0; j < h->h_num_sectors_in_master_sat; j++) {
if (mid < 0)
goto out;
if (j >= CDF_LOOP_LIMIT) {
DPRINTF(("Reading master sector loop limit"));
errno = EFTYPE;
goto out2;
}
if (cdf_read_sector(fd, msa, 0, ss, h, mid) != (ssize_t)ss) {
if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) {
DPRINTF(("Reading master sector %d", mid));
goto out2;
}
for (k = 0; k < (ss / sizeof(mid)) - 1; k++, i++)
if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h,
CDF_TOLE4(msa[k])) != (ssize_t)ss) {
for (k = 0; k < nsatpersec; k++, i++) {
sec = CDF_TOLE4(msa[k]);
if (sec < 0)
goto out;
if (i >= sat->sat_len) {
DPRINTF(("Out of bounds reading MSA %u >= %u",
i, sat->sat_len));
errno = EFTYPE;
goto out2;
}
if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
sec) != (ssize_t)ss) {
DPRINTF(("Reading sector %d",
CDF_TOLE4(msa[k])));
goto out2;
}
mid = CDF_TOLE4(msa[(ss / sizeof(mid)) - 1]);
}
mid = CDF_TOLE4(msa[nsatpersec]);
}
out:
sat->sat_len = i;
free(msa);
return 0;
out2:
@ -328,11 +404,10 @@ out1:
}
size_t
cdf_count_chain(const cdf_header_t *h, const cdf_sat_t *sat,
cdf_secid_t sid)
cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
{
size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t);
cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * s);
size_t i, j;
cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size);
DPRINTF(("Chain:"));
for (j = i = 0; sid >= 0; i++, j++) {
@ -354,12 +429,12 @@ cdf_count_chain(const cdf_header_t *h, const cdf_sat_t *sat,
}
int
cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
cdf_secid_t sid, size_t len, cdf_stream_t *scn)
cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
const cdf_sat_t *sat, cdf_secid_t sid, size_t len, cdf_stream_t *scn)
{
size_t ss = CDF_SEC_SIZE(h), i, j;
ssize_t nr;
scn->sst_len = cdf_count_chain(h, sat, sid);
scn->sst_len = cdf_count_chain(sat, sid, ss);
scn->sst_dirlen = len;
if (scn->sst_len == (size_t)-1)
@ -370,7 +445,18 @@ cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
return -1;
for (j = i = 0; sid >= 0; i++, j++) {
if ((nr = cdf_read_sector(fd, scn->sst_tab, i * ss, ss, h,
if (j >= CDF_LOOP_LIMIT) {
DPRINTF(("Read long sector chain loop limit"));
errno = EFTYPE;
goto out;
}
if (i >= scn->sst_len) {
DPRINTF(("Out of bounds reading long sector chain "
"%u > %u\n", i, scn->sst_len));
errno = EFTYPE;
goto out;
}
if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
sid)) != (ssize_t)ss) {
if (i == scn->sst_len - 1 && nr > 0) {
/* Last sector might be truncated */
@ -380,16 +466,11 @@ cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
goto out;
}
sid = CDF_TOLE4(sat->sat_tab[sid]);
if (j >= CDF_LOOP_LIMIT) {
DPRINTF(("Read long sector chain loop limit"));
errno = EFTYPE;
goto out;
}
}
return 0;
out:
free(scn->sst_tab);
return (size_t)-1;
return -1;
}
int
@ -398,10 +479,10 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
cdf_secid_t sid, size_t len, cdf_stream_t *scn)
{
size_t ss = CDF_SHORT_SEC_SIZE(h), i, j;
scn->sst_len = cdf_count_chain(h, ssat, sid);
scn->sst_len = cdf_count_chain(ssat, sid, CDF_SEC_SIZE(h));
scn->sst_dirlen = len;
if (scn->sst_len == (size_t)-1)
if (sst->sst_tab == NULL || scn->sst_len == (size_t)-1)
return -1;
scn->sst_tab = calloc(scn->sst_len, ss);
@ -414,6 +495,12 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
errno = EFTYPE;
goto out;
}
if (i >= scn->sst_len) {
DPRINTF(("Out of bounds reading short sector chain "
"%u > %u\n", i, scn->sst_len));
errno = EFTYPE;
goto out;
}
if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
sid) != (ssize_t)ss) {
DPRINTF(("Reading short sector chain %d", sid));
@ -424,12 +511,12 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
return 0;
out:
free(scn->sst_tab);
return (size_t)-1;
return -1;
}
int
cdf_read_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
const cdf_sat_t *ssat, const cdf_stream_t *sst,
cdf_read_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
cdf_secid_t sid, size_t len, cdf_stream_t *scn)
{
@ -437,19 +524,19 @@ cdf_read_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
return cdf_read_short_sector_chain(h, ssat, sst, sid, len,
scn);
else
return cdf_read_long_sector_chain(fd, h, sat, sid, len, scn);
return cdf_read_long_sector_chain(info, h, sat, sid, len, scn);
}
int
cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
cdf_dir_t *dir)
cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
const cdf_sat_t *sat, cdf_dir_t *dir)
{
size_t i, j;
size_t ss = CDF_SEC_SIZE(h), ns, nd;
char *buf;
cdf_secid_t sid = h->h_secid_first_directory;
ns = cdf_count_chain(h, sat, sid);
ns = cdf_count_chain(sat, sid, ss);
if (ns == (size_t)-1)
return -1;
@ -471,7 +558,7 @@ cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
errno = EFTYPE;
goto out;
}
if (cdf_read_sector(fd, buf, 0, ss, h, sid) != (ssize_t)ss) {
if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) {
DPRINTF(("Reading directory sector %d", sid));
goto out;
}
@ -494,14 +581,14 @@ out:
int
cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
cdf_sat_t *ssat)
cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
const cdf_sat_t *sat, cdf_sat_t *ssat)
{
size_t i, j;
size_t ss = CDF_SEC_SIZE(h);
cdf_secid_t sid = h->h_secid_first_sector_in_short_sat;
ssat->sat_len = cdf_count_chain(h, sat, sid);
ssat->sat_len = cdf_count_chain(sat, sid, CDF_SEC_SIZE(h));
if (ssat->sat_len == (size_t)-1)
return -1;
@ -515,7 +602,13 @@ cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
errno = EFTYPE;
goto out;
}
if (cdf_read_sector(fd, ssat->sat_tab, i * ss, ss, h, sid) !=
if (i >= ssat->sat_len) {
DPRINTF(("Out of bounds reading short sector chain "
"%u > %u\n", i, ssat->sat_len));
errno = EFTYPE;
goto out;
}
if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
(ssize_t)ss) {
DPRINTF(("Reading short sat sector %d", sid));
goto out;
@ -529,8 +622,8 @@ out:
}
int
cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
const cdf_dir_t *dir, cdf_stream_t *scn)
cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h,
const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn)
{
size_t i;
const cdf_directory_t *d;
@ -539,22 +632,22 @@ cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE)
break;
if (i == dir->dir_len) {
DPRINTF(("Cannot find root storage node\n"));
errno = EFTYPE;
return -1;
}
/* If the it is not there, just fake it; some docs don't have it */
if (i == dir->dir_len)
goto out;
d = &dir->dir_tab[i];
/* If the it is not there, just fake it; some docs don't have it */
if (d->d_stream_first_sector < 0) {
scn->sst_tab = NULL;
scn->sst_len = 0;
return 0;
}
if (d->d_stream_first_sector < 0)
goto out;
return cdf_read_long_sector_chain(fd, h, sat,
return cdf_read_long_sector_chain(info, h, sat,
d->d_stream_first_sector, d->d_size, scn);
out:
scn->sst_tab = NULL;
scn->sst_len = 0;
scn->sst_dirlen = 0;
return 0;
}
static int
@ -567,7 +660,7 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l)
}
int
cdf_read_summary_info(int fd, const cdf_header_t *h,
cdf_read_summary_info(const cdf_info_t *info, const cdf_header_t *h,
const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
const cdf_dir_t *dir, cdf_stream_t *scn)
{
@ -587,7 +680,7 @@ cdf_read_summary_info(int fd, const cdf_header_t *h,
return -1;
}
d = &dir->dir_tab[i];
return cdf_read_sector_chain(fd, h, sat, ssat, sst,
return cdf_read_sector_chain(info, h, sat, ssat, sst,
d->d_stream_first_sector, d->d_size, scn);
}
@ -607,12 +700,28 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
size_t i, o, nelements, j;
cdf_property_info_t *inp;
if (offs > UINT32_MAX / 4) {
errno = EFTYPE;
goto out;
}
shp = (const void *)((const char *)sst->sst_tab + offs);
if (cdf_check_stream_offset(sst, shp, sizeof(*shp)) == -1)
goto out;
sh.sh_len = CDF_TOLE4(shp->sh_len);
#define CDF_SHLEN_LIMIT (UINT32_MAX / 8)
if (sh.sh_len > CDF_SHLEN_LIMIT) {
errno = EFTYPE;
goto out;
}
sh.sh_properties = CDF_TOLE4(shp->sh_properties);
DPRINTF(("section len: %d properties %d\n", sh.sh_len,
#define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(*inp)))
if (sh.sh_properties > CDF_PROP_LIMIT)
goto out;
DPRINTF(("section len: %u properties %u\n", sh.sh_len,
sh.sh_properties));
if (*maxcount) {
if (*maxcount > CDF_PROP_LIMIT)
goto out;
*maxcount += sh.sh_properties;
inp = realloc(*info, *maxcount * sizeof(*inp));
} else {
@ -626,6 +735,8 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
*count += sh.sh_properties;
p = (const void *)((const char *)sst->sst_tab + offs + sizeof(sh));
e = (const void *)(((const char *)shp) + sh.sh_len);
if (cdf_check_stream_offset(sst, e, 0) == -1)
goto out;
for (i = 0; i < sh.sh_properties; i++) {
q = (const uint32_t *)((const char *)p +
CDF_TOLE4(p[(i << 1) + 1])) - 2;
@ -683,6 +794,9 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
case CDF_LENGTH32_STRING:
if (nelements > 1) {
size_t nelem = inp - *info;
if (*maxcount > CDF_PROP_LIMIT
|| nelements > CDF_PROP_LIMIT)
goto out;
*maxcount += nelements;
inp = realloc(*info, *maxcount * sizeof(*inp));
if (inp == NULL)
@ -735,6 +849,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi,
const cdf_section_declaration_t *sd = (const void *)
((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET);
if (cdf_check_stream_offset(sst, si, sizeof(*si)) == -1 ||
cdf_check_stream_offset(sst, sd, sizeof(*sd)) == -1)
return -1;
ssi->si_byte_order = CDF_TOLE2(si->si_byte_order);
ssi->si_os_version = CDF_TOLE2(si->si_os_version);
ssi->si_os = CDF_TOLE2(si->si_os);
@ -848,12 +965,14 @@ cdf_dump_header(const cdf_header_t *h)
{
size_t i;
#define DUMP(a, b) printf("%40.40s = " a "\n", # b, h->h_ ## b)
#define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b)
#define DUMP2(a, b) (void)fprintf(stderr, "%40.40s = " a " (" a ")\n", # b, \
h->h_ ## b, 1 << h->h_ ## b)
DUMP("%d", revision);
DUMP("%d", version);
DUMP("0x%x", byte_order);
DUMP("%d", sec_size_p2);
DUMP("%d", short_sec_size_p2);
DUMP2("%d", sec_size_p2);
DUMP2("%d", short_sec_size_p2);
DUMP("%d", num_sectors_in_sat);
DUMP("%d", secid_first_directory);
DUMP("%d", min_size_standard_stream);
@ -864,24 +983,26 @@ cdf_dump_header(const cdf_header_t *h)
for (i = 0; i < __arraycount(h->h_master_sat); i++) {
if (h->h_master_sat[i] == CDF_SECID_FREE)
break;
printf("%35.35s[%.3zu] = %d\n",
(void)fprintf(stderr, "%35.35s[%.3zu] = %d\n",
"master_sat", i, h->h_master_sat[i]);
}
}
void
cdf_dump_sat(const char *prefix, const cdf_header_t *h, const cdf_sat_t *sat)
cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size)
{
size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t);
size_t i, j, s = size / sizeof(cdf_secid_t);
for (i = 0; i < sat->sat_len; i++) {
printf("%s[%zu]:\n", prefix, i);
(void)fprintf(stderr, "%s[%zu]:\n%.6d: ", prefix, i, i * s);
for (j = 0; j < s; j++) {
printf("%5d, ", CDF_TOLE4(sat->sat_tab[s * i + j]));
(void)fprintf(stderr, "%5d, ",
CDF_TOLE4(sat->sat_tab[s * i + j]));
if ((j + 1) % 10 == 0)
printf("\n");
(void)fprintf(stderr, "\n%.6d: ",
i * s + j + 1);
}
printf("\n");
(void)fprintf(stderr, "\n");
}
}
@ -891,17 +1012,17 @@ cdf_dump(void *v, size_t len)
size_t i, j;
unsigned char *p = v;
char abuf[16];
printf("%.4x: ", 0);
(void)fprintf(stderr, "%.4x: ", 0);
for (i = 0, j = 0; i < len; i++, p++) {
printf("%.2x ", *p);
(void)fprintf(stderr, "%.2x ", *p);
abuf[j++] = isprint(*p) ? *p : '.';
if (j == 16) {
j = 0;
abuf[15] = '\0';
printf("%s\n%.4x: ", abuf, i + 1);
(void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1);
}
}
printf("\n");
(void)fprintf(stderr, "\n");
}
void
@ -913,8 +1034,8 @@ cdf_dump_stream(const cdf_header_t *h, const cdf_stream_t *sst)
}
void
cdf_dump_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
const cdf_sat_t *ssat, const cdf_stream_t *sst,
cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h,
const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
const cdf_dir_t *dir)
{
size_t i, j;
@ -930,29 +1051,30 @@ cdf_dump_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
d = &dir->dir_tab[i];
for (j = 0; j < sizeof(name); j++)
name[j] = (char)CDF_TOLE2(d->d_name[j]);
printf("Directory %zu: %s\n", i, name);
(void)fprintf(stderr, "Directory %zu: %s\n", i, name);
if (d->d_type < __arraycount(types))
printf("Type: %s\n", types[d->d_type]);
(void)fprintf(stderr, "Type: %s\n", types[d->d_type]);
else
printf("Type: %d\n", d->d_type);
printf("Color: %s\n", d->d_color ? "black" : "red");
printf("Left child: %d\n", d->d_left_child);
printf("Right child: %d\n", d->d_right_child);
printf("Flags: 0x%x\n", d->d_flags);
(void)fprintf(stderr, "Type: %d\n", d->d_type);
(void)fprintf(stderr, "Color: %s\n",
d->d_color ? "black" : "red");
(void)fprintf(stderr, "Left child: %d\n", d->d_left_child);
(void)fprintf(stderr, "Right child: %d\n", d->d_right_child);
(void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags);
cdf_timestamp_to_timespec(&ts, d->d_created);
printf("Created %s", ctime(&ts.tv_sec));
(void)fprintf(stderr, "Created %s", ctime(&ts.tv_sec));
cdf_timestamp_to_timespec(&ts, d->d_modified);
printf("Modified %s", ctime(&ts.tv_sec));
printf("Stream %d\n", d->d_stream_first_sector);
printf("Size %d\n", d->d_size);
(void)fprintf(stderr, "Modified %s", ctime(&ts.tv_sec));
(void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector);
(void)fprintf(stderr, "Size %d\n", d->d_size);
switch (d->d_type) {
case CDF_DIR_TYPE_USER_STORAGE:
printf("Storage: %d\n", d->d_storage);
(void)fprintf(stderr, "Storage: %d\n", d->d_storage);
break;
case CDF_DIR_TYPE_USER_STREAM:
if (sst == NULL)
break;
if (cdf_read_sector_chain(fd, h, sat, ssat, sst,
if (cdf_read_sector_chain(info, h, sat, ssat, sst,
d->d_stream_first_sector, d->d_size, &scn) == -1) {
warn("Can't read stream for %s at %d len %d",
name, d->d_stream_first_sector, d->d_size);
@ -978,33 +1100,38 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
for (i = 0; i < count; i++) {
cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
printf("%zu) %s: ", i, buf);
(void)fprintf(stderr, "%zu) %s: ", i, buf);
switch (info[i].pi_type) {
case CDF_SIGNED16:
printf("signed 16 [%hd]\n", info[i].pi_s16);
(void)fprintf(stderr, "signed 16 [%hd]\n",
info[i].pi_s16);
break;
case CDF_SIGNED32:
printf("signed 32 [%d]\n", info[i].pi_s32);
(void)fprintf(stderr, "signed 32 [%d]\n",
info[i].pi_s32);
break;
case CDF_UNSIGNED32:
printf("unsigned 32 [%u]\n", info[i].pi_u32);
(void)fprintf(stderr, "unsigned 32 [%u]\n",
info[i].pi_u32);
break;
case CDF_LENGTH32_STRING:
printf("string %u [%.*s]\n", info[i].pi_str.s_len,
(void)fprintf(stderr, "string %u [%.*s]\n",
info[i].pi_str.s_len,
info[i].pi_str.s_len, info[i].pi_str.s_buf);
break;
case CDF_FILETIME:
tp = info[i].pi_tp;
if (tp < 1000000000000000LL) {
cdf_print_elapsed_time(buf, sizeof(buf), tp);
printf("timestamp %s\n", buf);
(void)fprintf(stderr, "timestamp %s\n", buf);
} else {
cdf_timestamp_to_timespec(&ts, tp);
printf("timestamp %s", ctime(&ts.tv_sec));
(void)fprintf(stderr, "timestamp %s",
ctime(&ts.tv_sec));
}
break;
case CDF_CLIPBOARD:
printf("CLIPBOARD %u\n", info[i].pi_u32);
(void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32);
break;
default:
DPRINTF(("Don't know how to deal with %x\n",
@ -1026,13 +1153,13 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
(void)&h;
if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1)
return;
printf("Endian: %x\n", ssi.si_byte_order);
printf("Os Version %d.%d\n", ssi.si_os_version & 0xff,
(void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order);
(void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
ssi.si_os_version >> 8);
printf("Os %d\n", ssi.si_os);
(void)fprintf(stderr, "Os %d\n", ssi.si_os);
cdf_print_classid(buf, sizeof(buf), &ssi.si_class);
printf("Class %s\n", buf);
printf("Count %d\n", ssi.si_count);
(void)fprintf(stderr, "Class %s\n", buf);
(void)fprintf(stderr, "Count %d\n", ssi.si_count);
cdf_dump_property_info(info, count);
free(info);
}
@ -1043,61 +1170,64 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
int
main(int argc, char *argv[])
{
int fd, i;
int i;
cdf_header_t h;
cdf_sat_t sat, ssat;
cdf_stream_t sst, scn;
cdf_dir_t dir;
cdf_info_t info;
if (argc < 2) {
(void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
return -1;
}
info.i_buf = NULL;
info.i_len = 0;
for (i = 1; i < argc; i++) {
if ((fd = open(argv[1], O_RDONLY)) == -1)
if ((info.i_fd = open(argv[1], O_RDONLY)) == -1)
err(1, "Cannot open `%s'", argv[1]);
if (cdf_read_header(fd, &h) == -1)
if (cdf_read_header(&info, &h) == -1)
err(1, "Cannot read header");
#ifdef CDF_DEBUG
cdf_dump_header(&h);
#endif
if (cdf_read_sat(fd, &h, &sat) == -1)
if (cdf_read_sat(&info, &h, &sat) == -1)
err(1, "Cannot read sat");
#ifdef CDF_DEBUG
cdf_dump_sat("SAT", &h, &sat);
cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
#endif
if (cdf_read_ssat(fd, &h, &sat, &ssat) == -1)
if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1)
err(1, "Cannot read ssat");
#ifdef CDF_DEBUG
cdf_dump_sat("SSAT", &h, &ssat);
cdf_dump_sat("SSAT", &h, &ssat, CDF_SHORT_SEC_SIZE(&h));
#endif
if (cdf_read_dir(fd, &h, &sat, &dir) == -1)
if (cdf_read_dir(&info, &h, &sat, &dir) == -1)
err(1, "Cannot read dir");
if (cdf_read_short_stream(fd, &h, &sat, &dir, &sst) == -1)
if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1)
err(1, "Cannot read short stream");
#ifdef CDF_DEBUG
cdf_dump_stream(&h, &sst);
#endif
#ifdef CDF_DEBUG
cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir);
cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
#endif
if (cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir,
if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
&scn) == -1)
err(1, "Cannot read summary info");
#ifdef CDF_DEBUG
cdf_dump_summary_info(&h, &scn);
#endif
(void)close(fd);
(void)close(info.i_fd);
}
return 0;

41
cdf.h
View File

@ -242,38 +242,45 @@ typedef struct {
#define CDF_PROPERTY_SECURITY 0x00000013
#define CDF_PROPERTY_LOCALE_ID 0x80000000
typedef struct {
int i_fd;
const unsigned char *i_buf;
size_t i_len;
} cdf_info_t;
struct timespec;
int cdf_timestamp_to_timespec(struct timespec *, cdf_timestamp_t);
int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timespec *);
int cdf_read_header(int, cdf_header_t *);
int cdf_read_header(const cdf_info_t *, cdf_header_t *);
void cdf_swap_header(cdf_header_t *);
void cdf_unpack_header(cdf_header_t *, char *);
void cdf_swap_dir(cdf_directory_t *);
void cdf_unpack_dir(cdf_directory_t *, char *);
void cdf_swap_class(cdf_classid_t *);
ssize_t cdf_read_sector(int, void *, size_t, size_t, const cdf_header_t *,
cdf_secid_t);
ssize_t cdf_read_sector(const cdf_info_t *, void *, size_t, size_t,
const cdf_header_t *, cdf_secid_t);
ssize_t cdf_read_short_sector(const cdf_stream_t *, void *, size_t, size_t,
const cdf_header_t *, cdf_secid_t);
int cdf_read_sat(int, cdf_header_t *, cdf_sat_t *);
size_t cdf_count_chain(const cdf_header_t *, const cdf_sat_t *,
cdf_secid_t);
int cdf_read_long_sector_chain(int, const cdf_header_t *,
int cdf_read_sat(const cdf_info_t *, cdf_header_t *, cdf_sat_t *);
size_t cdf_count_chain(const cdf_sat_t *, cdf_secid_t, size_t);
int cdf_read_long_sector_chain(const cdf_info_t *, const cdf_header_t *,
const cdf_sat_t *, cdf_secid_t, size_t, cdf_stream_t *);
int cdf_read_short_sector_chain(const cdf_header_t *, const cdf_sat_t *,
const cdf_stream_t *, cdf_secid_t, size_t, cdf_stream_t *);
int cdf_read_sector_chain(int, const cdf_header_t *,
int cdf_read_sector_chain(const cdf_info_t *, const cdf_header_t *,
const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, cdf_secid_t,
size_t, cdf_stream_t *);
int cdf_read_dir(int, const cdf_header_t *, const cdf_sat_t *, cdf_dir_t *);
int cdf_read_ssat(int, const cdf_header_t *, const cdf_sat_t *, cdf_sat_t *);
int cdf_read_short_stream(int, const cdf_header_t *, const cdf_sat_t *,
const cdf_dir_t *, cdf_stream_t *);
int cdf_read_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
cdf_dir_t *);
int cdf_read_ssat(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
cdf_sat_t *);
int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *,
const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *);
int cdf_read_property_info(const cdf_stream_t *, uint32_t,
cdf_property_info_t **, size_t *, size_t *);
int cdf_read_summary_info(int, const cdf_header_t *, const cdf_sat_t *,
const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *,
cdf_stream_t *);
int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *,
const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
const cdf_dir_t *, cdf_stream_t *);
int cdf_unpack_summary_info(const cdf_stream_t *, cdf_summary_info_header_t *,
cdf_property_info_t **, size_t *);
int cdf_print_classid(char *, size_t, const cdf_classid_t *);
@ -285,10 +292,10 @@ uint64_t cdf_tole8(uint64_t);
#ifdef CDF_DEBUG
void cdf_dump_header(const cdf_header_t *);
void cdf_dump_sat(const char *, const cdf_header_t *, const cdf_sat_t *);
void cdf_dump_sat(const char *, const cdf_sat_t *, size_t);
void cdf_dump(void *, size_t);
void cdf_dump_stream(const cdf_header_t *, const cdf_stream_t *);
void cdf_dump_dir(int, const cdf_header_t *, const cdf_sat_t *,
void cdf_dump_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *);
void cdf_dump_property_info(const cdf_property_info_t *, size_t);
void cdf_dump_summary_info(const cdf_header_t *, const cdf_stream_t *);

View File

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: cdf_time.c,v 1.5 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: cdf_time.c,v 1.6 2009/03/10 11:44:29 christos Exp $")
#endif
#include <time.h>
@ -102,6 +102,7 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
#ifdef HAVE_STRUCT_TM_TM_ZONE
static char UTC[] = "UTC";
#endif
int rdays;
/* Unit is 100's of nanoseconds */
ts->tv_nsec = (t % CDF_TIME_PREC) * 100;
@ -119,7 +120,7 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
// XXX: Approx
tm.tm_year = CDF_BASE_YEAR + (t / 365);
int rdays = cdf_getdays(tm.tm_year);
rdays = cdf_getdays(tm.tm_year);
t -= rdays;
tm.tm_mday = cdf_getday(tm.tm_year, t);
tm.tm_mon = cdf_getmonth(tm.tm_year, t);

View File

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: compress.c,v 1.61 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: compress.c,v 1.63 2009/03/23 14:21:51 christos Exp $")
#endif
#include "magic.h"
@ -76,6 +76,7 @@ private const struct {
/* ...only first file examined */
{ "BZh", 3, { "bzip2", "-cd", NULL }, 1 }, /* bzip2-ed */
{ "LZIP", 4, { "lzip", "-cdq", NULL }, 1 },
{ "\3757zXZ\0",6,{ "xz", "-cd", NULL }, 1 }, /* XZ Utils */
};
private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
@ -486,6 +487,8 @@ err:
#else
(void)wait(NULL);
#endif
(void) close(fdin[0]);
return n;
}
}

1504
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -93,6 +93,9 @@
/* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL
/* HAVE_STRUCT_OPTION */
#undef HAVE_STRUCT_OPTION
/* Define to 1 if `st_rdev' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_RDEV

1622
config.sub vendored

File diff suppressed because it is too large Load Diff

5177
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(file, 5.00, christos@astron.com)
AC_INIT(file, 5.03, christos@astron.com)
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
#AC_CONFIG_MACRO_DIR([m4])
AC_MSG_CHECKING(for builtin ELF support)
AC_ARG_ENABLE(elf,
@ -46,6 +47,7 @@ fi], [
fsect=4
])
AC_SUBST([pkgdatadir], ['$(datadir)/misc'])
AC_SUBST(fsect)
AM_CONDITIONAL(FSECT5, test x$fsect = x5)
@ -82,6 +84,8 @@ AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
AC_TYPE_MBSTATE_T
AC_STRUCT_OPTION_GETOPT_H
AC_CHECK_TYPES([uint8_t, uint16_t, uint32_t, int32_t, uint64_t, int64_t])
AC_CHECK_SIZEOF(long long)
AH_BOTTOM([
@ -116,7 +120,7 @@ typedef long int64_t;
AC_MSG_CHECKING(for gcc compiler warnings)
AC_ARG_ENABLE(warnings,
[ --disable-warnings disable compiler warnings],
[if test "${enableval}" = no -o $GCC = no; then
[if test "${enableval}" = no -o "$GCC" = no; then
AC_MSG_RESULT(no)
WARNINGS=
else
@ -126,7 +130,7 @@ else
-Wsign-compare -Wreturn-type -Wswitch -Wshadow \
-Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter"
fi], [
if test $GCC = no; then
if test "$GCC" = no; then
WARNINGS=
AC_MSG_RESULT(no)
else

4
file.c
View File

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: file.c,v 1.130 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: file.c,v 1.131 2009/02/13 18:48:05 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -61,7 +61,7 @@ FILE_RCSID("@(#)$File: file.c,v 1.130 2009/02/03 20:27:51 christos Exp $")
#include <wchar.h>
#endif
#ifdef HAVE_GETOPT_H
#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
#include <getopt.h>
#else
#include "mygetopt.h"

10
file.h
View File

@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
* @(#)$File: file.h,v 1.118 2009/02/03 20:27:51 christos Exp $
* @(#)$File: file.h,v 1.119 2009/02/04 18:24:32 christos Exp $
*/
#ifndef __file_h__
@ -387,7 +387,13 @@ protected size_t file_mbswidth(const char *);
protected const char *file_getbuffer(struct magic_set *);
protected ssize_t sread(int, void *, size_t, int);
protected int file_check_mem(struct magic_set *, unsigned int);
protected int file_looks_utf8(const unsigned char *, size_t, unichar *, size_t *);
protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
size_t *);
#ifdef __EMX__
protected int file_os2_apptype(struct magic_set *, const char *, const void *,
size_t);
#endif /* __EMX__ */
#ifndef COMPILE_ONLY
extern const char *file_names[];

11
funcs.c
View File

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: funcs.c,v 1.51 2008/11/07 18:57:28 christos Exp $")
FILE_RCSID("@(#)$File: funcs.c,v 1.53 2009/04/07 11:07:00 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -303,7 +303,14 @@ file_reset(struct magic_set *ms)
file_error(ms, 0, "no magic files loaded");
return -1;
}
ms->o.buf = NULL;
if (ms->o.buf) {
free(ms->o.buf);
ms->o.buf = NULL;
}
if (ms->o.pbuf) {
free(ms->o.pbuf);
ms->o.pbuf = NULL;
}
ms->event_flags &= ~EVENT_HAD_ERR;
ms->error = -1;
return 0;

View File

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: getopt_long.c,v 1.5 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: getopt_long.c,v 1.6 2009/02/13 18:48:05 christos Exp $")
#endif /* lint */
#include <assert.h>
@ -42,7 +42,7 @@ FILE_RCSID("@(#)$File: getopt_long.c,v 1.5 2009/02/03 20:27:51 christos Exp $")
#define warnx printf
#endif
#include <errno.h>
#ifdef HAVE_GETOPT_H
#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
#include <getopt.h>
#else
#include "mygetopt.h"

34
magic.c
View File

@ -28,7 +28,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25:41 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -57,10 +57,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $")
#include <unistd.h> /* for read() */
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#include <netinet/in.h> /* for byte swapping */
#include "patchlevel.h"
@ -74,12 +70,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $")
#endif
#endif
#ifdef __EMX__
private char *apptypeName = NULL;
protected int file_os2_apptype(struct magic_set *ms, const char *fn,
const void *buf, size_t nb);
#endif /* __EMX__ */
private void free_mlist(struct mlist *);
private void close_and_restore(const struct magic_set *, const char *, int,
const struct stat *);
@ -297,26 +287,10 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
errno = 0;
if ((fd = open(inname, flags)) < 0) {
#ifdef __CYGWIN__
/* FIXME: Do this with EXEEXT from autotools */
size_t len = strlen(inname) + 5;
char *tmp = alloca(len);
(void)strlcat(strlcpy(tmp, inname, len), ".exe", len);
if ((fd = open(tmp, flags)) < 0) {
#endif
if (unreadable_info(ms, sb.st_mode,
#ifdef __CYGWIN
tmp
#else
inname
#endif
) == -1)
goto done;
rv = 0;
if (unreadable_info(ms, sb.st_mode, inname) == -1)
goto done;
#ifdef __CYGWIN__
}
#endif
rv = 0;
goto done;
}
#ifdef O_NONBLOCK
if ((flags = fcntl(fd, F_GETFL)) != -1) {

View File

@ -1,11 +1,20 @@
#define FILE_VERSION_MAJOR 5
#define patchlevel 0
#define patchlevel 3
/*
* Patchlevel file for Ian Darwin's MAGIC command.
* $File: patchlevel.h,v 1.71 2009/01/21 19:09:42 christos Exp $
* $File: patchlevel.h,v 1.74 2009/05/06 20:32:48 christos Exp $
*
* $Log: patchlevel.h,v $
* Revision 1.74 2009/05/06 20:32:48 christos
* welcome to 5.03
*
* Revision 1.73 2009/05/04 15:15:13 christos
* 5.02...
*
* Revision 1.72 2009/04/30 21:20:15 christos
* 5.01 we are almost here.
*
* Revision 1.71 2009/01/21 19:09:42 christos
* file 5.0
*

View File

@ -26,7 +26,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: readcdf.c,v 1.11 2009/02/03 20:27:51 christos Exp $")
FILE_RCSID("@(#)$File: readcdf.c,v 1.18 2009/05/06 20:48:22 christos Exp $")
#endif
#include <stdlib.h>
@ -75,9 +75,23 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
if (len > 1) {
s = info[i].pi_str.s_buf;
if (NOTMIME(ms)) {
if (file_printf(ms, ", %s: %.*s", buf,
len, s) == -1)
return -1;
char vbuf[1024];
size_t j;
for (j = 0; j < sizeof(vbuf) && len--;
j++, s++) {
if (*s == '\0')
break;
if (isprint((unsigned char)*s))
vbuf[j] = *s;
}
if (j == sizeof(vbuf))
--j;
vbuf[j] = '\0';
if (vbuf[0]) {
if (file_printf(ms, ", %s: %s",
buf, vbuf) == -1)
return -1;
}
} else if (info[i].pi_id ==
CDF_PROPERTY_NAME_OF_APPLICATION) {
if (strstr(s, "Word"))
@ -115,7 +129,6 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
case CDF_CLIPBOARD:
break;
default:
file_error(ms, 0, "Internal parsing error");
return -1;
}
}
@ -134,15 +147,8 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst)
size_t count;
int m;
if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1) {
if (si.si_byte_order != 0xfffe)
return 0;
else
return -1;
}
if (si.si_byte_order != 0xfffe)
return 0;
if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1)
return -1;
if (NOTMIME(ms)) {
if (file_printf(ms, "CDF V2 Document") == -1)
@ -183,66 +189,64 @@ protected int
file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
size_t nbytes)
{
cdf_info_t info;
cdf_header_t h;
cdf_sat_t sat, ssat;
cdf_stream_t sst, scn;
cdf_dir_t dir;
int i;
(void)&nbytes;
(void)&buf;
const char *expn = "";
info.i_fd = fd;
info.i_buf = buf;
info.i_len = nbytes;
if (ms->flags & MAGIC_APPLE)
return 0;
if (cdf_read_header(fd, &h) == -1)
if (cdf_read_header(&info, &h) == -1)
return 0;
#ifdef CDF_DEBUG
cdf_dump_header(&h);
#endif
if (cdf_read_sat(fd, &h, &sat) == -1) {
file_error(ms, errno, "Can't read SAT");
return -1;
if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
expn = "Can't read SAT";
goto out0;
}
#ifdef CDF_DEBUG
cdf_dump_sat("SAT", &h, &sat);
cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
#endif
if ((i = cdf_read_ssat(fd, &h, &sat, &ssat)) == -1) {
file_error(ms, errno, "Can't read SAT");
if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
expn = "Can't read SSAT";
goto out1;
}
#ifdef CDF_DEBUG
cdf_dump_sat("SSAT", &h, &ssat);
cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
#endif
if ((i = cdf_read_dir(fd, &h, &sat, &dir)) == -1) {
file_error(ms, errno, "Can't read directory");
if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
expn = "Can't read directory";
goto out2;
}
if ((i = cdf_read_short_stream(fd, &h, &sat, &dir, &sst)) == -1) {
file_error(ms, errno, "Cannot read short stream");
if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
expn = "Cannot read short stream";
goto out3;
}
#ifdef CDF_DEBUG
cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir);
#endif
if ((i = cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir, &scn))
== -1) {
/* Some files don't have summary info! */
#ifdef notyet
file_error(ms, errno, "Can't read summary_info");
#else
i = 0;
cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
#endif
if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
&scn)) == -1) {
expn = "Cannot read summary info";
goto out4;
}
#ifdef CDF_DEBUG
cdf_dump_summary_info(&h, &scn);
#endif
if ((i = cdf_file_summary_info(ms, &scn)) == -1)
file_error(ms, errno, "Can't expand summary_info");
expn = "Can't expand summary_info";
free(scn.sst_tab);
out4:
free(sst.sst_tab);
@ -252,5 +256,14 @@ out2:
free(ssat.sat_tab);
out1:
free(sat.sat_tab);
out0:
if (i != 1) {
if (file_printf(ms, "CDF V2 Document") == -1)
return -1;
if (*expn)
if (file_printf(ms, ", corrupt: %s", expn) == -1)
return -1;
i = 1;
}
return i;
}

View File

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: softmagic.c,v 1.133 2008/11/07 22:50:37 christos Exp $")
FILE_RCSID("@(#)$File: softmagic.c,v 1.135 2009/03/27 22:42:49 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -256,11 +256,14 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* make sure that we have a separator first.
*/
if (*m->desc) {
printed_something = 1;
if ((e = handle_annotation(ms, m)) != 0)
return e;
if (print_sep(ms, firstline) == -1)
return -1;
if (!printed_something) {
printed_something = 1;
if (print_sep(ms, firstline)
== -1)
return -1;
}
}
/*
* This continuation matched. Print
@ -338,14 +341,13 @@ strndup(const char *str, size_t n)
size_t len;
char *copy;
len = strlen(str);
if (len > n)
len = n;
if (!(copy = malloc(len + 1)))
return (NULL);
(void) memcpy(copy, str, len + 1);
for (len = 0; len < n && str[len]; len++)
continue;
if ((copy = malloc(len + 1)) == NULL)
return NULL;
(void)memcpy(copy, str, len);
copy[len] = '\0';
return (copy);
return copy;
}
#endif /* HAVE_STRNDUP */

58
strlcat.c Normal file
View File

@ -0,0 +1,58 @@
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
#include "file.h"
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

54
strlcpy.c Normal file
View File

@ -0,0 +1,54 @@
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
#include "file.h"
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}

View File

@ -14,7 +14,6 @@
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@ -62,6 +61,7 @@ DIST_SOURCES = test.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgdatadir = @pkgdatadir@
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
@ -81,6 +81,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@ -103,6 +104,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@ -112,6 +114,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@