Example #1
0
/* returns TRUE on error */
static gboolean
zip_child_init (GsfInfileZip *child, GError **errmsg)
{
	static guint8 const header_signature[] =
		{ 'P', 'K', 0x03, 0x04 };
	guint8 const *data = NULL;
	guint16 name_len, extras_len;
	char *err = NULL;

	GsfZipDirent *dirent = child->vdir->dirent;

	/* skip local header
	 * should test tons of other info, but trust that those are correct
	 **/

	if (gsf_input_seek (child->source, (gsf_off_t) dirent->offset, G_SEEK_SET))
		err = g_strdup_printf ("Error seeking to zip header @ %" GSF_OFF_T_FORMAT,
				       dirent->offset);
	else if (NULL == (data = gsf_input_read (child->source, ZIP_FILE_HEADER_SIZE, NULL)))
		err = g_strdup_printf ("Error reading %d bytes in zip header", ZIP_FILE_HEADER_SIZE);
	else if (0 != memcmp (data, header_signature, sizeof (header_signature))) {
		err = g_strdup_printf ("Error incorrect zip header @ %" GSF_OFF_T_FORMAT,
				       dirent->offset);
		g_print ("Header is :\n");
		gsf_mem_dump (data, sizeof (header_signature));
		g_print ("Header should be :\n");
		gsf_mem_dump (header_signature, sizeof (header_signature));
	}

	if (NULL != err) {
		if (errmsg != NULL)
			*errmsg = g_error_new_literal (gsf_input_error_id (), 0, err);
		g_free (err);
		return TRUE;
	}

	name_len =   GSF_LE_GET_GUINT16 (data + ZIP_FILE_HEADER_NAME_SIZE);
	extras_len = GSF_LE_GET_GUINT16 (data + ZIP_FILE_HEADER_EXTRAS_SIZE);

	dirent->data_offset = dirent->offset + ZIP_FILE_HEADER_SIZE + name_len + extras_len;
	child->restlen  = dirent->usize;
	child->crestlen = dirent->csize;

	if (dirent->compr_method != GSF_ZIP_STORED) {
		int err;

		if (!child->stream)
			child->stream = g_new0 (z_stream, 1);

		err = inflateInit2 (child->stream, -MAX_WBITS);
		if (err != Z_OK) {
			if (errmsg != NULL)
				*errmsg = g_error_new (gsf_input_error_id (), 0,
						       "problem uncompressing stream");
			return TRUE;
		}
	}

	return FALSE;
}
Example #2
0
PangoAttrList *
ms_container_read_markup (MSContainer const *c,
			  guint8 const *data, size_t txo_len,
			  char const *str)
{
	TXORun txo_run;
	size_t str_len;

	XL_CHECK_CONDITION_VAL (txo_len >= 16,
				pango_attr_list_new ()); /* min two records */

	str_len = g_utf8_strlen (str, -1);

	txo_run.last = G_MAXINT;
	txo_run.accum = NULL;
	for (txo_len -= 16 ; (gssize)txo_len >= 0 ; txo_len -= 8) {
		guint16 o = GSF_LE_GET_GUINT16 (data + txo_len);
		guint16 idx = GSF_LE_GET_GUINT16 (data + txo_len + 2);

		XL_CHECK_CONDITION_VAL (o <= str_len, txo_run.accum);
		txo_run.first = g_utf8_offset_to_pointer (str, o) - str;
		XL_CHECK_CONDITION_VAL (txo_run.first < txo_run.last, txo_run.accum);

		if (idx != 0) {
			if (!txo_run.accum)
				txo_run.accum = pango_attr_list_new ();
			pango_attr_list_filter
				(ms_container_get_markup (c, idx),
				 (PangoAttrFilterFunc) append_txorun,
				 &txo_run);
		}
		txo_run.last = txo_run.first;
	}
	return txo_run.accum;
}
Example #3
0
static guint8 const *
qpro_get_record (QProReadState *state, guint16 *id, guint16 *len)
{
	guint8 const *data;

	data = gsf_input_read (state->input, 4, NULL);
	Q_CHECK_CONDITION (data != NULL);

	*id  = GSF_LE_GET_GUINT16 (data + 0);
	*len = GSF_LE_GET_GUINT16 (data + 2);

#if 0
	g_printerr ("%hd with %hd\n", *id, *len);
#endif

	if (*len == 0)
		return "";

	data = gsf_input_read (state->input, *len, NULL);

	switch (*id) {
	case QPRO_UNDOCUMENTED_837:
	case QPRO_UNDOCUMENTED_907:
		break; /* Nothing. */
	default:
		Q_CHECK_CONDITION (*len < 0x2000);
	}

	Q_CHECK_CONDITION (data != NULL);

	return data;

error:
	return NULL;
}
Example #4
0
static GsfZipDirent *
zip_dirent_new_in (GsfInfileZip *zip, gsf_off_t *offset)
{
	static guint8 const dirent_signature[] =
		{ 'P', 'K', 0x01, 0x02 };
	GsfZipDirent *dirent;
	guint8 const *data;
	guint16 name_len, extras_len, comment_len, compr_method, flags;
	guint32 crc32, csize, usize, off;
	gchar *name;

	/* Read data and check the header */
	if (gsf_input_seek (zip->source, *offset, G_SEEK_SET) ||
	    NULL == (data = gsf_input_read (zip->source, ZIP_DIRENT_SIZE, NULL)) ||
	    0 != memcmp (data, dirent_signature, sizeof (dirent_signature))) {
		return NULL;
	}

	name_len =      GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_NAME_SIZE);
	extras_len =    GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_EXTRAS_SIZE);
	comment_len =   GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_COMMENT_SIZE);

	flags =         GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_FLAGS);
	compr_method =  GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_COMPR_METHOD);
	crc32 =         GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CRC32);
	csize =         GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CSIZE);
	usize =         GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_USIZE);
	off =           GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_OFFSET);

	if ((data = gsf_input_read (zip->source, name_len, NULL)) == NULL)
		return NULL;

	name = g_new (gchar, (gulong) (name_len + 1));
	memcpy (name, data, name_len);
	name[name_len] = '\0';

	dirent = gsf_zip_dirent_new ();
	dirent->name = name;

	dirent->flags = flags;
	dirent->compr_method =  compr_method;
	dirent->crc32 =         crc32;
	dirent->csize =         csize;
	dirent->usize =         usize;
	dirent->offset =        off;
