Quellcode durchsuchen

Import upstream version 5.11

Christos Zoulas vor 13 Jahren
Ursprung
Commit
b17eae96d8
15 geänderte Dateien mit 342 neuen und 158 gelöschten Zeilen
  1. 4 0
      ChangeLog
  2. 10 10
      configure
  3. 1 1
      configure.ac
  4. 2 1
      magic/Magdir/audio
  5. 9 1
      magic/Magdir/games
  6. 17 8
      magic/Magdir/gnu
  7. 6 1
      magic/Magdir/linux
  8. 10 10
      magic/Magdir/palm
  9. 96 0
      magic/Magdir/zfs
  10. 2 1
      magic/Makefile.am
  11. 2 1
      magic/Makefile.in
  12. 69 26
      src/cdf.c
  13. 89 85
      src/cdf.h
  14. 2 2
      src/encoding.c
  15. 23 11
      src/readcdf.c

+ 4 - 0
ChangeLog

@@ -1,3 +1,7 @@
+2012-02-20  17:33  Christos Zoulas <christos@zoulas.com>
+
+	* Fix CDF parsing issues found by CERT's fuzzing tool (Will Dormann)
+
 2011-12-15  12:17  Chris Metcalf <cmetcalf@tilera.com>
 
 	* Support Tilera architectures (tile64, tilepro, tilegx).

+ 10 - 10
configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for file 5.10.
+# Generated by GNU Autoconf 2.68 for file 5.11.
 #
 # Report bugs to <christos@astron.com>.
 #
@@ -709,8 +709,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='file'
 PACKAGE_TARNAME='file'
-PACKAGE_VERSION='5.10'
-PACKAGE_STRING='file 5.10'
+PACKAGE_VERSION='5.11'
+PACKAGE_STRING='file 5.11'
 PACKAGE_BUGREPORT='christos@astron.com'
 PACKAGE_URL=''
 
