/** * Code from Dom Lachowicz and/or Robert Staudinger. */ UT_Error ODi_Abi_Data::_loadStream (GsfInfile* oo, const char* stream, UT_ByteBuf& buf ) { guint8 const *data = NULL; size_t len = 0; static const size_t BUF_SZ = 4096; buf.truncate (0); GsfInput * input = gsf_infile_child_by_name(oo, stream); if (!input) return UT_ERROR; if (gsf_input_size (input) > 0) { while ((len = gsf_input_remaining (input)) > 0) { len = UT_MIN (len, BUF_SZ); if (NULL == (data = gsf_input_read (input, len, NULL))) { g_object_unref (G_OBJECT (input)); return UT_ERROR; } buf.append ((const UT_Byte *)data, len); } } g_object_unref (G_OBJECT (input)); return UT_OK; }
/** * Static utility method to read a file/stream embedded inside of the * zipfile into an xml parser */ UT_Error IE_Imp_OpenDocument::_parseStream (GsfInput* pInput, UT_XML & parser) { guint8 const *data = NULL; size_t len = 0; UT_Error ret = UT_OK; UT_return_val_if_fail(pInput, UT_ERROR); if (gsf_input_size (pInput) > 0) { while ((len = gsf_input_remaining (pInput)) > 0) { // FIXME: we want to pass the stream in chunks, but libXML2 finds this disagreeable. // we probably need to pass some magic to our XML parser? // len = UT_MIN (len, BUF_SZ); if (NULL == (data = gsf_input_read (pInput, len, NULL))) { g_object_unref (G_OBJECT (pInput)); return UT_ERROR; } ret = parser.parse ((const char *)data, len); } // if there is an error we think we can recover. if(ret != UT_OK) { ret = UT_IE_TRY_RECOVER; } } return ret; }
static void clone(GsfInput * input, GsfOutput * output) { guint8 const *data; size_t len; int i; if (gsf_input_size(input) > 0) { while ((len = gsf_input_remaining(input)) > 0) { /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read(input, len, NULL))) { g_warning("error reading ?"); return; } if (!gsf_output_write(output, len, data)) { g_warning("error writing ?"); return; } } } gsf_output_close(output); g_object_unref(G_OBJECT(output)); g_object_unref(G_OBJECT(input)); }
/** * gsf_structured_blob_read: * @input: An input (potentially a GsfInfile) holding the blob * * Create a tree of binary blobs with unknown content from a #GsfInput or * #GsfInfile and store it in a newly created #GsfStructuredBlob. * * Returns: (transfer full): a new #GsfStructuredBlob object which the caller is responsible for. **/ GsfStructuredBlob * gsf_structured_blob_read (GsfInput *input) { GsfStructuredBlob *blob; gsf_off_t content_size; int i = 0; g_return_val_if_fail (GSF_IS_INPUT (input), NULL); blob = g_object_new (GSF_STRUCTURED_BLOB_TYPE, NULL); content_size = gsf_input_remaining (input); if (content_size > 0) { guint8 *buf = (guint8*)g_try_malloc (content_size); if (buf == NULL) { g_warning ("Failed attempting to allocate %" GSF_OFF_T_FORMAT " bytes", content_size); g_object_unref (blob); return NULL; } gsf_input_read (input, content_size, buf); blob->data = gsf_shared_memory_new (buf, content_size, TRUE); } gsf_input_set_name (GSF_INPUT (blob), gsf_input_name (input)); if (GSF_IS_INFILE (input)) i = gsf_infile_num_children (GSF_INFILE (input)); if (i > 0) { GsfInput *child; GsfStructuredBlob *child_blob; blob->children = g_ptr_array_sized_new (i); g_ptr_array_set_size (blob->children, i); while (i-- > 0) { child = gsf_infile_child_by_index (GSF_INFILE (input), i); child_blob = gsf_structured_blob_read (child); g_object_unref (child); g_ptr_array_index (blob->children, i) = child_blob; #if 0 /* * We don't need this, and setting it causes circular * links. */ gsf_input_set_container (GSF_INPUT (child_blob), GSF_INFILE (blob)); #endif } } return blob; }
/*! Detect encoding of text file \param fp File Supports UTF-8 and UCS-2 big and little endian CJK encodings could be added */ UT_Error IE_Imp_Text::_recognizeEncoding(GsfInput * fp) { char szBuf[4096]; // 4096 ought to be enough UT_sint32 iNumbytes; iNumbytes = UT_MIN(4096, gsf_input_remaining(fp)); gsf_input_read(fp, iNumbytes, (guint8 *)szBuf); gsf_input_seek(fp, 0, G_SEEK_SET); return _recognizeEncoding(szBuf, iNumbytes); }
static void zip_thumbnail (GsfInfile *infile, const char *out_filename, int thumb_size) { GsfInput *thumbnail; /* Office Document thumbnail */ if (NULL != (thumbnail = gsf_infile_child_by_vname (infile, "Thumbnails", "thumbnail.png", NULL))) { gsf_off_t len = gsf_input_remaining (thumbnail); guint8 const *data = gsf_input_read (thumbnail, len, NULL); write_thumbnail (out_filename, data, len, thumb_size); g_object_unref (thumbnail); /* Check MS Office Open thumbnail */ } else if (NULL != (thumbnail = gsf_open_pkg_open_rel_by_type (GSF_INPUT(infile), "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail", NULL))) { gsf_off_t len = gsf_input_remaining (thumbnail); guint8 const *data = gsf_input_read (thumbnail, len, NULL); write_thumbnail (out_filename, data, len, thumb_size); g_object_unref (thumbnail); } else show_error_string_and_exit ("Could not find thumbnail in zip file"); }
static void clone (GsfInput *input, GsfOutput *output) { guint8 const *data; size_t len; int i; if (gsf_input_size (input) > 0) { while ((len = gsf_input_remaining (input)) > 0) { /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read (input, len, NULL))) { g_warning ("error reading ?"); return; } if (!gsf_output_write (output, len, data)) { g_warning ("error writing ?"); return; } } } /* See test-cp-msole.c for explanation how to distinct directories * from regular files. */ if (GSF_IS_INFILE (input) && gsf_infile_num_children (GSF_INFILE (input)) > 0) { GsfInfile *in = GSF_INFILE (input); GsfOutfile *out = GSF_OUTFILE (output); GsfInput *src; GsfOutput *dst; gboolean is_dir; for (i = 0 ; i < gsf_infile_num_children (in) ; i++) { src = gsf_infile_child_by_index (in, i); is_dir = GSF_IS_INFILE (src) && gsf_infile_num_children (GSF_INFILE (src)) >= 0; dst = gsf_outfile_new_child (out, gsf_infile_name_by_index (in, i), is_dir); clone (src, dst); } } gsf_output_close (output); g_object_unref (G_OBJECT (output)); g_object_unref (G_OBJECT (input)); }
UT_Error OXMLi_PackageManager::_parseStream( GsfInput * stream, OXMLi_StreamListener * pListener) { UT_return_val_if_fail(stream != NULL && pListener != NULL , UT_ERROR); //First, we check if this stream has already been parsed before std::string part_name = gsf_input_name(stream); //TODO: determine if part names are truly unique std::map<std::string, bool>::iterator it; it = m_parsedParts.find(part_name); if (it != m_parsedParts.end() && it->second) { //this stream has already been parsed successfully return UT_OK; } UT_Error ret = UT_OK; guint8 const *data = NULL; const char * cdata = NULL; size_t len = 0; UT_XML reader; reader.setListener(pListener); if (gsf_input_size (stream) > 0) { len = gsf_input_remaining (stream); if (len > 0) { data = gsf_input_read (stream, len, NULL); if (NULL == data) { g_object_unref (G_OBJECT (stream)); return UT_ERROR; } cdata = (const char *)data; ret = reader.parse (cdata, len); } } //There are two error codes to check here. if (ret == UT_OK && pListener->getStatus() == UT_OK) m_parsedParts[part_name] = true; //We prioritize the one from UT_XML when returning. return ret == UT_OK ? pListener->getStatus() : ret; }
static ArStatus ar_read_header (GsfInput *fp, ArHeader *header) { size_t len; if (fp == NULL || header == NULL) return AR_FAILURE; memset(header, 0, AR_HEADER_LEN); len = gsf_input_remaining (fp); if (len == 0) return AR_EOF; else if (len < AR_HEADER_LEN) return AR_FAILURE; else { gsf_input_read (fp, AR_HEADER_LEN, (guint8*)header); if (strncmp (header->fmag, AR_FMAG, 2)) return AR_FAILURE; return AR_SUCCESS; } }
static void clone_ (GsfInfile *in, GsfOutfile *out) { GsfInput *input = GSF_INPUT (in); GsfOutput *output = GSF_OUTPUT (out); if (gsf_input_size (input) > 0) { size_t len; while ((len = gsf_input_remaining (input)) > 0) { guint8 const *data; /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read (input, len, NULL))) { g_warning ("error reading ?"); break; } if (!gsf_output_write (output, len, data)) { g_warning ("error writing ?"); break; } } } else { int i, n = gsf_infile_num_children (in); for (i = 0 ; i < n; i++) { int level; gboolean is_dir; char const *name = gsf_infile_name_by_index (in, i); char *display_name = name ? g_filename_display_name (name) : NULL; input = gsf_infile_child_by_index (in, i); if (NULL == input) { g_print ("Error opening '%s, index = %d\n", display_name ? display_name : "?", i); g_free (display_name); continue; } is_dir = gsf_infile_num_children (GSF_INFILE (input)) >= 0; g_object_get (G_OBJECT (input), "compression-level", &level, NULL); g_print ("%s: size=%ld, level=%d, %s\n", display_name ? display_name : "?", (long)gsf_input_size (input), level, is_dir ? "directory" : "file"); g_free (display_name); output = gsf_outfile_new_child_full (out, name, is_dir, "compression-level", level, NULL); clone_ (GSF_INFILE (input), GSF_OUTFILE (output)); } } gsf_output_close (GSF_OUTPUT (out)); g_object_unref (G_OBJECT (out)); g_object_unref (G_OBJECT (in)); }
/** * gsf_input_textline_utf8_gets: * @textline: #GsfInputTextline * * A utility routine to read things line by line from the underlying source. * Trailing newlines and carriage returns are stripped, and the resultant buffer * can be edited. * * Returns: (transfer none): the string read, or %NULL on eof. **/ guint8 * gsf_input_textline_utf8_gets (GsfInputTextline *textline) { guint8 const *ptr ,*end; unsigned len, count = 0; g_return_val_if_fail (textline != NULL, NULL); while (1) { if (textline->remainder == NULL || textline->remainder_size == 0) { gsf_off_t remain = gsf_input_remaining (textline->source); len = MIN (remain, textline->max_line_size); textline->remainder = gsf_input_read (textline->source, len, NULL); if (textline->remainder == NULL) return NULL; textline->remainder_size = len; } ptr = textline->remainder; end = ptr + textline->remainder_size; for (; ptr < end ; ptr++) if (*ptr == '\n' || *ptr == '\r') break; /* copy the remains into the buffer, grow it if necessary */ len = ptr - textline->remainder; if (count + len >= textline->buf_size) { textline->buf_size += len; textline->buf = g_renew (guint8, textline->buf, textline->buf_size + 1); } g_return_val_if_fail (textline->buf != NULL, NULL); memcpy (textline->buf + count, textline->remainder, len); count += len; if (ptr < end) { unsigned char last = ptr[0]; /* eat the trailing eol marker: \n, \r\n, or \r. */ ptr++; if (ptr >= end && last == '\r') { /* be extra careful, the CR is at the bound */ if (gsf_input_remaining (textline->source) > 0) { ptr = gsf_input_read (textline->source, 1, NULL); if (ptr == NULL) return NULL; textline->remainder = ptr; textline->remainder_size = 1; end = ptr + 1; } else ptr = end = NULL; } if (ptr != NULL && last == '\r' && *ptr == '\n') ptr++; break; } else if (gsf_input_remaining (textline->source) <= 0) { ptr = end = NULL; break; } else textline->remainder = NULL; } textline->remainder = ptr; textline->remainder_size = end - ptr; textline->buf[count] = '\0'; return textline->buf; }
static gboolean csv_tsv_probe (GOFileOpener const *fo, GsfInput *input, GOFileProbeLevel pl) { /* Rough and ready heuristic. If the first N bytes have no * unprintable characters this may be text */ const gsf_off_t N = 512; if (pl == GO_FILE_PROBE_CONTENT) { guint8 const *header; gsf_off_t i; char const *enc = NULL; GString *header_utf8; char const *p; gboolean ok = TRUE; if (gsf_input_seek (input, 0, G_SEEK_SET)) return FALSE; i = gsf_input_remaining (input); /* If someone ships us an empty file, accept it only if it has a proper name. */ if (i == 0) return csv_tsv_probe (fo, input, GO_FILE_PROBE_FILE_NAME); if (i > N) i = N; if (NULL == (header = gsf_input_read (input, i, NULL))) return FALSE; enc = go_guess_encoding (header, i, NULL, &header_utf8, NULL); if (!enc) return FALSE; for (p = header_utf8->str; *p; p = g_utf8_next_char (p)) { gunichar uc = g_utf8_get_char (p); /* isprint might not be true for these: */ if (uc == '\n' || uc == '\t' || uc == '\r') continue; /* Also, ignore a byte-order mark which may be used to * indicate UTF-8; see * http://en.wikipedia.org/wiki/Byte_Order_Mark for * background. */ if (p == header_utf8->str && uc == 0x0000FEFF) { continue; } if (!g_unichar_isprint (uc)) { ok = FALSE; break; } } g_string_free (header_utf8, TRUE); return ok; } else { char const *name = gsf_input_name (input); if (name == NULL) return FALSE; name = gsf_extension_pointer (name); return (name != NULL && (g_ascii_strcasecmp (name, "csv") == 0 || g_ascii_strcasecmp (name, "tsv") == 0 || g_ascii_strcasecmp (name, "txt") == 0)); } }
static void make_stream (HwpHWP5File *file, GError **error) { GsfInput *input = NULL; GsfInfile *ole = GSF_INFILE (file->priv->olefile); gint n_root_entry = gsf_infile_num_children (ole); if (n_root_entry < 1) { g_set_error_literal (error, HWP_FILE_ERROR, HWP_FILE_ERROR_INVALID, "invalid hwp file"); return; } /* 우선 순위에 따라 스트림을 만든다 */ input = gsf_infile_child_by_name (ole, "FileHeader"); if (input && gsf_infile_num_children (GSF_INFILE (input)) == -1) { file->file_header_stream = input; input = NULL; parse_file_header (file); } else { goto FAIL; } input = gsf_infile_child_by_name (ole, "DocInfo"); if (input && gsf_infile_num_children (GSF_INFILE (input)) == -1) { if (file->is_compress) { GInputStream *gis; GZlibDecompressor *zd; GInputStream *cis; gis = (GInputStream *) gsf_input_stream_new (input); zd = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); cis = g_converter_input_stream_new (gis, (GConverter *) zd); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (cis), TRUE); file->doc_info_stream = cis; g_object_unref (zd); g_object_unref (gis); input = NULL; } else { file->doc_info_stream = (GInputStream *) gsf_input_stream_new (input); } } else { goto FAIL; } if (!file->is_distribute) input = gsf_infile_child_by_name (ole, "BodyText"); else input = gsf_infile_child_by_name (ole, "ViewText"); if (input) { for (gint i = 0; i < gsf_infile_num_children (GSF_INFILE (input)); i++) { GsfInput *section = gsf_infile_child_by_name (GSF_INFILE (input), g_strdup_printf("Section%d", i)); if (gsf_infile_num_children (GSF_INFILE (section)) != -1) { if (GSF_IS_INPUT (section)) g_object_unref (section); g_set_error_literal (error, HWP_FILE_ERROR, HWP_FILE_ERROR_INVALID, "invalid hwp file"); return; } if (file->is_distribute) { guint8 *data = g_malloc0 (256); gsf_input_read (section, 4, NULL); gsf_input_read (section, 256, data); guint32 seed = GSF_LE_GET_GUINT32 (data); msvc_srand (seed); gint n = 0, val = 0, offset; for (guint i = 0; i < 256; i++) { if (n == 0) { val = msvc_rand() & 0xff; n = (msvc_rand() & 0xf) + 1; } data[i] ^= val; n--; } offset = 4 + (seed & 0xf); gchar *key = g_malloc0 (16); memcpy (key, (const gchar *) data + offset, 16); #ifdef HWP_ENABLE_DEBUG gchar *sha1 = g_convert ((const gchar *) data + offset, 80, "UTF-8", "UTF-16LE", NULL, NULL, error); printf ("sha1: %s\n", sha1); printf ("key: %s\n", key); g_free (sha1); #endif g_free (data); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); EVP_CIPHER_CTX_init (ctx); EVP_DecryptInit_ex (ctx, EVP_aes_128_ecb(), NULL, (unsigned char *) key, NULL); g_free (key); EVP_CIPHER_CTX_set_padding(ctx, 0); /* no padding */ gsf_off_t encrypted_data_len = gsf_input_remaining (section); guint8 const *encrypted_data = gsf_input_read (section, encrypted_data_len, NULL); guint8 *decrypted_data = g_malloc (encrypted_data_len); int decrypted_data_len, len; EVP_DecryptUpdate (ctx, decrypted_data, &len, encrypted_data, encrypted_data_len); decrypted_data_len = len; EVP_DecryptFinal_ex (ctx, decrypted_data + len, &len); decrypted_data_len += len; EVP_CIPHER_CTX_free (ctx); g_object_unref (section); section = gsf_input_memory_new (decrypted_data, decrypted_data_len, TRUE); } if (file->is_compress) { GInputStream *gis; GZlibDecompressor *zd; GInputStream *cis; gis = (GInputStream *) gsf_input_stream_new (section); zd = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); cis = g_converter_input_stream_new (gis, (GConverter *) zd); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (cis), TRUE); g_ptr_array_add (file->section_streams, cis); g_object_unref (zd); g_object_unref (gis); } else { GInputStream *stream = (GInputStream *) gsf_input_stream_new (section); g_ptr_array_add (file->section_streams, stream); } } /* for */ g_object_unref (input); input = NULL; } else { goto FAIL; } input = gsf_infile_child_by_name (ole, "\005HwpSummaryInformation"); if (input && gsf_infile_num_children (GSF_INFILE (input)) == -1) { file->summary_info_stream = input; input = NULL; } else { goto FAIL; } input = gsf_infile_child_by_name (ole, "BinData"); if (input) { gint n_data = gsf_infile_num_children (GSF_INFILE (input)); for (gint i = 0; i < n_data; i++) { GsfInput *bin_data_input = gsf_infile_child_by_index (GSF_INFILE (input), i); if (gsf_infile_num_children (GSF_INFILE (bin_data_input)) != -1) { if (GSF_IS_INPUT (bin_data_input)) g_object_unref (bin_data_input); g_set_error_literal (error, HWP_FILE_ERROR, HWP_FILE_ERROR_INVALID, "invalid hwp file"); return; } if (file->is_compress) { GInputStream *gis; GZlibDecompressor *zd; GInputStream *cis; gis = (GInputStream *) gsf_input_stream_new (bin_data_input); zd = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); cis = g_converter_input_stream_new (gis, (GConverter *) zd); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (cis), TRUE); g_ptr_array_add (file->bin_data_streams, cis); g_object_unref (zd); g_object_unref (gis); } else { GInputStream *stream = (GInputStream *) gsf_input_stream_new (bin_data_input); g_ptr_array_add (file->bin_data_streams, stream); } } g_object_unref (input); input = NULL; } input = gsf_infile_child_by_name (ole, "PrvText"); if (input && gsf_infile_num_children (GSF_INFILE (input)) == -1) { file->prv_text_stream = input; input = NULL; } else { goto FAIL; } input = gsf_infile_child_by_name (ole, "PrvImage"); if (input && gsf_infile_num_children (GSF_INFILE (input)) == -1) { file->prv_image_stream = input; input = NULL; } else { goto FAIL; } return; FAIL: if (GSF_IS_INPUT (input)) g_object_unref (input); g_set_error_literal (error, HWP_FILE_ERROR, HWP_FILE_ERROR_INVALID, "invalid hwp file"); return; }
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; }
static guint8 const * gsf_input_gzip_read (GsfInput *input, size_t num_bytes, guint8 *buffer) { GsfInputGZip *gzip = GSF_INPUT_GZIP (input); if (buffer == NULL) { if (gzip->buf_size < num_bytes) { gzip->buf_size = MAX (num_bytes, 256); g_free (gzip->buf); gzip->buf = g_new (guint8, gzip->buf_size); } buffer = gzip->buf; } gzip->stream.next_out = buffer; gzip->stream.avail_out = num_bytes; while (gzip->stream.avail_out != 0) { int zerr; if (gzip->stream.avail_in == 0) { gsf_off_t remain = gsf_input_remaining (gzip->source); if (remain <= gzip->trailer_size) { if (remain < gzip->trailer_size || gzip->stop_byte_added) { g_clear_error (&gzip->err); gzip->err = g_error_new (gsf_input_error_id (), 0, "truncated source"); return NULL; } /* zlib requires an extra byte. */ gzip->stream.avail_in = 1; gzip->gzipped_data = ""; gzip->stop_byte_added = TRUE; } else { size_t n = MIN (remain - gzip->trailer_size, Z_BUFSIZE); gzip->gzipped_data = gsf_input_read (gzip->source, n, NULL); if (!gzip->gzipped_data) { g_clear_error (&gzip->err); gzip->err = g_error_new (gsf_input_error_id (), 0, "Failed to read from source"); return NULL; } gzip->stream.avail_in = n; } gzip->stream.next_in = (Byte *)gzip->gzipped_data; } zerr = inflate (&(gzip->stream), Z_NO_FLUSH); if (zerr != Z_OK) { if (zerr != Z_STREAM_END) return NULL; /* Premature end of stream. */ if (gzip->stream.avail_out != 0) return NULL; } } gzip->crc = crc32 (gzip->crc, buffer, (uInt)(gzip->stream.next_out - buffer)); return buffer; }