#if 0
	g_print ("%s = 0x%x @ %" GSF_OFF_T_FORMAT "\n", name, off, *offset);
#endif

	*offset += ZIP_DIRENT_SIZE + name_len + extras_len + comment_len;

	return dirent;
}
Example #5
0
/** Given a data pointer, returns a color string (like cccccc for a medium gray).
 * throws BOGUS_DOCUMENT on error. */
UT_String makeColor(UT_uint8* aData, UT_uint32 aDataLen) {
	// from tools/source/generic/color.cxx line 183ff
	#define COL_NAME_USER		(0x8000)
	#define COL_RED_1B			(0x0001)
	#define COL_RED_2B			(0x0002)
	#define COL_GREEN_1B		(0x0010)
	#define COL_GREEN_2B		(0x0020)
	#define COL_BLUE_1B 		(0x0100)
	#define COL_BLUE_2B 		(0x0200)

	UT_String rv;
	if (aDataLen < 2)
		throw UT_IE_BOGUSDOCUMENT;
	UT_uint16 colorName = GSF_LE_GET_GUINT16(aData);
	if (colorName & COL_NAME_USER) {
		// XXX TODO. Awaiting reply in mailinglist about what CompressMode is.
		return "000000";
	}
	else {
		if (colorName < COLOR_SIZE) {
			UT_String_sprintf(rv, "%02x%02x%02x", gColors[colorName].red,
			                  gColors[colorName].green, gColors[colorName].blue);
			return rv;
		}
		else {
			UT_DEBUGMSG(("SDW: COLOR OUT OF RANGE! has num %u\n", colorName));
			return "000000";
		}
			
	}
}
Example #6
0
static gboolean
qpro_check_signature (GsfInput *input)
{
	guint8 const *header;
	guint16 version;

	if (gsf_input_seek (input, 0, G_SEEK_SET) ||
	    NULL == (header = gsf_input_read (input, 2+2+2, NULL)) ||
	    GSF_LE_GET_GUINT16 (header + 0) != 0 ||
	    GSF_LE_GET_GUINT16 (header + 2) != 2)
		return FALSE;
	version = GSF_LE_GET_GUINT16 (header + 4);
	return (version == 0x1001 || /* 'WB1' format, documented */
		version == 0x1002 || /* 'WB2' format, documented */
		version == 0x1006 ||  /* qpro 6.0 ?? */
		version == 0x1007);  /* qpro 7.0 ?? */
}
Example #7
0
/**
 * gsf_vba_inflate:
 * @input: stream to read from
 * @offset: offset into it for start byte of compressed stream
 * @size: size of the returned array
 * @add_null_terminator: whenever add or not null at the end of array
 * 
 * Decompresses VBA stream.
 * 
 * Return value: A pointer to guint8 array
 **/
