/** * 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); }
static GsfInput * gsf_infile_tar_child_by_index (GsfInfile *infile, int target, GError **err) { GsfInfileTar *tar = GSF_INFILE_TAR (infile); const TarChild *c; if (err) *err = NULL; if (target < 0 || (unsigned)target >= tar->children->len) return NULL; c = &g_array_index (tar->children, TarChild, target); if (c->dir) return g_object_ref (c->dir); else { GsfInput *input = gsf_input_proxy_new_section (tar->source, c->offset, c->length); gsf_input_set_name (input, c->name); return input; } }