示例#1
0
static GsfInput *
gsf_infile_zip_new_child (GsfInfileZip *parent, GsfZipVDir *vdir, GError **err)
{
	GsfInfileZip *child;
	GsfZipDirent *dirent = vdir->dirent;
	child = zip_dup (parent, err);

	if (child == NULL)
		return NULL;

	gsf_input_set_name (GSF_INPUT (child), vdir->name);
	gsf_input_set_container (GSF_INPUT (child), GSF_INFILE (parent));

	child->vdir = vdir;

	if (dirent) {
		gsf_input_set_size (GSF_INPUT (child),
				    (gsf_off_t) dirent->usize);
		if (zip_child_init (child, err) != FALSE) {
			g_object_unref (child);
			return NULL;
		}
	} else
		gsf_input_set_size (GSF_INPUT (child), 0);

	return GSF_INPUT (child);
}
示例#2
0
/**
 * gsf_input_stdio_new_FILE :
 * @filename  : The filename corresponding to @file.
 * @file      : an existing stdio <type>FILE</type> *
 * @keep_open : Should @file be closed when the wrapper is closed
 *
 * Assumes ownership of @file when succeeding.  If @keep_open is true,
 * ownership reverts to caller when the GsfObject is closed.
 *
 * Returns: a new GsfInput wrapper for @file.  Note that if the file is not
 * 	seekable, this function will make a local copy of the entire file.
 **/
GsfInput *
gsf_input_stdio_new_FILE (char const *filename, FILE *file, gboolean keep_open)
{
	GsfInputStdio *stdio;
	struct stat st;
	gsf_off_t size;

	g_return_val_if_fail (filename != NULL, NULL);
	g_return_val_if_fail (file != NULL, NULL);

	if (fstat (fileno (file), &st) < 0 || !S_ISREG (st.st_mode)) {
		return make_local_copy (file, filename, NULL);
	}

	size = st.st_size;

	stdio = g_object_new (GSF_INPUT_STDIO_TYPE, NULL);
	if (G_UNLIKELY (NULL == stdio)) return NULL;
	stdio->file = file;
	stdio->keep_open = keep_open;
	stdio->filename = g_strdup (filename);
	gsf_input_set_size (GSF_INPUT (stdio), size);
	gsf_input_set_name_from_filename (GSF_INPUT (stdio), filename);
	return GSF_INPUT (stdio);
}
示例#3
0
static GsfInput *
gsf_input_textline_dup (GsfInput *src_input, G_GNUC_UNUSED GError **err)
{
	GsfInputTextline const *src = (GsfInputTextline *)src_input;
	GsfInputTextline *dst = g_object_new (GSF_INPUT_TEXTLINE_TYPE, NULL);

	dst->source = g_object_ref (src->source);
	gsf_input_set_size (GSF_INPUT (dst), gsf_input_size (src_input));

	return GSF_INPUT (dst);
}
示例#4
0
/* coverity[ -tainted_string_sink_content : arg-0 ] */
GsfInput *
gsf_input_stdio_new (char const *filename, GError **err)
{
	GsfInputStdio *input;
	struct stat st;
	FILE *file;
	gsf_off_t size;

	g_return_val_if_fail (filename != NULL, NULL);

	file = g_fopen (filename, "rb");
	if (file == NULL) {
		if (err) {
			int save_errno = errno;
			char *utf8name = g_filename_display_name (filename);
			g_set_error (err,
				     G_FILE_ERROR,
				     g_file_error_from_errno (save_errno),
				     "%s: %s",
				     utf8name, g_strerror (save_errno));
			g_free (utf8name);
		}
		return NULL;
	}

	if (fstat (fileno (file), &st) < 0 || !S_ISREG (st.st_mode)) {
		GsfInput *res = make_local_copy (file, filename, err);
		fclose (file);
		return res;
	}

	size = st.st_size;
	input = (GsfInputStdio *)g_object_new (GSF_INPUT_STDIO_TYPE, NULL);
	if (G_UNLIKELY (NULL == input)) {
		fclose (file);
		return NULL;
	}

	input->file = file;
	input->filename = g_strdup (filename);
	input->buf  = NULL;
	input->buf_size = 0;
	input->keep_open = FALSE;
	gsf_input_set_size (GSF_INPUT (input), size);
	gsf_input_set_name_from_filename (GSF_INPUT (input), filename);

	return GSF_INPUT (input);
}
示例#5
0
/**
 * gsf_input_textline_new:
 * @source: in some combination of ascii and utf8
 *
 * <note>This adds a reference to @source.</note>
 *
 * Returns: a new file or %NULL.
 **/