guint8 *
gsf_vba_inflate (GsfInput *input, gsf_off_t offset, int *size, gboolean add_null_terminator)
{
	guint8 sig;
	GByteArray *res;
	gsf_off_t length;

	res = g_byte_array_new();

	gsf_input_read (input, 1, &sig);
	if (1 != sig) /* should start with 0x01 */
		return NULL;
	offset++;

	length = gsf_input_size (input);
	while (offset < length) {
		GsfInput *chunk;
		guint16 chunk_hdr;
		guint8 const *tmp;

		tmp = gsf_input_read (input, 2, NULL);
		if (!tmp)
			break;

		chunk_hdr = GSF_LE_GET_GUINT16 (tmp);
		offset += 2;

		if (0xB000 == (chunk_hdr&0xF000) && (chunk_hdr&0xFFF) > 0 && (length - offset < 4094)){
			if (length < offset + (chunk_hdr&0xFFF))
				break;
			chunk = gsf_input_proxy_new_section (input, offset, (gsf_off_t) (chunk_hdr&0xFFF) + 1);
			offset += (chunk_hdr&0xFFF) + 1;
		} else {
			if (length < offset + 4094){
				chunk = gsf_input_proxy_new_section (input, offset, length-offset);
				offset = length;
			} else {
				chunk = gsf_input_proxy_new_section (input, offset, 4094);
				offset += 4094;
			}
		}
		if (chunk) {
			GByteArray *tmpres = gsf_msole_inflate (chunk, 0);
			gsf_input_seek (input, offset, G_SEEK_CUR);
			g_byte_array_append (res, tmpres->data, tmpres->len);
			g_byte_array_free (tmpres, TRUE);
			g_object_unref (chunk);
		}
	}
	
	if (res == NULL)
		return NULL;
	if (add_null_terminator)
		g_byte_array_append (res, "", 1);
	*size = res->len;

	return g_byte_array_free (res, FALSE);
}
Example #8
0
static void
dump_biff_stream (GsfInput *stream)
{
	guint8 const *data;
	guint16 len, opcode;
	unsigned pos = gsf_input_tell (stream);

	while (NULL != (data = gsf_input_read (stream, 4, NULL))) {
		gboolean enable_dump = TRUE;

		opcode	= GSF_LE_GET_GUINT16 (data);
		len	= GSF_LE_GET_GUINT16 (data+2);

		if (len > 15000) {
			enable_dump = TRUE;
			g_warning ("Suspicious import of biff record > 15,000 (0x%x) for opcode 0x%hx",
				   len, opcode);
		} else if ((opcode & 0xff00) > 0x1000) {
			enable_dump = TRUE;
			g_warning ("Suspicious import of biff record with opcode 0x%hx",
				   opcode);
		}

		if (enable_dump)
			printf ("Opcode 0x%3hx : %15s, length 0x%hx (=%hd)\n",
				opcode, get_biff_opcode_name (opcode),
				len, len);

		if (len > 0) {
			data = gsf_input_read (stream, len, NULL);
			if (data == NULL)
				break;
			if (enable_dump)
				gsf_mem_dump (data, len);
		}
		pos = gsf_input_tell (stream);
	}
}
Example #9
0
void streamRead(GsfInput* aStream, TextAttr& aAttr, gsf_off_t aEoa)
    throw(UT_Error)
{
	UT_uint8 flags;
	gsf_off_t newPos;
	readFlagRec(aStream, flags, &newPos);

	streamRead(aStream, aAttr.which);
	streamRead(aStream, aAttr.ver);
	if (flags & 0x10) {
		aAttr.startSet = true;
		streamRead(aStream, aAttr.start);
	}
	else
		aAttr.startSet = false;

	if (flags & 0x20) {
		aAttr.endSet = true;
		streamRead(aStream, aAttr.end);
	}
	else
		aAttr.endSet = false;

	if (gsf_input_seek(aStream, newPos, G_SEEK_SET))
		throw UT_IE_BOGUSDOCUMENT;

	gsf_off_t curPos = gsf_input_tell(aStream);
	if (curPos != aEoa) {
		// there is data
		aAttr.dataLen = aEoa - curPos;
		aAttr.data = new UT_uint8[aAttr.dataLen];
		streamRead(aStream, aAttr.data, aAttr.dataLen);
	}
  // LIST OF THE VALUES: http://ooo.ximian.com/lxr/source/sw/sw/inc/hintids.hxx#086
  // together with http://ooo.ximian.com/lxr/source/sw/sw/source/core/sw3io/sw3fmts.cxx#172
	switch (aAttr.which) {
		case 0x1004: // strikethrough
			aAttr.attrName = "text-decoration";
			if (!aAttr.data || aAttr.data[0])
				aAttr.attrVal = "line-through";
			else
				aAttr.isOff = true;
			break;
		case 0x1005: { // sub-/superscript
			if (aAttr.dataLen < 3)
				break;
			// first byte is size of text % of normal size
			UT_sint16 height = GSF_LE_GET_GINT16(aAttr.data + 1);	
			aAttr.attrName = "text-position";
			if (height > 0)
				aAttr.attrVal = "superscript";
			else if (height < 0)
				aAttr.attrVal = "subscript";
			else
				aAttr.isOff = true;
			break; }
		case 0x1006: { // font family
			if (!aAttr.data || aAttr.dataLen < 7)
				// 7 = 3 byte family etc., 2 byte name length, 2 byte style length
				break;
			aAttr.attrName = "font-family";
			// XXX TODO This code here assumes that the font names are in latin1
			UT_uint16 fontLen = GSF_LE_GET_GUINT16(aAttr.data + 3);
			UT_String_sprintf(aAttr.attrVal, "%.*s", fontLen, (aAttr.data + 5));
			
		break; }
    case 0x1007: // font height
      // structure: | height (2 byte, twips) | prop (?) (2 byte) (if version >= 2, if ver=1 1 byte) | unit (if version>=2) |
      // XXX we ignore "prop" and unit for now, they seem not used much
      aAttr.attrName = "font-size";
      if (aAttr.data)
        aAttr.attrVal = twipsToSizeString(GSF_LE_GET_GUINT16(aAttr.data));
      break;
		case 0x100a: // Italic
			aAttr.attrName = "font-style";
			if (!aAttr.data || aAttr.data[0]) // if there is data, first byte must be != 0
				// abiword doesn't support oblique, so always set italic
				aAttr.attrVal = "italic";
			else
				aAttr.isOff = true;
			break;
		case 0x100d: // Underline
			aAttr.attrName = "text-decoration";
			if (!aAttr.data || aAttr.data[0])
				aAttr.attrVal = "underline";
			else
				aAttr.isOff = true;
			break;
		case 0x100e: // Bold
			aAttr.attrName = "font-weight";
			if (!aAttr.data || aAttr.data[0] >= 8) // 8=Bold.
				aAttr.attrVal = "bold";
			else
				aAttr.isOff = true;
			break;
    case 0x4000: // line spacing
      aAttr.attrName = "line-height";
      aAttr.isPara = true;
      // prop space (s8) | inter space (s16) | height (u16) | rule (s8) | interrule (s8)
      if (aAttr.data && aAttr.dataLen >= 7) {
        // Abiword wants it as float value, StarOffice saves as percentage (e.g.
        // 150 for 1.5)
        float proportionalLineSpace = float(aAttr.data[0])/100;
        // But maybe we need to use the height - stored as twips, need points
        // (used for "exact" and "minimum" line spacing)
        // XXX inter-line spacing not supported by abiword (would be rule=0x00
        // interrule=0x02, value to use=inter space, unit twips)
        UT_String lineHeight = twipsToSizeString(GSF_LE_GET_GINT16(aAttr.data + 3));

        // We'll turn the bytes at 5 and 6 into a single integer, for easier
        // evaluation
        switch (GSF_LE_GET_GUINT16(aAttr.data + 5)) {
          case 0x0100: // proportional
            aAttr.attrVal = std_size_string(proportionalLineSpace);
            break;
          case 0x0001:
          case 0x0002:
            aAttr.attrVal = lineHeight;
            if (aAttr.data[5] == 2) // "minimum" case
              aAttr.attrVal += '+';
            break;
          default:
            UT_DEBUGMSG(("Unsupported linespacing: %02x %02x\n", aAttr.data[5], aAttr.data[6]));
        }
      }
      break;
		case 0x4001: // Alignment
			aAttr.attrName = "text-align";
			aAttr.isPara = true;
			if (aAttr.data) {
				switch (aAttr.data[0]) {
					case 0:
						aAttr.attrVal = "left";
						break;
					case 1:
						aAttr.attrVal = "right";
						break;
					case 2:
					case 4: // BLOCKLINE!? what's BLOCKLINE? I'm guessing justify.
						aAttr.attrVal = "justify";
						break;
					case 3:
						aAttr.attrVal = "center";
						break;
				}
			}
      break;
    case 0x4005: {// Tabstops
      aAttr.attrName = "tabstops";
      aAttr.isPara = true;
      // Data structure:
      // Count(8) | Position (in twips) (32) | Adjustment (8) | Decimal Separator (?) (8) | Fill character (8)
      // (total size per tab = 7)
      // UT_sint8 count = aAttr.data[0];
      for (UT_uint32 i = 1; (i + 6) < aAttr.dataLen; i += 7) {
        // Abiword wants: 12.3cm/L0, where 0 indicates what to fill with
        UT_uint16 posInTwips = GSF_LE_GET_GUINT32(aAttr.data + i);
        UT_String pos = twipsToSizeString(posInTwips);

        aAttr.attrVal += pos;
        aAttr.attrVal += '/';
        if (aAttr.data[i + 4] < sizeof(sTabAlignment)/sizeof(*sTabAlignment))
          aAttr.attrVal += sTabAlignment[aAttr.data[i + 4]];
        else
          aAttr.attrVal += 'L'; // fallback

        char fillIndex = '0';
        // Fill character
        switch (aAttr.data[i + 6]) {
          case '.':
            fillIndex = '1';
            break;
          case '-':
            fillIndex = '2';
            break;
          case '_':
            fillIndex = '3';
            break;
          case ' ':
            fillIndex = '0';
            break;
          default:
            UT_DEBUGMSG(("Filling with '%c' is not supported\n", aAttr.data[i + 6]));
        }
        aAttr.attrVal += fillIndex;
        aAttr.attrVal += ',';
      }
      }
      break;
    default:
      UT_DEBUGMSG(("SDW: unknown attribute 0x%x, compressed %d\n", aAttr.which, lcl_sw3io__CompressWhich(aAttr.which)));
	}

}
Example #10
0
static void
qpro_parse_formula (QProReadState *state, int col, int row,
		    guint8 const *data, guint8 const *end)
{
	guint16 magic, ref_offset;
#if 0
	int flags = GSF_LE_GET_GUINT16 (data + 8);
	int length = GSF_LE_GET_GUINT16 (data + 10);
#endif
	GnmValue   *val;
	GSList *stack = NULL;
	GnmExprTop const *texpr = NULL;
	guint8 const *refs, *fmla;

#ifdef DEBUG_MISSING
	dump_missing_functions ();
#endif

	Q_CHECK_CONDITION (end - data >= 14);
	magic = GSF_LE_GET_GUINT16 (data + 6) & 0x7ff8;
	ref_offset = GSF_LE_GET_GUINT16 (data + 12);

	fmla = data + 14;
	refs = fmla + ref_offset;
	Q_CHECK_CONDITION (refs <= end);

#if 0
	puts (cell_coord_name (col, row));
	gsf_mem_dump (data, 14);
	gsf_mem_dump (fmla, refs-fmla);
	gsf_mem_dump (refs, end-refs);
#endif

	while (fmla < refs && *fmla != QPRO_OP_EOF) {
		QProOperators op = *fmla++;
		GnmExpr const *expr = NULL;
#if 0
		g_print ("Operator %d.\n", op);
#endif
		switch (op) {
		case QPRO_OP_CONST_FLOAT:
			Q_CHECK_CONDITION (refs - fmla >= 8);
			expr = gnm_expr_new_constant (value_new_float (
				gsf_le_get_double (fmla)));
			fmla += 8;
			break;

		case QPRO_OP_CELLREF: {
			GnmCellRef ref;
			guint16 tmp;

			Q_CHECK_CONDITION (end - refs >= 6);
			tmp = GSF_LE_GET_GUINT16 (refs + 4);
			ref.sheet = NULL;
			ref.col = *((gint8 *)(refs + 2));
			ref.col_relative = (tmp & 0x4000) ? TRUE : FALSE;
			ref.row_relative = (tmp & 0x2000) ? TRUE : FALSE;
			if (ref.row_relative)
				ref.row = (int)(((gint16)((tmp & 0x1fff) << 3)) >> 3);
			else
				ref.row = tmp & 0x1fff;
			expr = gnm_expr_new_cellref (&ref);
			refs += 6;
			break;
		}

		case QPRO_OP_RANGEREF: {
			GnmCellRef a, b;
			guint16 tmp;

			Q_CHECK_CONDITION (end - refs >= 10);

			tmp = GSF_LE_GET_GUINT16 (refs + 4);
			a.sheet = NULL;
			a.col = *((gint8 *)(refs + 2));
			a.col_relative = (tmp & 0x4000) ? TRUE : FALSE;
			a.row_relative = (tmp & 0x2000) ? TRUE : FALSE;
			if (a.row_relative)
				a.row = (int)(((gint16)((tmp & 0x1fff) << 3)) >> 3);
			else
				a.row = tmp & 0x1fff;

			tmp = GSF_LE_GET_GUINT16 (refs + 8);
			b.sheet = NULL;
			b.col = *((gint8 *)(refs + 6));
			b.col_relative = (tmp & 0x4000) ? TRUE : FALSE;
			b.row_relative = (tmp & 0x2000) ? TRUE : FALSE;
			if (b.row_relative)
				b.row = (int)(((gint16)((tmp & 0x1fff) << 3)) >> 3);
			else
				b.row = tmp & 0x1fff;

			expr = gnm_expr_new_constant (
				value_new_cellrange_unsafe (&a, &b));
			refs += 10;
			break;
		}
Example #11
0
static gboolean
check_header (GsfInputGZip *input)
{
	if (input->raw) {
		input->header_size = 0;
		input->trailer_size = 0;
	} else {
		static guint8 const signature[2] = {0x1f, 0x8b};
		guint8 const *data;
		unsigned flags, len;

		/* Check signature */
		if (NULL == (data = gsf_input_read (input->source, 2 + 1 + 1 + 6, NULL)) ||
		    0 != memcmp (data, signature, sizeof (signature)))
			return TRUE;

		/* verify flags and compression type */
		flags  = data[3];
		if (data[2] != Z_DEFLATED || (flags & ~GZIP_HEADER_FLAGS) != 0)
			return TRUE;

		/* If we have the size, don't bother seeking to the end.  */
		if (input->uncompressed_size < 0) {
			/* Get the uncompressed size */
			if (gsf_input_seek (input->source, (gsf_off_t) -4, G_SEEK_END) ||
			    NULL == (data = gsf_input_read (input->source, 4, NULL)))
				return TRUE;
			/* FIXME, but how?  The size read here is modulo 2^32.  */
			input->uncompressed_size = GSF_LE_GET_GUINT32 (data);

			if (input->uncompressed_size / 1000 > gsf_input_size (input->source)) {
				g_warning ("Suspiciously well compressed file with better than 1000:1 ratio.\n"
					   "It is probably truncated or corrupt");
			}
		}

		if (gsf_input_seek (input->source, 2 + 1 + 1 + 6, G_SEEK_SET))
			return TRUE;

		if (flags & GZIP_EXTRA_FIELD) {
			if (NULL == (data = gsf_input_read (input->source, 2, NULL)))
				return TRUE;
			len = GSF_LE_GET_GUINT16 (data);
			if (NULL == gsf_input_read (input->source, len, NULL))
				return TRUE;
		}
		if (flags & GZIP_ORIGINAL_NAME) {
			/* Skip over the filename (which is in ISO 8859-1 encoding).  */
			do {
				if (NULL == (data = gsf_input_read (input->source, 1, NULL)))
					return TRUE;
			} while (*data != 0);
		}

		if (flags & GZIP_HAS_COMMENT) {
			/* Skip over the comment (which is in ISO 8859-1 encoding).  */
			do {
				if (NULL == (data = gsf_input_read (input->source, 1, NULL)))
					return TRUE;
			} while (*data != 0);
		}

		if (flags & GZIP_HEADER_CRC &&
		    NULL == (data = gsf_input_read (input->source, 2, NULL)))
			return TRUE;

		input->header_size = input->source->cur_offset;
		/* the last 8 bytes are the crc and size.  */
		input->trailer_size = 8;
	}

	gsf_input_set_size (GSF_INPUT (input), input->uncompressed_size);

	if (gsf_input_remaining (input->source) < input->trailer_size)
		return TRUE;	/* No room for payload */

	return FALSE;
}
Example #12
0
/**
 * vba_project_read:
 * @vba: #GsfInfileMSVBA
 * @err: (allow-none): place to store a #GError if anything goes wrong
 *
 * Read an VBA dirctory and its project file.
 * along the way.
 *
 * Returns: %FALSE on error setting @err if it is supplied.
 **/
static gboolean
vba_project_read (GsfInfileMSVBA *vba, GError **err)
{
	/* NOTE : This seems constant, find some confirmation */
	static guint8 const signature[]	  = { 0xcc, 0x61 };
	static struct {
		guint8 const signature[4];
		char const * const name;
		int const vba_version;
		gboolean const is_mac;
	} const  versions [] = {
		{ { 0x5e, 0x00, 0x00, 0x01 }, "Office 97",              5, FALSE},
		{ { 0x5f, 0x00, 0x00, 0x01 }, "Office 97 SR1",          5, FALSE },
		{ { 0x65, 0x00, 0x00, 0x01 }, "Office 2000 alpha?",     6, FALSE },
		{ { 0x6b, 0x00, 0x00, 0x01 }, "Office 2000 beta?",      6, FALSE },
		{ { 0x6d, 0x00, 0x00, 0x01 }, "Office 2000",            6, FALSE },
		{ { 0x6f, 0x00, 0x00, 0x01 }, "Office 2000",            6, FALSE },
		{ { 0x70, 0x00, 0x00, 0x01 }, "Office XP beta 1/2",     6, FALSE },
		{ { 0x73, 0x00, 0x00, 0x01 }, "Office XP",              6, FALSE },
		{ { 0x76, 0x00, 0x00, 0x01 }, "Office 2003",            6, FALSE },
		{ { 0x79, 0x00, 0x00, 0x01 }, "Office 2003",            6, FALSE },
		{ { 0x60, 0x00, 0x00, 0x0e }, "MacOffice 98",           5, TRUE },
		{ { 0x62, 0x00, 0x00, 0x0e }, "MacOffice 2001",         5, TRUE },
		{ { 0x63, 0x00, 0x00, 0x0e }, "MacOffice X",		6, TRUE },
		{ { 0x64, 0x00, 0x00, 0x0e }, "MacOffice 2004",         6, TRUE },
	};

	guint8 const *data;
	unsigned i, count, len;
	gunichar2 *uni_name;
	char *name;
	GsfInput *dir;

	dir = gsf_infile_child_by_name (vba->source, "dir");
	if (dir == NULL) {
		if (err != NULL)
			*err = g_error_new (gsf_input_error_id (), 0,
					    _("Can't find the VBA directory stream"));
		return FALSE;
	}

	if (gsf_input_seek (dir, 0, G_SEEK_SET) ||
	    NULL == (data = gsf_input_read (dir, VBA56_DIRENT_HEADER_SIZE, NULL)) ||
	    0 != memcmp (data, signature, sizeof (signature))) {
		if (err != NULL)
			*err = g_error_new (gsf_input_error_id (), 0,
					    _("No VBA signature"));
		return FALSE;
	}

	for (i = 0 ; i < G_N_ELEMENTS (versions); i++)
		if (!memcmp (data+2, versions[i].signature, 4))
			break;

	if (i >= G_N_ELEMENTS (versions)) {
		if (err != NULL)
			*err = g_error_new (gsf_input_error_id (), 0,
					    _("Unknown VBA version signature 0x%x%x%x%x"),
					    data[2], data[3], data[4], data[5]);
		return FALSE;
	}

	puts (versions[i].name);

	/* these depend strings seem to come in 2 blocks */
	count = GSF_LE_GET_GUINT16 (data + VBA56_DIRENT_RECORD_COUNT);
	for (; count > 0 ; count--) {
		if (NULL == ((data = gsf_input_read (dir, 2, NULL))))
			break;
		len = GSF_LE_GET_GUINT16 (data);
		if (NULL == ((data = gsf_input_read (dir, len, NULL)))) {
			printf ("len == 0x%x ??\n", len);
			break;
		}

		uni_name = g_new0 (gunichar2, len/2 + 1);

		/* be wary about endianness */
		for (i = 0 ; i < len ; i += 2)
			uni_name [i/2] = GSF_LE_GET_GUINT16 (data + i);
		name = g_utf16_to_utf8 (uni_name, -1, NULL, NULL, NULL);
		g_free (uni_name);

		printf ("%d %s\n", count, name);

		/* ignore this blob ???? */
		if (!strncmp ("*\\G", name, 3)) {
			if (NULL == ((data = gsf_input_read (dir, 12, NULL)))) {
				printf ("len == 0x%x ??\n", len);
				break;
			}
		}

		g_free (name);
	}

	g_return_val_if_fail (count == 0, FALSE);

	return TRUE;
}
Example #13
0
/**
 * vba_dir_read:
 * @vba: #GsfInfileMSVBA
 * @err: (allow-none): place to store a #GError if anything goes wrong
 *
 * Read an VBA dirctory and its project file.
 * along the way.
 *
 * Returns: %FALSE on error setting @err if it is supplied.
 **/
static gboolean
vba_dir_read (GsfInfileMSVBA *vba, GError **err)
{
	int inflated_size, element_count = -1;
	char const *msg = NULL;
	char *name, *elem_stream = NULL;
	guint32 len;
	guint16 tag;
	guint8   *inflated_data, *end, *ptr;
	GsfInput *dir;
	gboolean  failed = TRUE;

	/* 0. get the stream */
	dir = gsf_infile_child_by_name (vba->source, "dir");
	if (dir == NULL) {
		msg = _("Can't find the VBA directory stream");
		goto fail_stream;
	}

	/* 1. decompress it */
	ptr = inflated_data = gsf_vba_inflate (dir, 0, &inflated_size, TRUE);
	if (inflated_data == NULL)
		goto fail_compression;
	end = inflated_data + inflated_size;

	/* 2. GUESS : based on several xls with macros and XL8GARY this looks like a
	 * series of sized records.  Be _extra_ careful */
	do {
		/* I have seen
		 * type		len	data
		 *  1		 4	 1 0 0 0
		 *  2		 4	 9 4 0 0
		 *  3		 2	 4 e4
		 *  4		<var>	 project name
		 *  5		 0
		 *  6		 0
		 *  7		 4
		 *  8		 4
		 *  0x3d	 0
		 *  0x40	 0
		 *  0x14	 4	 9 4 0 0
		 *
		 *  0x0f == number of elements
		 *  0x1c == (Size 0)
		 *  0x1e == (Size 4)
		 *  0x48 == (Size 0)
		 *  0x31 == stream offset of the compressed source !
		 *
		 *  0x16 == an ascii dependency name
		 *  0x3e == a unicode dependency name
		 *  0x33 == a classid for a dependency with no trialing data
		 *
		 *  0x2f == a dummy classid
		 *  0x30 == a classid
		 *  0x0d == the classid
		 *  0x2f, and 0x0d appear contain
		 * 	uint32 classid_size;
		 * 	<classid>
		 *	00 00 00 00 00 00
		 *	and sometimes some trailing junk
		 **/
		if ((ptr + 6) > end) {
			msg = _("vba project header problem");
			goto fail_content;
		}
		tag = GSF_LE_GET_GUINT16 (ptr);
		len = GSF_LE_GET_GUINT32 (ptr + 2);

		ptr += 6;
		if ((ptr + len) > end) {
			msg = _("vba project header problem");
			goto fail_content;
		}

		switch (tag) {
		case 4:
			name = g_strndup (ptr, len);
#ifdef OLD_VBA_DUMP
			puts ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			printf ("<project name=\"%s\">", name);
#endif
			g_free (name);
			break;
		case 9:
			/* this seems to have an extra two bytes that are not
			 * part of the length ..?? */
			len += 2;
			break;
		case 0xf  :
			if (len != 2) {
				g_warning ("element count is not what we expected");
				break;
			}
			if (element_count >= 0) {
				g_warning ("More than one element count ??");
				break;
			}
			element_count = GSF_LE_GET_GUINT16 (ptr);
			break;

		/* dependencies */
		case 0x0d : break;
		case 0x2f : break;
		case 0x30 : break;
		case 0x33 : break;
		case 0x3e : break;
		case 0x16:
#if 0
			name = g_strndup (ptr, len);
			g_print ("Depend Name : '%s'\n", name);
			g_free (name);
#endif
			break;

		/* elements */
		case 0x47 : break;
		case 0x32 : break;
		case 0x1a:
#if 0
			name = g_strndup (ptr, len);
			g_print ("Element Name : '%s'\n", name);
			g_free (name);
#endif
			break;
		case 0x19:
			g_free (elem_stream);
			elem_stream = g_strndup (ptr, len);
			break;

		case 0x31:
			if (len != 4) {
				g_warning ("source offset property is not what we expected");
				break;
			}
			vba_extract_module_source (vba, elem_stream,
				GSF_LE_GET_GUINT32 (ptr));
			g_free (elem_stream); elem_stream = NULL;
			element_count--;
			break;

		default :
#if 0
			g_print ("tag %hx : len %u\n", tag, len);
			gsf_mem_dump (ptr, len);
#endif
			break;
		}

		ptr += len;
	} while (tag != 0x10);

	if (element_count != 0)
		g_warning ("Number of elements differs from expectations");

	failed = FALSE;

fail_content :
	g_free (inflated_data);
#ifdef OLD_VBA_DUMP
	puts ("</project>");
#endif

fail_compression :
	g_object_unref (dir);
fail_stream :

	g_free (elem_stream);

	if (failed) {
		if (err != NULL)
			*err = g_error_new_literal (gsf_input_error_id (), 0, msg);
		return FALSE;
	}

	return TRUE;
}