static void ls_R (GsfInput *input) { char const *name = gsf_input_name (input); gboolean is_dir = GSF_IS_INFILE (input) && (gsf_infile_num_children (GSF_INFILE (input)) >= 0); /* Please see the comment on is_dir in test-cp-msole.c. */ printf ("%c '%s'\t\t%" GSF_OFF_T_FORMAT "\n", (is_dir ? 'd' : ' '), (name != NULL) ? name : "", gsf_input_size (input)); if (is_dir) { GsfInfile *infile = GSF_INFILE (input); int i; puts ("{"); for (i = 0 ; i < gsf_infile_num_children (infile) ; i++) ls_R (gsf_infile_child_by_index (infile, i)); puts ("}"); } g_object_unref (G_OBJECT (input)); }
static void clone_dir (GsfInfile *in, GsfOutfile *out) { GsfInput *new_input; GsfOutput *new_output; gboolean is_dir; int i; for (i = 0 ; i < gsf_infile_num_children (in) ; i++) { new_input = gsf_infile_child_by_index (in, i); /* In theory, if new_file is a regular file (not directory), * it should be GsfInput only, not GsfInfile, as it is not * structured. However, having each Infile define a 2nd class * that only inherited from Input was cumbersome. So in * practice, the convention is that new_input is always * GsfInfile, but regular file is distinguished by having -1 * children. */ is_dir = GSF_IS_INFILE (new_input) && gsf_infile_num_children (GSF_INFILE (new_input)) >= 0; new_output = gsf_outfile_new_child (out, gsf_infile_name_by_index (in, i), is_dir); clone (new_input, new_output); } /* An observation: when you think about the explanation to is_dir * above, you realize that clone_dir is called even for regular files. * But nothing bad happens, as the loop is never entered. */ }
/* Decompress infile in dest_dir. */ static void decompress_infile (GsfInfile *infile, gchar *dest_dir) { GError *err = (GError *) NULL; int j = 0; for (j = 0; j < gsf_infile_num_children (infile); j++) { GsfInput *child = gsf_infile_child_by_index (infile, j); char const* filename = gsf_input_name (child); gboolean is_dir = gsf_infile_num_children (GSF_INFILE (child)) >= 0; if (is_dir) { gchar *dir_path = g_build_filename (dest_dir, filename, (gchar *) 0); decompress_infile (GSF_INFILE (child), dir_path); g_free (dir_path); } else { gchar *file_path = g_build_filename (dest_dir, filename, (gchar *) 0); GsfOutput *output = GSF_OUTPUT (gsf_output_stdio_new (file_path, &err)); gsf_input_copy (child, output); gsf_output_close (output); g_object_unref (output); g_free (file_path); } g_object_unref (G_OBJECT (child)); } }
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)); }
const char * AbiWordperfectInputStream::subStreamName(unsigned id) { if (!m_ole) m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL)); if (!m_ole) m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL)); if (m_ole) { if ((int)id >= gsf_infile_num_children(m_ole)) { return 0; } std::map<unsigned, std::string>::iterator i = m_substreams.lower_bound(id); if (i == m_substreams.end() || m_substreams.key_comp()(id, i->first)) { std::string name = gsf_infile_name_by_index(m_ole, (int)id); i = m_substreams.insert(i, std::map<unsigned, std::string>::value_type(id, name)); } return i->second.c_str(); } return 0; }
/** * 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; }
static void ls_R (GsfInput *input, char const *prefix) { char const *name = gsf_input_name (input); GsfInfile *infile = GSF_IS_INFILE (input) ? GSF_INFILE (input) : NULL; gboolean is_dir = infile && gsf_infile_num_children (infile) > 0; char *full_name; char *new_prefix; if (prefix) { char *display_name = name ? g_filename_display_name (name) : g_strdup ("?"); full_name = g_strconcat (prefix, display_name, NULL); new_prefix = g_strconcat (full_name, "/", NULL); g_free (display_name); } else { full_name = g_strdup ("*root*"); new_prefix = g_strdup (""); } g_print ("%c %10" GSF_OFF_T_FORMAT " %s\n", (is_dir ? 'd' : 'f'), gsf_input_size (input), full_name); if (is_dir) { int i; for (i = 0 ; i < gsf_infile_num_children (infile) ; i++) { GsfInput *child = gsf_infile_child_by_index (infile, i); /* We can get NULL here in case of file corruption. */ if (child) { ls_R (child, new_prefix); g_object_unref (child); } } } g_free (full_name); g_free (new_prefix); }
unsigned AbiWordperfectInputStream::subStreamCount() { if (!m_ole) m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL)); if (!m_ole) m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL)); if (m_ole) { int numChildren = gsf_infile_num_children(m_ole); if (numChildren > 0) return numChildren; return 0; } return 0; }
UT_Error IE_Imp_EPUB::uncompress() { m_tmpDir = UT_go_filename_to_uri(g_get_tmp_dir()); m_tmpDir += G_DIR_SEPARATOR_S; m_tmpDir += getDoc()->getDocUUIDString(); if (!UT_go_directory_create(m_tmpDir.c_str(), 0644, NULL)) { UT_DEBUGMSG(("Can`t create temporary directory\n")); return UT_ERROR; } GsfInput *opsDirInput = gsf_infile_child_by_name(m_epub, m_opsDir.c_str()); UT_DEBUGMSG(("Child count : %d", gsf_infile_num_children(m_epub))); if (opsDirInput == NULL) { UT_DEBUGMSG(("Failed to open OPS dir\n")); return UT_ERROR; } for (std::map<std::string, std::string>::iterator i = m_manifestItems.begin(); i != m_manifestItems.end(); i++) { gchar *itemFileName = UT_go_filename_from_uri( (m_tmpDir + G_DIR_SEPARATOR_S + (*i).second).c_str()); gchar** aname = g_strsplit((*i).second.c_str(), G_DIR_SEPARATOR_S, 0); GsfInput* itemInput = gsf_infile_child_by_aname( GSF_INFILE(opsDirInput), (const char**) aname); GsfOutput* itemOutput = createFileByPath(itemFileName); gsf_input_seek(itemInput, 0, G_SEEK_SET); gsf_input_copy(itemInput, itemOutput); g_strfreev(aname); g_free(itemFileName); g_object_unref(G_OBJECT(itemInput)); gsf_output_close(itemOutput); } g_object_unref(G_OBJECT(opsDirInput)); return UT_OK; }
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)); }
static int test (int argc, char *argv[]) { GsfInput *input; GsfInfile *infile; GError *err = NULL; fprintf (stderr, "%s\n", argv [1]); input = gsf_input_stdio_new (argv[1], &err); if (input == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' error: %s", argv[1], err->message); g_error_free (err); return 1; } input = gsf_input_uncompress (input); infile = gsf_infile_msole_new (input, &err); g_object_unref (G_OBJECT (input)); if (infile == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' Not an OLE file: %s", argv[1], err->message); g_error_free (err); return 1; } if (argc > 2) { int i; GsfInput *child, *ptr = GSF_INPUT (infile); for (i = 2 ; i < argc && ptr != NULL; i++, ptr = child) { fprintf (stderr, "--> '%s'\n", argv [i]); if (GSF_IS_INFILE (ptr) && gsf_infile_num_children (GSF_INFILE (ptr)) >= 0) { child = gsf_infile_child_by_name (GSF_INFILE (ptr), argv [i]); if (child == NULL) { g_warning ("No child named '%s'", argv [i]); child = NULL; } } else { g_warning ("stream is not a directory '%s'", argv [i]); child = NULL; } g_object_unref (G_OBJECT (ptr)); } if (ptr != NULL) { /* See the comment on is_dir in test-cp-msole.c. */ if (GSF_IS_INFILE (ptr) && gsf_infile_num_children (GSF_INFILE (ptr)) >= 0) ls_R (ptr); /* unrefs infile */ else { gsf_input_dump (GSF_INPUT (ptr), dump_as_hex); g_object_unref (G_OBJECT (ptr)); } } } else ls_R (GSF_INPUT (infile)); /* unrefs infile */ return 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 int test (unsigned argc, char *argv[]) { static char const * const stream_names[] = { "Workbook", "WORKBOOK", "workbook", "Book", "BOOK", "book" }; GsfInput *input, *stream, *pcache_dir; GsfInfile *infile; GError *err = NULL; unsigned i, j; for (i = 1 ; i < argc ; i++) { fprintf( stderr, "%s\n",argv[i]); input = gsf_input_mmap_new (argv[i], NULL); if (input == NULL) /* Only report error if stdio fails too */ input = gsf_input_stdio_new (argv[i], &err); if (input == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' error: %s", argv[i], err->message); g_error_free (err); err = NULL; continue; } input = gsf_input_uncompress (input); infile = gsf_infile_msole_new (input, &err); if (infile == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' Not an OLE file: %s", argv[i], err->message); g_error_free (err); err = NULL; #ifdef DUMP_CONTENT dump_biff_stream (input); #endif g_object_unref (G_OBJECT (input)); continue; } #if 0 stream = gsf_infile_child_by_name (infile, "\01CompObj"); if (stream != NULL) { gsf_off_t len = gsf_input_size (stream); guint8 const *data = gsf_input_read (stream, len, NULL); if (data != NULL) gsf_mem_dump (data, len); g_object_unref (G_OBJECT (stream)); } return 0; #endif stream = gsf_infile_child_by_name (infile, "\05SummaryInformation"); if (stream != NULL) { GsfDocMetaData *meta_data = gsf_doc_meta_data_new (); puts ( "SummaryInfo"); err = gsf_doc_meta_data_read_from_msole (meta_data, stream); if (err != NULL) { g_warning ("'%s' error: %s", argv[i], err->message); g_error_free (err); err = NULL; } else gsf_doc_meta_dump (meta_data); g_object_unref (meta_data); g_object_unref (G_OBJECT (stream)); } stream = gsf_infile_child_by_name (infile, "\05DocumentSummaryInformation"); if (stream != NULL) { GsfDocMetaData *meta_data = gsf_doc_meta_data_new (); puts ( "DocSummaryInfo"); err = gsf_doc_meta_data_read_from_msole (meta_data, stream); if (err != NULL) { g_warning ("'%s' error: %s", argv[i], err->message); g_error_free (err); err = NULL; } else gsf_doc_meta_dump (meta_data); g_object_unref (meta_data); g_object_unref (G_OBJECT (stream)); } for (j = 0 ; j < G_N_ELEMENTS (stream_names) ; j++) { stream = gsf_infile_child_by_name (infile, stream_names[j]); if (stream != NULL) { puts (j < 3 ? "Excel97" : "Excel95"); #ifdef DUMP_CONTENT dump_biff_stream (stream); #endif g_object_unref (G_OBJECT (stream)); break; } } #ifdef DUMP_CONTENT pcache_dir = gsf_infile_child_by_name (infile, "_SX_DB_CUR"); /* Excel 97 */ if (NULL == pcache_dir) pcache_dir = gsf_infile_child_by_name (infile, "_SX_DB"); /* Excel 95 */ if (NULL != pcache_dir) { int i, n = gsf_infile_num_children (infile); for (i = 0 ; i < n ; i++) { stream = gsf_infile_child_by_index (GSF_INFILE (pcache_dir), i); if (stream != NULL) { printf ("=================================================\nPivot cache '%04hX'\n\n", i); dump_biff_stream (stream); g_object_unref (G_OBJECT (stream)); } } g_object_unref (G_OBJECT (pcache_dir)); } #endif g_object_unref (G_OBJECT (infile)); g_object_unref (G_OBJECT (input)); } return 0; }