示例#1
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;
}
示例#2
0
static gboolean
go_plugin_file_opener_probe (GOFileOpener const *fo, GsfInput *input,
                               GOFileProbeLevel pl)
{
	GOPluginFileOpener *pfo = GO_PLUGIN_FILE_OPENER (fo);
	GOPluginServiceFileOpener *service_file_opener = GO_PLUGIN_SERVICE_FILE_OPENER (pfo->service);

	g_return_val_if_fail (GSF_IS_INPUT (input), FALSE);

	if (pl == GO_FILE_PROBE_FILE_NAME && service_file_opener->suffixes != NULL) {
		GSList *ptr;
		gchar const *extension;
		gchar *lowercase_extension;

		if (gsf_input_name (input) == NULL)
			return FALSE;
		extension = gsf_extension_pointer (gsf_input_name (input));
		if (extension == NULL)
			return FALSE;

		lowercase_extension = g_utf8_strdown (extension, -1);
		for (ptr = service_file_opener->suffixes; ptr != NULL ; ptr = ptr->next)
			if (0 == strcmp (lowercase_extension, ptr->data))
				break;
		g_free (lowercase_extension);
		return ptr != NULL;
	}

	if (service_file_opener->has_probe) {
		GOErrorInfo *ignored_error = NULL;

		go_plugin_service_load (pfo->service, &ignored_error);
		if (ignored_error != NULL) {
			go_error_info_print (ignored_error);
			go_error_info_free (ignored_error);
			return FALSE;
		} else if (service_file_opener->cbs.plugin_func_file_probe == NULL) {
			return FALSE;
		} else {
			gboolean res = service_file_opener->cbs.plugin_func_file_probe (fo, pfo->service, input, pl);
			gsf_input_seek (input, 0, G_SEEK_SET);
			return res;
		}
	} else {
		return FALSE;
	}
}
示例#3
0
/**
 * gsf_infile_tar_new :
 * @source: A base #GsfInput
 * @err: A #GError, optionally %null
 *
 * Opens the root directory of a Tar file.
 * <note>This adds a reference to @source.</note>
 *
 * Returns: the new tar file handler
 **/
GsfInfile *
gsf_infile_tar_new (GsfInput *source, GError **err)
{
	GsfInfileTar *tar;

	g_return_val_if_fail (GSF_IS_INPUT (source), NULL);

	tar = g_object_new (GSF_INFILE_TAR_TYPE,
			    "source", source,
			    NULL);

	if (tar->err) {
		if (err)
			*err = g_error_copy (tar->err);
		g_object_unref (tar);
		return NULL;
	}

	return GSF_INFILE (tar);
}
示例#4
0
/**
 * gsf_infile_zip_new :
 * @source: A base #GsfInput
 * @err: A #GError, optionally %null
 *
 * Opens the root directory of a Zip file.
 * <note>This adds a reference to @source.</note>
 *
 * Returns: the new zip file handler
 **/
GsfInfile *
gsf_infile_zip_new (GsfInput *source, GError **err)
{
	GsfInfileZip *zip;

	g_return_val_if_fail (GSF_IS_INPUT (source), NULL);

	zip = g_object_new (GSF_INFILE_ZIP_TYPE,
			    "source", source,
			    NULL);
	if (G_UNLIKELY (NULL == zip)) return NULL;

	if (zip->err) {
		if (err)
			*err = g_error_copy (zip->err);
		g_object_unref (zip);
		return NULL;
	}

	return GSF_INFILE (zip);
}
示例#5
0
/**
 * gsf_infile_ar_new :
 * @source: #GsfInput
 * @err: #Gerror
 *
 * Opens the root directory of a Ar file.
 * <note>This adds a reference to @source.</note>
 *
 * Returns: the new AR file handler
 **/
GsfInfile *
gsf_infile_ar_new (GsfInput *source, GError **err)
{
	GsfInfileAr *ar;

	g_return_val_if_fail (GSF_IS_INPUT (source), NULL);

	ar = g_object_new (GSF_INFILE_AR_TYPE, NULL);
	if (G_UNLIKELY (NULL == ar)) return NULL;

	g_object_ref (source);
	ar->input = source;
	gsf_input_set_size (GSF_INPUT (ar), 0);

	if (ar_init_info (ar, err)) {
		g_object_unref (ar);
		return NULL;
	}
	ar->vdir = ar->info->vdir;

	return GSF_INFILE (ar);
}
示例#6
0
/**
 * gsf_input_gzip_new :
 * @source : The underlying data source.
 * @err	   : optionally %NULL.
 *
 * Adds a reference to @source.
 *
 * Returns: a new file or %NULL.
 **/
GsfInput *
gsf_input_gzip_new (GsfInput *source, GError **err)
{
	GsfInputGZip *gzip;

	g_return_val_if_fail (GSF_IS_INPUT (source), NULL);

	gzip = g_object_new (GSF_INPUT_GZIP_TYPE,
			     "source", source,
			     NULL);
	if (G_UNLIKELY (NULL == gzip)) return NULL;

	if (gzip->err) {
		if (err)
			*err = g_error_copy (gzip->err);
		g_object_unref (gzip);
		return NULL;
	}
	gsf_input_set_name (GSF_INPUT (gzip), gsf_input_name (source));

	return GSF_INPUT (gzip);
}
示例#7
0
static void
go_plugin_file_opener_open (GOFileOpener const *fo, gchar const *enc,
			     GOIOContext *io_context,
			     GoView *view,
			     GsfInput *input)

{
	GOPluginFileOpener *pfo = GO_PLUGIN_FILE_OPENER (fo);
	GOPluginServiceFileOpener *service_file_opener = GO_PLUGIN_SERVICE_FILE_OPENER (pfo->service);
	GOErrorInfo *error = NULL;

	g_return_if_fail (GSF_IS_INPUT (input));

	go_plugin_service_load (pfo->service, &error);
	if (error != NULL) {
		go_io_error_info_set (io_context, error);
		go_io_error_push (io_context, go_error_info_new_str (
		                        _("Error while reading file.")));
		return;
	}

	g_return_if_fail (service_file_opener->cbs.plugin_func_file_open != NULL);
	service_file_opener->cbs.plugin_func_file_open (fo, pfo->service, io_context, view, input, enc);
}
示例#8
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;
}