GsfInput *
gsf_input_textline_new (GsfInput *source)
{
	GsfInputTextline *input;

	g_return_val_if_fail (source != NULL, NULL);

	input = g_object_new (GSF_INPUT_TEXTLINE_TYPE, NULL);
	input->source = g_object_ref (source);
	input->buf = NULL;
	input->buf_size = 0;
	gsf_input_set_size (GSF_INPUT (input), gsf_input_size (source));
	gsf_input_set_name (GSF_INPUT (input), gsf_input_name (source));

	return GSF_INPUT (input);
}
示例#6
0
/**
 * gsf_input_gio_new:
 * @file:
 * @err: (allow-none): place to store a #GError if anything goes wrong
 *
 * Returns: A new #GsfInputGio or %NULL
 */
GsfInput *
gsf_input_gio_new (GFile *file, GError **err)
{
    GsfInputGio *input;
    GInputStream *stream;
    gsf_off_t filesize;

    g_return_val_if_fail (file != NULL, NULL);

    stream = (GInputStream *)g_file_read (file, NULL, err);
    if (stream == NULL)
        return NULL;

    if (1) {
        /* see https://bugzilla.gnome.org/show_bug.cgi?id=724970 */
        return make_local_copy (file, stream);
    }

    if (!can_seek (stream))
        return make_local_copy (file, stream);

    {
        GFileInfo *info =
            g_file_query_info (file,
                               G_FILE_ATTRIBUTE_STANDARD_SIZE,
                               0, NULL, NULL);
        if (!info)
            return make_local_copy (file, stream);
        filesize = g_file_info_get_size (info);
        g_object_unref (info);
    }

    input = g_object_new (GSF_INPUT_GIO_TYPE, NULL);

    gsf_input_set_size (GSF_INPUT (input), filesize);

    g_object_ref (file);

    input->stream = stream;
    input->file = file;
    input->buf  = NULL;
    input->buf_size = 0;

    set_name_from_file (GSF_INPUT (input), file);
    return GSF_INPUT (input);
}
示例#7
0
/**
 * gsf_input_gio_new:
 * @file:
 * @err: optionally NULL.
 *
 * Returns: A new #GsfInputGio or NULL
 */
GsfInput *
gsf_input_gio_new (GFile *file, GError **err)
{
	GsfInputGio *input;
	GInputStream *stream;
	gsf_off_t filesize;

	g_return_val_if_fail (file != NULL, NULL);

	stream = (GInputStream *)g_file_read (file, NULL, err);
	if (stream == NULL)
		return NULL;

	if (!can_seek (stream))
		return make_local_copy (file, stream);

	{
		GFileInfo *info =
			g_file_query_info (file,
					   G_FILE_ATTRIBUTE_STANDARD_SIZE,
					   0, NULL, NULL);
		if (!info)
			return make_local_copy (file, stream);
		filesize = g_file_info_get_size (info);
		g_object_unref (info);
	}

	input = g_object_new (GSF_INPUT_GIO_TYPE, NULL);
	if (G_UNLIKELY (NULL == input)) {
		g_input_stream_close (stream, NULL, NULL);
		g_object_unref (stream);
		return NULL;
	}

	gsf_input_set_size (GSF_INPUT (input), filesize);

	g_object_ref (file);

	input->stream = stream;
	input->file = file;
	input->buf  = NULL;
	input->buf_size = 0;

	set_name_from_file (GSF_INPUT (input), file);
	return GSF_INPUT (input);
}
示例#8
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);
}
示例#9
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;
}