@@ -1439,7 +1439,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures file 5.10 to adapt to many kinds of systems.
+\`configure' configures file 5.11 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1509,7 +1509,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of file 5.10:";;
+     short | recursive ) echo "Configuration of file 5.11:";;
    esac
   cat <<\_ACEOF
 
@@ -1615,7 +1615,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-file configure 5.10
+file configure 5.11
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2319,7 +2319,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by file $as_me 5.10, which was
+It was created by file $as_me 5.11, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3134,7 +3134,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='file'
- VERSION='5.10'
+ VERSION='5.11'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13555,7 +13555,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by file $as_me 5.10, which was
+This file was extended by file $as_me 5.11, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -13621,7 +13621,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-file config.status 5.10
+file config.status 5.11
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 

+ 1 - 1
configure.ac

@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT(file, 5.10, christos@astron.com)
+AC_INIT(file, 5.11, christos@astron.com)
 AM_INIT_AUTOMAKE()
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 

+ 2 - 1
magic/Magdir/audio

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: audio,v 1.63 2011/09/06 11:00:06 christos Exp $
+# $File: audio,v 1.64 2012/02/20 16:37:34 christos Exp $
 # audio:  file(1) magic for sound formats (see also "iff")
 #
 # Jan Nicolai Langfeldt (janl@ifi.uio.no), Dan Quinlan (quinlan@yggdrasil.com),
@@ -491,6 +491,7 @@
 # From danny.milo@gmx.net (Danny Milosavljevic)
 # New version from Abel Cheung <abel (@) oaka.org>
 0		string		MAC\040		Monkey's Audio compressed format
+!:mime audio/x-ape
 >4		uleshort	>0x0F8B		version %d
 >>(0x08.l)	uleshort	=1000		with fast compression
 >>(0x08.l)	uleshort	=2000		with normal compression

+ 9 - 1
magic/Magdir/games

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: games,v 1.12 2010/11/25 15:00:12 christos Exp $
+# $File: games,v 1.13 2012/02/13 22:50:50 christos Exp $
 # games:  file(1) for games
 
 # Fabio Bonelli <fabiobonelli@libero.it>
@@ -255,3 +255,11 @@
 >2	regex/c	GM\\[19\\]			- Octi Game
 >2	regex/c	GM\\[20\\]			- Gess Game
 >2	regex/c	GM\\[21\\]			- twix Game
+
+# Epic Games/Unreal Engine Package
+#
+0	lelong		0x9E2A83C1	Unreal Engine Package,
+>4	leshort		x		version: %i
+>12	lelong		!0		\b, names: %i
+>28	lelong		!0		\b, imports: %i
+>20	lelong		!0		\b, exports: %i

+ 17 - 8
magic/Magdir/gnu

@@ -1,19 +1,28 @@
 
 #------------------------------------------------------------------------------
-# $File: gnu,v 1.12 2011/12/08 12:12:46 rrt Exp $
+# $File: gnu,v 1.13 2012/01/03 17:16:54 christos Exp $
 # gnu:  file(1) magic for various GNU tools
 #
 # GNU nlsutils message catalog file format
 #
+# GNU message catalog (.mo and .gmo files)
+
 0	string		\336\22\4\225	GNU message catalog (little endian),
->4	lelong		x		revision %d,
->8	lelong		x		%d messages
+>6	leshort		x		revision %d.
+>4	leshort		>0		\b%d,
+>>8	lelong		x		%d messages,
+>>36	lelong		x		%d sysdep messages
+>4	leshort		=0		\b%d,
+>>8	lelong		x		%d messages
+
 0	string		\225\4\22\336	GNU message catalog (big endian),
->4	belong		x		revision %d,
->8	belong		x		%d messages
-# message catalogs, from Mitchum DSouza <m.dsouza@mrc-apu.cam.ac.uk>
-0	string		*nazgul*	Nazgul style compiled message catalog
->8	lelong		>0		\b, version %ld
+>4	beshort		x		revision %d.
+>6	beshort		>0		\b%d,
+>>8	belong		x		%d messages,
+>>36	belong		x		%d sysdep messages
+>6	beshort		=0		\b%d,
+>>8	belong		x		%d messages
+
 
 # GnuPG
 # The format is very similar to pgp

+ 6 - 1
magic/Magdir/linux

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: linux,v 1.41 2011/04/20 18:57:10 christos Exp $
+# $File: linux,v 1.42 2012/02/07 21:35:03 christos Exp $
 # linux:  file(1) magic for Linux files
 #
 # Values for Linux/i386 binaries, from Daniel Quinlan <quinlan@yggdrasil.com>
@@ -182,6 +182,11 @@
 >>&0 string \x80\x00\x20\x00\x00\x00\x00\x00 Z990 32bit kernel
 >>&0 string \x80\x00\x00\x00\x00\x00\x00\x00 Z900 32bit kernel
 
+# Linux ARM compressed kernel image
+# From: Kevin Cernekee <cernekee@gmail.com>
+36	lelong	0x016f2818	Linux kernel ARM boot executable zImage (little-endian)
+36	belong	0x016f2818	Linux kernel ARM boot executable zImage (big-endian)
+
 ############################################################################
 # Linux 8086 executable
 0	lelong&0xFF0000FF 0xC30000E9	Linux-Dev86 executable, headerless

+ 10 - 10
magic/Magdir/palm

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: palm,v 1.8 2011/12/15 16:21:43 christos Exp $
+# $File: palm,v 1.9 2012/01/16 15:16:43 christos Exp $
 # palm:	 file(1) magic for PalmOS {.prc,.pdb}: applications, docfiles, and hacks
 #
 # Brian Lalor <blalor@hcirisc.cs.binghamton.edu>
@@ -10,17 +10,17 @@
 # What are the possibilities and where is this documented?
 
 # appl
-59	byte			\0
->60	string			appl		PalmOS application
->0	string			>\0		"%s"
+#59	byte			\0
+#>60	string			appl		PalmOS application
+#>0	string			>\0		"%s"
 # TEXt
-59	byte			\0
->60	belong			TEXt		AportisDoc file
->0	string			>\0		"%s"
+#59	byte			\0
+#>60	belong			TEXt		AportisDoc file
+#>0	string			>\0		"%s"
 # HACK
-59	byte			\0
->60	string			HACK		HackMaster hack
->0	string			>\0		"%s"
+#59	byte			\0
+#>60	string			HACK		HackMaster hack
+#>0	string			>\0		"%s"
 
 # Variety of PalmOS document types
 # Michael-John Turner <mj@debian.org>

+ 96 - 0
magic/Magdir/zfs

@@ -0,0 +1,96 @@
+#------------------------------------------------------------------------------
+# zfs:	file(1) magic for ZFS dumps
+#
+# From <rea-fbsd@codelabs.ru>
+# ZFS dump header has the following structure (as per zfs_ioctl.h
+# in FreeBSD with drr_type is set to DRR_BEGIN)
+#
+#   enum {
+#	DRR_BEGIN, DRR_OBJECT, DRR_FREEOBJECTS,
+#	DRR_WRITE, DRR_FREE, DRR_END,
+#   } drr_type;
+#   uint32_t drr_pad;
+#   uint64_t drr_magic;
+#   uint64_t drr_version;
+#   uint64_t drr_creation_time;
+#   dmu_objset_type_t drr_type;
+#   uint32_t drr_pad;
+#   uint64_t drr_toguid;
+#   uint64_t drr_fromguid;
+#   char drr_toname[MAXNAMELEN];
+#
+# Backup magic is 0x00000002f5bacbac (quad word)
+# The drr_type is defined as
+#   typedef enum dmu_objset_type {
+#	  DMU_OST_NONE,
+#	  DMU_OST_META,
+#	  DMU_OST_ZFS,
+#	  DMU_OST_ZVOL,
+#	  DMU_OST_OTHER,		  /* For testing only! */
+#	  DMU_OST_ANY,			  /* Be careful! */
+#	  DMU_OST_NUMTYPES
+#  } dmu_objset_type_t;
+#
+# Almost all uint64_t fields are printed as the 32-bit ones (with high
+# 32 bits zeroed), because there is no simple way to print them as the
+# full 64-bit values.
+
+# Big-endian values
+8	string	\000\000\000\002\365\272\313\254 ZFS shapshot (big-endian machine),
+>20	belong	x	version %lu,
+>32	belong	0	type: NONE,
+>32	belong	1	type: META,
+>32	belong	2	type: ZFS,
+>32	belong	3	type: ZVOL,
+>32	belong	4	type: OTHER,
+>32	belong	5	type: ANY,
+>32	belong	>5	type: UNKNOWN (%lu),
+>40	byte	x	destination GUID: %02X
+>41	byte	x	%02X
+>42	byte	x	%02X
+>43	byte	x	%02X
+>44	byte	x	%02X
+>45	byte	x	%02X
+>46	byte	x	%02X
+>47	byte	x	%02X,
+>48	ulong	>0
+>>52	ulong	>0
+>>>48	byte	x	source GUID: %02X
+>>>49	byte	x	%02X
+>>>50	byte	x	%02X
+>>>51	byte	x	%02X
+>>>52	byte	x	%02X
+>>>53	byte	x	%02X
+>>>54	byte	x	%02X
+>>>55	byte	x	%02X,
+>56	string	>\0	name: '%s'
+
+# Little-endian values
+8	string	\254\313\272\365\002\000\000\000	ZFS shapshot (little-endian machine),
+>16	lelong	x	version %lu,
+>32	lelong	0	type: NONE,
+>32	lelong	1	type: META,
+>32	lelong	2	type: ZFS,
+>32	lelong	3	type: ZVOL,
+>32	lelong	4	type: OTHER,
+>32	lelong	5	type: ANY,
+>32	lelong	>5	type: UNKNOWN (%lu),
+>47	byte	x	destination GUID: %02X
+>46	byte	x	%02X
+>45	byte	x	%02X
+>44	byte	x	%02X
+>43	byte	x	%02X
+>42	byte	x	%02X
+>41	byte	x	%02X
+>40	byte	x	%02X,
+>48	ulong	>0
+>>52	ulong	>0
+>>>55	byte	x	source GUID: %02X
+>>>54	byte	x	%02X
+>>>53	byte	x	%02X
+>>>52	byte	x	%02X
+>>>51	byte	x	%02X
+>>>50	byte	x	%02X
+>>>49	byte	x	%02X
+>>>48	byte	x	%02X,
+>56	string	>\0	name: '%s'

+ 2 - 1
magic/Makefile.am

@@ -1,5 +1,5 @@
 #
-# $File: Makefile.am,v 1.77 2011/12/16 17:44:33 christos Exp $
+# $File: Makefile.am,v 1.78 2012/01/27 01:41:26 christos Exp $
 #
 MAGIC_FRAGMENT_BASE = Magdir
 MAGIC_DIR = $(top_srcdir)/magic
@@ -245,6 +245,7 @@ $(MAGIC_FRAGMENT_DIR)/xenix \
 $(MAGIC_FRAGMENT_DIR)/xilinx \
 $(MAGIC_FRAGMENT_DIR)/xo65 \
 $(MAGIC_FRAGMENT_DIR)/xwindows \
+$(MAGIC_FRAGMENT_DIR)/zfs \
 $(MAGIC_FRAGMENT_DIR)/zilog \
 $(MAGIC_FRAGMENT_DIR)/zyxel 
 

+ 2 - 1
magic/Makefile.in

@@ -196,7 +196,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 
 #
-# $File: Makefile.am,v 1.77 2011/12/16 17:44:33 christos Exp $
+# $File: Makefile.am,v 1.78 2012/01/27 01:41:26 christos Exp $
 #
 MAGIC_FRAGMENT_BASE = Magdir
 MAGIC_DIR = $(top_srcdir)/magic
@@ -440,6 +440,7 @@ $(MAGIC_FRAGMENT_DIR)/xenix \
 $(MAGIC_FRAGMENT_DIR)/xilinx \
 $(MAGIC_FRAGMENT_DIR)/xo65 \
 $(MAGIC_FRAGMENT_DIR)/xwindows \
+$(MAGIC_FRAGMENT_DIR)/zfs \
 $(MAGIC_FRAGMENT_DIR)/zilog \
 $(MAGIC_FRAGMENT_DIR)/zyxel 
 

+ 69 - 26
src/cdf.c

@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.46 2011/09/16 21:23:59 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.50 2012/02/20 22:35:29 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -75,6 +75,7 @@ static union {
 #define CDF_TOLE2(x)	((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x)))
 #define CDF_GETUINT32(x, y)	cdf_getuint32(x, y)
 
+
 /*
  * swap a short
  */
@@ -341,18 +342,27 @@ ssize_t
 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);
-	return cdf_read(info, (off_t)CDF_SEC_POS(h, id),
-	    ((char *)buf) + offs, len);
+	size_t ss = CDF_SEC_SIZE(h);
+	size_t pos = CDF_SEC_POS(h, id);
+	assert(ss == len);
+	return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len);
 }
 
 ssize_t
 cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
     size_t len, const cdf_header_t *h, cdf_secid_t id)
 {
-	assert((size_t)CDF_SHORT_SEC_SIZE(h) == len);
+	size_t ss = CDF_SHORT_SEC_SIZE(h);
+	size_t pos = CDF_SHORT_SEC_POS(h, id);
+	assert(ss == len);
+	if (pos > CDF_SEC_SIZE(h) * sst->sst_len) {
+		DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %"
+		    SIZE_T_FORMAT "u\n",
+		    pos, CDF_SEC_SIZE(h) * sst->sst_len));
+		return -1;
+	}
 	(void)memcpy(((char *)buf) + offs,
-	    ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len);
+	    ((const char *)sst->sst_tab) + pos, len);
 	return len;
 }
 
@@ -419,8 +429,8 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
 			if (sec < 0)
 				goto out;
 			if (i >= sat->sat_len) {
-			    DPRINTF(("Out of bounds reading MSA %u >= %u",
-				i, sat->sat_len));
+			    DPRINTF(("Out of bounds reading MSA %" SIZE_T_FORMAT
+				"u >= %" SIZE_T_FORMAT "u", i, sat->sat_len));
 			    errno = EFTYPE;
 			    goto out2;
 			}
@@ -493,7 +503,8 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
 		}
 		if (i >= scn->sst_len) {
 			DPRINTF(("Out of bounds reading long sector chain "
-			    "%u > %u\n", i, scn->sst_len));
+			    "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", i,
+			    scn->sst_len));
 			errno = EFTYPE;
 			goto out;
 		}
@@ -538,7 +549,8 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
 		}
 		if (i >= scn->sst_len) {
 			DPRINTF(("Out of bounds reading short sector chain "
-			    "%u > %u\n", i, scn->sst_len));
+			    "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n",
+			    i, scn->sst_len));
 			errno = EFTYPE;
 			goto out;
 		}
@@ -646,7 +658,8 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
 		}
 		if (i >= ssat->sat_len) {
 			DPRINTF(("Out of bounds reading short sector chain "
-			    "%u > %u\n", i, ssat->sat_len));
+			    "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", i,
+			    ssat->sat_len));
 			errno = EFTYPE;
 			goto out;
 		}
@@ -786,17 +799,18 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
 	if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1)
 		goto out;
 	for (i = 0; i < sh.sh_properties; i++) {
+		size_t ofs = CDF_GETUINT32(p, (i << 1) + 1);
 		q = (const uint8_t *)(const void *)
-		    ((const char *)(const void *)p +
-		    CDF_GETUINT32(p, (i << 1) + 1)) - 2 * sizeof(uint32_t);
+		    ((const char *)(const void *)p + ofs
+		    - 2 * sizeof(uint32_t));
 		if (q > e) {
 			DPRINTF(("Ran of the end %p > %p\n", q, e));
 			goto out;
 		}
 		inp[i].pi_id = CDF_GETUINT32(p, i << 1);
 		inp[i].pi_type = CDF_GETUINT32(q, 0);
-		DPRINTF(("%d) id=%x type=%x offs=%x,%d\n", i, inp[i].pi_id,
-		    inp[i].pi_type, q - p, CDF_GETUINT32(p, (i << 1) + 1)));
+		DPRINTF(("%" SIZE_T_FORMAT "u) id=%x type=%x offs=0x%tx,0x%x\n",
+		    i, inp[i].pi_id, inp[i].pi_type, q - p, offs));
 		if (inp[i].pi_type & CDF_VECTOR) {
 			nelements = CDF_GETUINT32(q, 1);
 			o = 2;
@@ -842,6 +856,20 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
 			(void)memcpy(&u64, &q[o4], sizeof(u64));
 			inp[i].pi_u64 = CDF_TOLE8((uint64_t)u64);
 			break;
+		case CDF_FLOAT:
+			if (inp[i].pi_type & CDF_VECTOR)
+				goto unknown;
+			(void)memcpy(&u32, &q[o4], sizeof(u32));
+			u32 = CDF_TOLE4(u32);
+			memcpy(&inp[i].pi_f, &u32, sizeof(inp[i].pi_f));
+			break;
+		case CDF_DOUBLE:
+			if (inp[i].pi_type & CDF_VECTOR)
+				goto unknown;
+			(void)memcpy(&u64, &q[o4], sizeof(u64));
+			u64 = CDF_TOLE8((uint64_t)u64);
+			memcpy(&inp[i].pi_d, &u64, sizeof(inp[i].pi_d));
+			break;
 		case CDF_LENGTH32_STRING:
 		case CDF_LENGTH32_WSTRING:
 			if (nelements > 1) {
@@ -857,17 +885,22 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
 				*info = inp;
 				inp = *info + nelem;
 			}
-			DPRINTF(("nelements = %d\n", nelements));
+			DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
+			    nelements));
 			for (j = 0; j < nelements; j++, i++) {
 				uint32_t l = CDF_GETUINT32(q, o);
 				inp[i].pi_str.s_len = l;
 				inp[i].pi_str.s_buf = (const char *)
 				    (const void *)(&q[o4 + sizeof(l)]);
-				DPRINTF(("l = %d, r = %d, s = %s\n", l,
+				DPRINTF(("l = %d, r = %" SIZE_T_FORMAT
+				    "u, s = %s\n", l,
 				    CDF_ROUND(l, sizeof(l)),
 				    inp[i].pi_str.s_buf));
-				l = 4 + (uint32_t)CDF_ROUND(l, sizeof(l));
-				o += l >> 2;
+				if (l & 1)
+					l++;
+				o += l >> 1;
+				if (q + o >= e)
+					goto out;
 				o4 = o * sizeof(uint32_t);
 			}
 			i--;
@@ -886,7 +919,7 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
 		unknown:
 			DPRINTF(("Don't know how to deal with %x\n",
 			    inp[i].pi_type));
-			goto out;
+			break;
 		}
 	}
 	return 0;
@@ -925,8 +958,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
 			return -1;
 		}
 		if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset),
-		    info, count, &maxcount) == -1)
+		    info, count, &maxcount) == -1) {
 			return -1;
+		}
 	}
 	return 0;
 }
@@ -1051,14 +1085,14 @@ cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size)
 	size_t i, j, s = size / sizeof(cdf_secid_t);
 
 	for (i = 0; i < sat->sat_len; i++) {
-		(void)fprintf(stderr, "%s[%" SIZE_T_FORMAT "u]:\n%.6d: ",
-		    prefix, i, i * s);
+		(void)fprintf(stderr, "%s[%" SIZE_T_FORMAT "u]:\n%.6"
+		    SIZE_T_FORMAT "u: ", prefix, i, i * s);
 		for (j = 0; j < s; j++) {
 			(void)fprintf(stderr, "%5d, ",
 			    CDF_TOLE4(sat->sat_tab[s * i + j]));
 			if ((j + 1) % 10 == 0)
-				(void)fprintf(stderr, "\n%.6d: ",
-				    i * s + j + 1);
+				(void)fprintf(stderr, "\n%.6" SIZE_T_FORMAT
+				    "u: ", i * s + j + 1);
 		}
 		(void)fprintf(stderr, "\n");
 	}
@@ -1077,7 +1111,8 @@ cdf_dump(void *v, size_t len)
 		if (j == 16) {
 			j = 0;
 			abuf[15] = '\0';
-			(void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1);
+			(void)fprintf(stderr, "%s\n%.4" SIZE_T_FORMAT "x: ",
+			    abuf, i + 1);
 		}
 	}
 	(void)fprintf(stderr, "\n");
@@ -1175,6 +1210,14 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
 			(void)fprintf(stderr, "unsigned 32 [%u]\n",
 			    info[i].pi_u32);
 			break;
+		case CDF_FLOAT:
+			(void)fprintf(stderr, "float [%g]\n",
+			    info[i].pi_f);
+			break;
+		case CDF_DOUBLE:
+			(void)fprintf(stderr, "double [%g]\n",
+			    info[i].pi_d);
+			break;
 		case CDF_LENGTH32_STRING:
 			(void)fprintf(stderr, "string %u [%.*s]\n",
 			    info[i].pi_str.s_len,

+ 89 - 85
src/cdf.h

@@ -51,136 +51,140 @@ typedef int32_t cdf_secid_t;
 
 #define CDF_SECID_NULL					0
 #define CDF_SECID_FREE					-1
-#define	CDF_SECID_END_OF_CHAIN				-2
-#define	CDF_SECID_SECTOR_ALLOCATION_TABLE		-3
+#define CDF_SECID_END_OF_CHAIN				-2
+#define CDF_SECID_SECTOR_ALLOCATION_TABLE		-3
 #define CDF_SECID_MASTER_SECTOR_ALLOCATION_TABLE	-4
 
 typedef struct {
-        uint64_t	h_magic;
+	uint64_t	h_magic;
 #define CDF_MAGIC	0xE11AB1A1E011CFD0LL
-        uint64_t	h_uuid[2];
-        uint16_t	h_revision;
-        uint16_t	h_version;
-        uint16_t	h_byte_order;
-        uint16_t	h_sec_size_p2;
-        uint16_t	h_short_sec_size_p2;
-        uint8_t		h_unused0[10];
-        uint32_t	h_num_sectors_in_sat;
-        uint32_t	h_secid_first_directory;
-        uint8_t		h_unused1[4];
-        uint32_t	h_min_size_standard_stream;
-        cdf_secid_t	h_secid_first_sector_in_short_sat;
-        uint32_t	h_num_sectors_in_short_sat;
-        cdf_secid_t	h_secid_first_sector_in_master_sat;
-        uint32_t	h_num_sectors_in_master_sat;
-        cdf_secid_t	h_master_sat[436/4];
+	uint64_t	h_uuid[2];
+	uint16_t	h_revision;
+	uint16_t	h_version;
+	uint16_t	h_byte_order;
+	uint16_t	h_sec_size_p2;
+	uint16_t	h_short_sec_size_p2;
+	uint8_t		h_unused0[10];
+	uint32_t	h_num_sectors_in_sat;
+	uint32_t	h_secid_first_directory;
+	uint8_t		h_unused1[4];
+	uint32_t	h_min_size_standard_stream;
+	cdf_secid_t	h_secid_first_sector_in_short_sat;
+	uint32_t	h_num_sectors_in_short_sat;
+	cdf_secid_t	h_secid_first_sector_in_master_sat;
+	uint32_t	h_num_sectors_in_master_sat;
+	cdf_secid_t	h_master_sat[436/4];
 } cdf_header_t;
 
-#define CDF_SEC_SIZE(h)	(1 << (h)->h_sec_size_p2)
+#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2))
 #define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h))
-#define CDF_SHORT_SEC_SIZE(h)	(1 << (h)->h_short_sec_size_p2)
+#define CDF_SHORT_SEC_SIZE(h)	((size_t)(1 << (h)->h_short_sec_size_p2))
 #define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h))
 
-typedef int32_t	cdf_dirid_t;
+typedef int32_t cdf_dirid_t;
 #define CDF_DIRID_NULL	-1
 
-typedef int64_t	cdf_timestamp_t;
+typedef int64_t cdf_timestamp_t;
 #define CDF_BASE_YEAR	1601
 #define CDF_TIME_PREC	10000000
 
 typedef struct {
-        uint16_t	d_name[32];
-        uint16_t	d_namelen;
-        uint8_t		d_type;
+	uint16_t	d_name[32];
+	uint16_t	d_namelen;
+	uint8_t		d_type;
 #define CDF_DIR_TYPE_EMPTY		0
-#define	CDF_DIR_TYPE_USER_STORAGE	1
-#define	CDF_DIR_TYPE_USER_STREAM	2
-#define	CDF_DIR_TYPE_LOCKBYTES		3
-#define	CDF_DIR_TYPE_PROPERTY		4
-#define	CDF_DIR_TYPE_ROOT_STORAGE	5
-        uint8_t		d_color;
+#define CDF_DIR_TYPE_USER_STORAGE	1
+#define CDF_DIR_TYPE_USER_STREAM	2
+#define CDF_DIR_TYPE_LOCKBYTES		3
+#define CDF_DIR_TYPE_PROPERTY		4
+#define CDF_DIR_TYPE_ROOT_STORAGE	5
+	uint8_t		d_color;
 #define CDF_DIR_COLOR_READ	0
 #define CDF_DIR_COLOR_BLACK	1
-        cdf_dirid_t	d_left_child;
-        cdf_dirid_t	d_right_child;
-        cdf_dirid_t	d_storage;
-        uint64_t	d_storage_uuid[2];
-        uint32_t	d_flags;
-        cdf_timestamp_t	d_created;
-        cdf_timestamp_t	d_modified;
-        cdf_secid_t	d_stream_first_sector;
-        uint32_t	d_size;
-        uint32_t	d_unused0;
+	cdf_dirid_t	d_left_child;
+	cdf_dirid_t	d_right_child;
+	cdf_dirid_t	d_storage;
+	uint64_t	d_storage_uuid[2];
+	uint32_t	d_flags;
+	cdf_timestamp_t d_created;
+	cdf_timestamp_t d_modified;
+	cdf_secid_t	d_stream_first_sector;
+	uint32_t	d_size;
+	uint32_t	d_unused0;
 } cdf_directory_t;
 
 #define CDF_DIRECTORY_SIZE	128
 
 typedef struct {
-        cdf_secid_t *sat_tab;
-        size_t sat_len;
+	cdf_secid_t *sat_tab;
+	size_t sat_len;
 } cdf_sat_t;
 
 typedef struct {
-        cdf_directory_t *dir_tab;
-        size_t dir_len;
+	cdf_directory_t *dir_tab;
+	size_t dir_len;
 } cdf_dir_t;
 
 typedef struct {
-        void *sst_tab;
-        size_t sst_len;
-        size_t sst_dirlen;
+	void *sst_tab;
+	size_t sst_len;
+	size_t sst_dirlen;
 } cdf_stream_t;
 
 typedef struct {
-        uint32_t	cl_dword;
-        uint16_t	cl_word[2];
-        uint8_t		cl_two[2];
-        uint8_t		cl_six[6];
+	uint32_t	cl_dword;
+	uint16_t	cl_word[2];
+	uint8_t		cl_two[2];
+	uint8_t		cl_six[6];
 } cdf_classid_t;
 
 typedef struct {
-        uint16_t	si_byte_order;
-        uint16_t	si_zero;
-        uint16_t	si_os_version;
-        uint16_t	si_os;
-        cdf_classid_t	si_class;
-        uint32_t	si_count;
+	uint16_t	si_byte_order;
+	uint16_t	si_zero;
+	uint16_t	si_os_version;
+	uint16_t	si_os;
+	cdf_classid_t	si_class;
+	uint32_t	si_count;
 } cdf_summary_info_header_t;
 
 #define CDF_SECTION_DECLARATION_OFFSET 0x1c
 
 typedef struct {
-        cdf_classid_t	sd_class;
-        uint32_t	sd_offset;
+	cdf_classid_t	sd_class;
+	uint32_t	sd_offset;
 } cdf_section_declaration_t;
 
 typedef struct {
-        uint32_t	sh_len;
-        uint32_t	sh_properties;
+	uint32_t	sh_len;
+	uint32_t	sh_properties;
 } cdf_section_header_t;
 
 typedef struct {
-        uint32_t	pi_id;
-        uint32_t	pi_type;
-        union {
-                uint16_t	_pi_u16;
-                int16_t		_pi_s16;
-                uint32_t	_pi_u32;
-                int32_t		_pi_s32;
-                uint64_t	_pi_u64;
-                int64_t		_pi_s64;
-                cdf_timestamp_t	_pi_tp;
-                struct {
-                        uint32_t s_len;
-                        const char *s_buf;
-                } _pi_str;
-        } pi_val;
+	uint32_t	pi_id;
+	uint32_t	pi_type;
+	union {
+		uint16_t	_pi_u16;
+		int16_t		_pi_s16;
+		uint32_t	_pi_u32;
+		int32_t		_pi_s32;
+		uint64_t	_pi_u64;
+		int64_t		_pi_s64;
+		cdf_timestamp_t _pi_tp;
+		float		_pi_f;
+		double		_pi_d;
+		struct {
+			uint32_t s_len;
+			const char *s_buf;
+		} _pi_str;
+	} pi_val;
 #define pi_u64	pi_val._pi_u64
 #define pi_s64	pi_val._pi_s64
 #define pi_u32	pi_val._pi_u32
 #define pi_s32	pi_val._pi_s32
 #define pi_u16	pi_val._pi_u16
 #define pi_s16	pi_val._pi_s16
+#define pi_f	pi_val._pi_f
+#define pi_d	pi_val._pi_d
 #define pi_tp	pi_val._pi_tp
 #define pi_str	pi_val._pi_str
 } cdf_property_info_t;
@@ -189,13 +193,13 @@ typedef struct {
 
 /* Variant type definitions */
 #define CDF_EMPTY		0x00000000
-#define	CDF_NULL		0x00000001
+#define CDF_NULL		0x00000001
 #define CDF_SIGNED16		0x00000002
 #define CDF_SIGNED32		0x00000003
 #define CDF_FLOAT		0x00000004
 #define CDF_DOUBLE		0x00000005
 #define CDF_CY			0x00000006
-#define	CDF_DATE		0x00000007
+#define CDF_DATE		0x00000007
 #define CDF_BSTR		0x00000008
 #define CDF_DISPATCH		0x00000009
 #define CDF_ERROR		0x0000000a
@@ -206,7 +210,7 @@ typedef struct {
 #define CDF_SIGNED8		0x00000010
 #define CDF_UNSIGNED8		0x00000011
 #define CDF_UNSIGNED16		0x00000012
-#define	CDF_UNSIGNED32		0x00000013
+#define CDF_UNSIGNED32		0x00000013
 #define CDF_SIGNED64		0x00000014
 #define CDF_UNSIGNED64		0x00000015
 #define CDF_INT			0x00000016
@@ -241,7 +245,7 @@ typedef struct {
 #define CDF_PROPERTY_SUBJECT			0x00000003
 #define CDF_PROPERTY_AUTHOR			0x00000004
 #define CDF_PROPERTY_KEYWORDS			0x00000005
-#define CDF_PROPERTY_COMMENTS                   0x00000006
+#define CDF_PROPERTY_COMMENTS			0x00000006
 #define CDF_PROPERTY_TEMPLATE			0x00000007
 #define CDF_PROPERTY_LAST_SAVED_BY		0x00000008
 #define CDF_PROPERTY_REVISION_NUMBER		0x00000009
@@ -258,9 +262,9 @@ typedef struct {
 #define CDF_PROPERTY_LOCALE_ID			0x80000000
 
 typedef struct {
-        int i_fd;
-        const unsigned char *i_buf;
-        size_t i_len;
+	int i_fd;
+	const unsigned char *i_buf;
+	size_t i_len;
 } cdf_info_t;
 
 struct timespec;

+ 2 - 2
src/encoding.c

@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: encoding.c,v 1.6 2011/12/08 12:38:24 rrt Exp $")
+FILE_RCSID("@(#)$File: encoding.c,v 1.7 2012/01/24 19:02:02 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -71,6 +71,7 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni
 	int rv = 1, ucs_type;
 	unsigned char *nbuf = NULL;
 
+	*type = "text";
 	mlen = (nbytes + 1) * sizeof(nbuf[0]);
 	if ((nbuf = CAST(unsigned char *, calloc((size_t)1, mlen))) == NULL) {
 		file_oomem(ms, mlen);
@@ -82,7 +83,6 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni
 		goto done;
 	}
 
-	*type = "text";
 	if (looks_ascii(buf, nbytes, *ubuf, ulen)) {
 		DPRINTF(("ascii %" SIZE_T_FORMAT "u\n", *ulen));
 		*code = "ASCII";

+ 23 - 11
src/readcdf.c

@@ -26,7 +26,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.27 2011/09/28 13:30:10 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.29 2012/02/20 20:04:58 christos Exp $")
 #endif
 
 #include <stdlib.h>
@@ -72,6 +72,16 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
                             info[i].pi_u32) == -1)
                                 return -1;
                         break;
+                case CDF_FLOAT:
+                        if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
+                            info[i].pi_f) == -1)
+                                return -1;
+                        break;
+                case CDF_DOUBLE:
+                        if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
+                            info[i].pi_d) == -1)
+                                return -1;
+                        break;
                 case CDF_LENGTH32_STRING:
                 case CDF_LENGTH32_WSTRING:
                         len = info[i].pi_str.s_len;
@@ -163,30 +173,31 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
                 return -1;
 
         if (NOTMIME(ms)) {
-                if (file_printf(ms, "Composite Document File V2 Document") == -1)
+                if (file_printf(ms, "Composite Document File V2 Document")
+		    == -1)
                         return -1;
 
                 if (file_printf(ms, ", %s Endian",
                     si.si_byte_order == 0xfffe ?  "Little" : "Big") == -1)
-                        return -1;
+                        return -2;
                 switch (si.si_os) {
                 case 2:
                         if (file_printf(ms, ", Os: Windows, Version %d.%d",
                             si.si_os_version & 0xff,
                             (uint32_t)si.si_os_version >> 8) == -1)
-                                return -1;
+                                return -2;
                         break;
                 case 1:
                         if (file_printf(ms, ", Os: MacOS, Version %d.%d",
                             (uint32_t)si.si_os_version >> 8,
                             si.si_os_version & 0xff) == -1)
-                                return -1;
+                                return -2;
                         break;
                 default:
                         if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
                             si.si_os_version & 0xff,
                             (uint32_t)si.si_os_version >> 8) == -1)
-                                return -1;
+                                return -2;
                         break;
                 }
         }
@@ -194,7 +205,7 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
         m = cdf_file_property_info(ms, info, count);
         free(info);
 
-        return m;
+        return m == -1 ? -2 : m;
 }
 
 protected int
@@ -263,7 +274,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
 #ifdef CDF_DEBUG
         cdf_dump_summary_info(&h, &scn);
 #endif
-        if ((i = cdf_file_summary_info(ms, &h, &scn)) == -1)
+        if ((i = cdf_file_summary_info(ms, &h, &scn)) < 0)
                 expn = "Can't expand summary_info";
 	if (i == 0) {
 		const char *str = "vnd.ms-office";
@@ -294,9 +305,10 @@ out1:
         free(sat.sat_tab);
 out0:
         if (i != 1) {
-                if (file_printf(ms, "Composite Document File V2 Document")
-		    == -1)
-                        return -1;
+		if (i == -1)
+		    if (file_printf(ms, "Composite Document File V2 Document")
+			== -1)
+			    return -1;
                 if (*expn)
                         if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
                                 return -1;