/** * hwp_hwp3_parser_parse: * @parser: a #HwpHWP3Parser * @file: a #HwpHWP3File * @error: a #GError * * Since: 0.0.1 */ void hwp_hwp3_parser_parse (HwpHWP3Parser *parser, HwpHWP3File *file, GError **error) { g_return_if_fail (HWP_IS_HWP3_FILE (file)); parser->stream = file->priv->stream; _hwp_hwp3_parser_parse_signature (parser, file, error); _hwp_hwp3_parser_parse_doc_info (parser, file, error); _hwp_hwp3_parser_parse_summary_info (parser, file, error); _hwp_hwp3_parser_parse_info_block (parser, file, error); if (file->is_compress) { GZlibDecompressor *zd; GInputStream *cis; zd = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); cis = g_converter_input_stream_new (file->priv->stream, G_CONVERTER (zd)); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (cis), TRUE); g_object_unref (file->priv->stream); file->priv->stream = g_object_ref (cis); g_object_unref (zd); } parser->stream = file->priv->stream; _hwp_hwp3_parser_parse_font_names (parser, file, error); _hwp_hwp3_parser_parse_styles (parser, file, error); _hwp_hwp3_parser_parse_paragraphs (parser, file, error); _hwp_hwp3_parser_parse_supplementary_info_block1 (parser, file, error); _hwp_hwp3_parser_parse_supplementary_info_block2 (parser, file, error); }
int main (int argc, char **argv) { GConverter *converter; GFile *file; GFileInputStream *file_stream; GInputStream *stream; gchar buf[1024]; gssize bytes; if (argc < 2) { g_printerr ("Usage: test-bz2 FILE\n"); return 1; } file = g_file_new_for_path (argv[1]); file_stream = g_file_read (file, NULL, NULL); converter = G_CONVERTER (yelp_bz2_decompressor_new ()); stream = g_converter_input_stream_new (G_INPUT_STREAM (file_stream), converter); while ((bytes = g_input_stream_read (stream, buf, 1024, NULL, NULL)) > 0) { gchar *out = g_strndup (buf, bytes); puts (out); g_free (out); } return 0; }
static gboolean decompress_all (GConverter *converter, GBytes *data, GBytes **out_uncompressed, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GMemoryInputStream) memin = (GMemoryInputStream*)g_memory_input_stream_new_from_bytes (data); g_autoptr(GMemoryOutputStream) memout = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); g_autoptr(GInputStream) convin = g_converter_input_stream_new ((GInputStream*)memin, converter); { gssize n_bytes_written = g_output_stream_splice ((GOutputStream*)memout, convin, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error); if (n_bytes_written < 0) goto out; } ret = TRUE; *out_uncompressed = g_memory_output_stream_steal_as_bytes (memout); out: return ret; }
/** * g_resource_open_stream: * @resource: A #GResource * @path: A pathname inside the resource * @lookup_flags: A #GResourceLookupFlags * @error: return location for a #GError, or %NULL * * Looks for a file at the specified @path in the resource and * returns a #GInputStream that lets you read the data. * * @lookup_flags controls the behaviour of the lookup. * * Returns: (transfer full): #GInputStream or %NULL on error. * Free the returned object with g_object_unref() * * Since: 2.32 **/ GInputStream * g_resource_open_stream (GResource *resource, const gchar *path, GResourceLookupFlags lookup_flags, GError **error) { const void *data; gsize data_size; guint32 flags; GInputStream *stream, *stream2; if (!do_lookup (resource, path, lookup_flags, NULL, &flags, &data, &data_size, error)) return NULL; stream = g_memory_input_stream_new_from_data (data, data_size, NULL); g_object_set_data_full (G_OBJECT (stream), "g-resource", g_resource_ref (resource), (GDestroyNotify)g_resource_unref); if (flags & G_RESOURCE_FLAGS_COMPRESSED) { GZlibDecompressor *decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB); stream2 = g_converter_input_stream_new (stream, G_CONVERTER (decompressor)); g_object_unref (decompressor); g_object_unref (stream); stream = stream2; } return stream; }
static VALUE rg_initialize(VALUE self, VALUE base_stream, VALUE converter) { G_INITIALIZE(self, g_converter_input_stream_new(RVAL2GINPUTSTREAM(base_stream), RVAL2GCONVERTER(converter))); return Qnil; }
static int compress_blob_to_tmp (GInputStream *file_stream) { char tmpl[] = "/tmp/shardXXXXXX"; int fd = mkstemp (tmpl); unlink (tmpl); /* Compress the given GInputStream to the tmpfile. */ g_autoptr(GZlibCompressor) compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, -1); g_autoptr(GInputStream) stream = g_converter_input_stream_new (G_INPUT_STREAM (file_stream), G_CONVERTER (compressor)); uint8_t buf[4096*4]; int size; while ((size = g_input_stream_read (stream, buf, sizeof (buf), NULL, NULL)) != 0) { g_assert (write (fd, buf, size) >= 0); } return fd; }
static void _ghwp_file_v3_parse_info_block (GHWPDocument *doc) { g_return_if_fail (doc != NULL); GInputStream *stream = GHWP_FILE_V3 (doc->file)->priv->stream; g_input_stream_skip (stream, GHWP_FILE_V3 (doc->file)->info_block_len, NULL, NULL); if (GHWP_FILE_V3 (doc->file)->is_compress) { GZlibDecompressor *zd; GInputStream *cis; zd = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); cis = g_converter_input_stream_new ((GInputStream*) stream, (GConverter*) zd); g_object_unref (GHWP_FILE_V3 (doc->file)->priv->stream); g_object_ref (cis); /* NOTE 기존의 스트림은 어떻게 ? */ GHWP_FILE_V3 (doc->file)->priv->stream = G_INPUT_STREAM (cis); g_object_unref (zd); } }
static void write_blob (int fd, struct eos_shard_writer_v1_blob_entry *blob) { g_autoptr(GError) error = NULL; if (!blob->file) return; GFileInputStream *file_stream = g_file_read (blob->file, NULL, &error); if (!file_stream) { g_error ("Could not read from %s: %s", g_file_get_path (blob->file), error->message); return; } g_autoptr(GInputStream) stream; if (blob->flags & EOS_SHARD_BLOB_FLAG_COMPRESSED_ZLIB) { g_autoptr(GZlibCompressor) compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, -1); stream = g_converter_input_stream_new (G_INPUT_STREAM (file_stream), G_CONVERTER (compressor)); g_object_unref (file_stream); } else { stream = G_INPUT_STREAM (file_stream); } blob->offs = lalign (fd); uint8_t buf[4096*4]; int size, total_size = 0; g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256); while ((size = g_input_stream_read (stream, buf, sizeof (buf), NULL, NULL)) != 0) { g_assert (write (fd, buf, size) >= 0); g_checksum_update (checksum, buf, size); total_size += size; } size_t checksum_buf_len = sizeof (blob->checksum); g_checksum_get_digest (checksum, blob->checksum, &checksum_buf_len); g_assert (checksum_buf_len == sizeof (blob->checksum)); blob->size = total_size; }
/** * as_get_yml_data_origin: * * Extract the data origin from the AppStream YAML file. * We don't use the #AsYAMLData loader, because it is much * slower than just loading the initial parts of the file and * extracting the origin manually. */ static gchar* as_get_yml_data_origin (const gchar *fname) { const gchar *data; GZlibDecompressor *zdecomp; g_autoptr(GFileInputStream) fistream = NULL; g_autoptr(GMemoryOutputStream) mem_os = NULL; g_autoptr(GInputStream) conv_stream = NULL; g_autoptr(GFile) file = NULL; g_autofree gchar *str = NULL; g_auto(GStrv) strv = NULL; GError *err; guint i; gchar *start, *end; gchar *origin = NULL; file = g_file_new_for_path (fname); fistream = g_file_read (file, NULL, &err); if (!fistream) { g_critical ("Unable to open file '%s' for reading: %s, skipping.", fname, err->message); g_error_free (err); return NULL; } mem_os = (GMemoryOutputStream*) g_memory_output_stream_new (NULL, 0, g_realloc, g_free); zdecomp = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); conv_stream = g_converter_input_stream_new (G_INPUT_STREAM (fistream), G_CONVERTER (zdecomp)); g_object_unref (zdecomp); g_output_stream_splice (G_OUTPUT_STREAM (mem_os), conv_stream, 0, NULL, NULL); data = (const gchar*) g_memory_output_stream_get_data (mem_os); /* faster than a regular expression? * Get the first YAML document, then extract the origin string. */ if (data == NULL) return NULL; /* start points to the start of the document, i.e. "File:" normally */ start = g_strstr_len (data, 400, YAML_SEPARATOR) + YAML_SEPARATOR_LEN; if (start == NULL) return NULL; /* Find the end of the first document - can be NULL if there is only one, * for example if we're given YAML for an empty archive */ end = g_strstr_len (start, -1, YAML_SEPARATOR); str = g_strndup (start, strlen(start) - (end ? strlen(end) : 0)); strv = g_strsplit (str, "\n", -1); for (i = 0; strv[i] != NULL; i++) { g_auto(GStrv) strv2 = NULL; if (!g_str_has_prefix (strv[i], "Origin:")) continue; strv2 = g_strsplit (strv[i], ":", 2); g_strstrip (strv2[1]); origin = g_strdup (strv2[1]); /* remove quotes, in case the string is quoted */ if ((g_str_has_prefix (origin, "\"")) && (g_str_has_suffix (origin, "\""))) { g_autofree gchar *tmp = NULL; tmp = origin; origin = g_strndup (tmp + 1, strlen (tmp) - 2); } break; } return origin; }
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; }
/** * as_node_from_file: (skip) * @file: file * @flags: #AsNodeFromXmlFlags, e.g. %AS_NODE_FROM_XML_FLAG_NONE * @cancellable: A #GCancellable, or %NULL * @error: A #GError or %NULL * * Parses an XML file into a DOM tree. * * Returns: (transfer none): A populated #AsNode tree * * Since: 0.1.0 **/ AsNode * as_node_from_file (GFile *file, AsNodeFromXmlFlags flags, GCancellable *cancellable, GError **error) { AsNodeToXmlHelper helper; GError *error_local = NULL; AsNode *root = NULL; const gchar *content_type = NULL; gboolean ret = TRUE; gsize chunk_size = 32 * 1024; gssize len; g_autofree gchar *data = NULL; g_autoptr(GMarkupParseContext) ctx = NULL; g_autoptr(GConverter) conv = NULL; g_autoptr(GFileInfo) info = NULL; g_autoptr(GInputStream) file_stream = NULL; g_autoptr(GInputStream) stream_data = NULL; const GMarkupParser parser = { as_node_start_element_cb, as_node_end_element_cb, as_node_text_cb, as_node_passthrough_cb, NULL }; /* what kind of file is this */ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, cancellable, error); if (info == NULL) return NULL; /* decompress if required */ file_stream = G_INPUT_STREAM (g_file_read (file, cancellable, error)); if (file_stream == NULL) return NULL; content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); if (g_strcmp0 (content_type, "application/gzip") == 0 || g_strcmp0 (content_type, "application/x-gzip") == 0) { conv = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP)); stream_data = g_converter_input_stream_new (file_stream, conv); } else if (g_strcmp0 (content_type, "application/xml") == 0) { stream_data = g_object_ref (file_stream); } else { g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "cannot process file of type %s", content_type); return NULL; } /* parse */ root = as_node_new (); helper.flags = flags; helper.current = root; ctx = g_markup_parse_context_new (&parser, G_MARKUP_PREFIX_ERROR_POSITION, &helper, NULL); data = g_malloc (chunk_size); while ((len = g_input_stream_read (stream_data, data, chunk_size, cancellable, error)) > 0) { ret = g_markup_parse_context_parse (ctx, data, len, &error_local); if (!ret) { g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, error_local->message); g_error_free (error_local); as_node_unref (root); return NULL; } } if (len < 0) { as_node_unref (root); return NULL; } /* more opening than closing */ if (root != helper.current) { g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Mismatched XML"); as_node_unref (root); return NULL; } return root; }
/** * as_validator_validate_file: * @validator: An instance of #AsValidator. * @metadata_file: An AppStream XML file. * * Validate an AppStream XML file **/ gboolean as_validator_validate_file (AsValidator *validator, GFile *metadata_file) { g_autoptr(GFileInfo) info = NULL; g_autoptr(GInputStream) file_stream = NULL; g_autoptr(GInputStream) stream_data = NULL; g_autoptr(GConverter) conv = NULL; g_autoptr(GString) asxmldata = NULL; g_autofree gchar *fname = NULL; gssize len; const gsize buffer_size = 1024 * 32; g_autofree gchar *buffer = NULL; const gchar *content_type = NULL; g_autoptr(GError) tmp_error = NULL; gboolean ret; info = g_file_query_info (metadata_file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); if (info != NULL) content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); fname = g_file_get_basename (metadata_file); as_validator_set_current_fname (validator, fname); file_stream = G_INPUT_STREAM (g_file_read (metadata_file, NULL, &tmp_error)); if (tmp_error != NULL) { as_validator_add_issue (validator, NULL, AS_ISSUE_IMPORTANCE_ERROR, AS_ISSUE_KIND_READ_ERROR, "Unable to read file: %s", tmp_error->message); return FALSE; } if (file_stream == NULL) return FALSE; if ((g_strcmp0 (content_type, "application/gzip") == 0) || (g_strcmp0 (content_type, "application/x-gzip") == 0)) { /* decompress the GZip stream */ conv = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP)); stream_data = g_converter_input_stream_new (file_stream, conv); } else { stream_data = g_object_ref (file_stream); } asxmldata = g_string_new (""); buffer = g_malloc (buffer_size); while ((len = g_input_stream_read (stream_data, buffer, buffer_size, NULL, &tmp_error)) > 0) { g_string_append_len (asxmldata, buffer, len); } if (tmp_error != NULL) { as_validator_add_issue (validator, NULL, AS_ISSUE_IMPORTANCE_ERROR, AS_ISSUE_KIND_READ_ERROR, "Unable to read file: %s", tmp_error->message); return FALSE; } /* check if there was an error */ if (len < 0) return FALSE; ret = as_validator_validate_data (validator, asxmldata->str); as_validator_clear_current_fname (validator); return ret; }
gboolean _ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, OstreeStaticDeltaOpenFlags flags, const char *expected_checksum, GVariant **out_part, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; gsize bytes_read; guint8 comptype; g_autoptr(GChecksum) checksum = NULL; g_autoptr(GInputStream) checksum_in = NULL; g_autoptr(GVariant) ret_part = NULL; GInputStream *source_in; /* We either take a fd or a GBytes reference */ g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); if (!skip_checksum) { checksum = g_checksum_new (G_CHECKSUM_SHA256); checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); source_in = checksum_in; } else { source_in = part_in; } { guint8 buf[1]; /* First byte is compression type */ if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, cancellable, error)) { g_prefix_error (error, "Reading initial compression flag byte: "); goto out; } comptype = buf[0]; } switch (comptype) { case 0: if (!inline_part_bytes) { int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); /* No compression, no checksums - a fast path */ if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } else { g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, g_bytes_get_size (inline_part_bytes) - 1); ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), content_bytes, trusted); g_variant_ref_sink (ret_part); } if (!skip_checksum) g_checksum_update (checksum, g_variant_get_data (ret_part), g_variant_get_size (ret_part)); break; case 'x': { g_autofree char *tmppath = g_strdup ("/var/tmp/ostree-delta-XXXXXX"); g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); g_autoptr(GOutputStream) unpacked_out = NULL; glnx_fd_close int unpacked_fd = -1; gssize n_bytes_written; unpacked_fd = g_mkstemp_full (tmppath, O_RDWR | O_CLOEXEC, 0640); if (unpacked_fd < 0) { glnx_set_error_from_errno (error); goto out; } /* Now make it autocleanup on process exit - in the future, we * should consider caching unpacked deltas as well. */ if (unlink (tmppath) < 0) { glnx_set_error_from_errno (error); goto out; } unpacked_out = g_unix_output_stream_new (unpacked_fd, FALSE); n_bytes_written = g_output_stream_splice (unpacked_out, convin, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error); if (n_bytes_written < 0) goto out; if (!ot_util_variant_map_fd (unpacked_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid compression type '%u'", comptype); goto out; } if (checksum) { const char *actual_checksum = g_checksum_get_string (checksum); g_assert (expected_checksum != NULL); if (strcmp (actual_checksum, expected_checksum) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Checksum mismatch in static delta part; expected=%s actual=%s", expected_checksum, actual_checksum); goto out; } } ret = TRUE; *out_part = g_steal_pointer (&ret_part); out: return ret; }
static void render_card_init (char *card_fname) { int i; if (render_init) { for (i = 0; i < 52; i++) g_object_unref (card_pixbuf[i]); cairo_surface_destroy (grey_surface); render_init = 0; } /* gdk_pixbuf_new_from_file doesn't seem to support .svgz (while * librsvg does), so decompress it here. Code from aisleriot * src/lib/ar-svg.c */ GFile *cf = g_file_new_for_path (card_fname); GFileInfo *info; GError *error = NULL; if (!(info = g_file_query_info (cf, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &error))) { printf ("%s: %s\n", card_fname, error->message); g_object_unref (cf); g_error_free (error); return; } const char *type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE); char *gz_type = g_content_type_from_mime_type ("application/x-gzip"); gboolean is_gzip = (type != NULL && g_content_type_is_a (type, gz_type)); g_free (gz_type); g_object_unref (info); GInputStream *stream; if (!(stream = G_INPUT_STREAM (g_file_read (cf, NULL, &error)))) { printf ("%s: %s\n", card_fname, error->message); g_object_unref (cf); g_error_free (error); return; } g_object_unref (cf); if (is_gzip) { GZlibDecompressor *decompressor; GInputStream *converter_stream; decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); converter_stream = g_converter_input_stream_new (stream, G_CONVERTER (decompressor)); g_object_unref (stream); stream = converter_stream; } /* file contains cards in 13 columns (A/2..10/J/Q/K) and 5 rows (C/D/H/S/Jokers) */ /* actual card height is computed from resulting actual size */ GdkPixbuf *pb = gdk_pixbuf_new_from_stream_at_scale (stream, card_width * 13, -1, TRUE, NULL, &error); g_object_unref (stream); if (!pb) { printf ("%s: %s.\n", card_fname, error->message); g_error_free (error); return; } int buf_width = gdk_pixbuf_get_width (pb); int buf_height = gdk_pixbuf_get_height (pb); card_width = ceil (gdk_pixbuf_get_width (pb) / 13.0); card_height = ceil (gdk_pixbuf_get_height (pb) / 5.0); for (i = 0; i < 52; i++) { card_pixbuf[i] = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, card_width, card_height); if (!card_pixbuf[i]) { printf ("%s: rendering card_pixbuf failed\n", card_fname); return; } int col = (i + 1) % 13; int row = i / 13; gdk_pixbuf_copy_area (pb, buf_width * col / 13.0, buf_height * row / 5.0, //gdk_pixbuf_copy_area (pb, card_width * col, card_height * row, card_width, card_height, card_pixbuf[i], 0, 0); } g_object_unref (pb); /* construct a alpha channel in card shape for greying out cards */ grey_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, card_width, card_height); cairo_t *ct = cairo_create (grey_surface); gdk_cairo_set_source_pixbuf (ct, card_pixbuf[0], 0, 0); cairo_paint_with_alpha (ct, 0.3); cairo_destroy (ct); render_init = 1; }
gboolean _ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, OstreeStaticDeltaOpenFlags flags, const char *expected_checksum, GVariant **out_part, GCancellable *cancellable, GError **error) { const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; gsize bytes_read; guint8 comptype; g_autoptr(GChecksum) checksum = NULL; g_autoptr(GInputStream) checksum_in = NULL; GInputStream *source_in; /* We either take a fd or a GBytes reference */ g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); if (!skip_checksum) { checksum = g_checksum_new (G_CHECKSUM_SHA256); checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); source_in = checksum_in; } else { source_in = part_in; } { guint8 buf[1]; /* First byte is compression type */ if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, cancellable, error)) return glnx_prefix_error (error, "Reading initial compression flag byte"); comptype = buf[0]; } g_autoptr(GVariant) ret_part = NULL; switch (comptype) { case 0: if (!inline_part_bytes) { int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); /* No compression, no checksums - a fast path */ if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) return FALSE; } else { g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, g_bytes_get_size (inline_part_bytes) - 1); ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), content_bytes, trusted); g_variant_ref_sink (ret_part); } if (!skip_checksum) g_checksum_update (checksum, g_variant_get_data (ret_part), g_variant_get_size (ret_part)); break; case 'x': { g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); g_autoptr(GBytes) buf = ot_map_anonymous_tmpfile_from_content (convin, cancellable, error); if (!buf) return FALSE; ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), buf, FALSE); } break; default: return glnx_throw (error, "Invalid compression type '%u'", comptype); } if (checksum) { const char *actual_checksum = g_checksum_get_string (checksum); g_assert (expected_checksum != NULL); if (strcmp (actual_checksum, expected_checksum) != 0) return glnx_throw (error, "Checksum mismatch in static delta part; expected=%s actual=%s", expected_checksum, actual_checksum); } *out_part = g_steal_pointer (&ret_part); return TRUE; }
static void decompress_db (GFile *db, const char *path) { GFile *db_decomp; GFile *db_decomp_tmp; GError *error = NULL; GZlibDecompressor *conv; GInputStream *instream; GInputStream *instream_conv; GOutputStream *outstream; char *tmp_db_path; instream = (GInputStream *) g_file_read (db, NULL, &error); if (!instream) { g_print ("Error opening file: %s", error->message); g_error_free (error); return; } conv = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); instream_conv = (GInputStream *) g_converter_input_stream_new (instream, G_CONVERTER (conv)); g_object_unref (instream); tmp_db_path = g_strdup_printf ("%s.%s", path, "tmp"); db_decomp_tmp = g_file_new_for_path (tmp_db_path); g_free (tmp_db_path); outstream = (GOutputStream *) g_file_replace (db_decomp_tmp, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error); if (!outstream) { g_print ("Error creating file: %s\n", error->message); g_error_free (error); goto end; } if (g_output_stream_splice (outstream, instream_conv, 0, NULL, &error) == -1) { g_print ("Error decompressing the database: %s\n", error->message); g_object_unref (outstream); g_error_free (error); goto end; } if (g_output_stream_close (outstream, NULL, &error) == FALSE) { g_print ("Error decompressing the database: %s\n", error->message); g_error_free (error); } else { db_decomp = g_file_new_for_path (path); if (g_file_move (db_decomp_tmp, db_decomp, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error) == FALSE) { g_print ("Error moving the temporary database file to the" \ " original database file: %s\n", error->message); g_error_free (error); } else { g_print ("Database updated\n"); } g_object_unref (db_decomp); } g_object_unref (outstream); end: g_object_unref (db_decomp_tmp); g_object_unref (conv); g_object_unref (instream_conv); }
/** * gs_plugin_file_to_app: */ gboolean gs_plugin_file_to_app (GsPlugin *plugin, GList **list, GFile *file, GCancellable *cancellable, GError **error) { g_autofree gchar *content_type = NULL; g_autofree gchar *id_prefixed = NULL; g_autoptr(GBytes) appstream_gz = NULL; g_autoptr(GBytes) icon_data = NULL; g_autoptr(GBytes) metadata = NULL; g_autoptr(GsApp) app = NULL; g_autoptr(XdgAppBundleRef) xref_bundle = NULL; const gchar *mimetypes[] = { "application/vnd.xdgapp", NULL }; /* does this match any of the mimetypes we support */ content_type = gs_utils_get_content_type (file, cancellable, error); if (content_type == NULL) return FALSE; if (!g_strv_contains (mimetypes, content_type)) return TRUE; /* load bundle */ xref_bundle = xdg_app_bundle_ref_new (file, error); if (xref_bundle == NULL) { g_prefix_error (error, "error loading bundle: "); return FALSE; } /* create a virtual ID */ id_prefixed = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref_bundle)); /* load metadata */ app = gs_app_new (id_prefixed); gs_app_set_kind (app, AS_APP_KIND_DESKTOP); gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL); gs_app_set_size_installed (app, xdg_app_bundle_ref_get_installed_size (xref_bundle)); gs_plugin_xdg_app_set_metadata (app, XDG_APP_REF (xref_bundle)); metadata = xdg_app_bundle_ref_get_metadata (xref_bundle); if (!gs_plugin_xdg_app_set_app_metadata (app, g_bytes_get_data (metadata, NULL), g_bytes_get_size (metadata), error)) return FALSE; /* load AppStream */ appstream_gz = xdg_app_bundle_ref_get_appstream (xref_bundle); if (appstream_gz != NULL) { g_autoptr(GZlibDecompressor) decompressor = NULL; g_autoptr(GInputStream) stream_gz = NULL; g_autoptr(GInputStream) stream_data = NULL; g_autoptr(GBytes) appstream = NULL; g_autoptr(AsStore) store = NULL; g_autofree gchar *id = NULL; AsApp *item; /* decompress data */ decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); stream_gz = g_memory_input_stream_new_from_bytes (appstream_gz); if (stream_gz == NULL) return FALSE; stream_data = g_converter_input_stream_new (stream_gz, G_CONVERTER (decompressor)); appstream = g_input_stream_read_bytes (stream_data, 0x100000, /* 1Mb */ cancellable, error); if (appstream == NULL) return FALSE; store = as_store_new (); if (!as_store_from_bytes (store, appstream, cancellable, error)) return FALSE; /* find app */ id = g_strdup_printf ("%s.desktop", gs_app_get_xdgapp_name (app)); item = as_store_get_app_by_id (store, id); if (item == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "application %s not found", id); return FALSE; } /* copy details from AppStream to app */ if (!gs_appstream_refine_app (plugin, app, item, error)) return FALSE; } /* load icon */ icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64 * gs_plugin_get_scale (plugin)); if (icon_data == NULL) icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64); if (icon_data != NULL) { g_autoptr(GInputStream) stream_icon = NULL; g_autoptr(GdkPixbuf) pixbuf = NULL; stream_icon = g_memory_input_stream_new_from_bytes (icon_data); pixbuf = gdk_pixbuf_new_from_stream (stream_icon, cancellable, error); if (pixbuf == NULL) return FALSE; gs_app_set_pixbuf (app, pixbuf); } else { g_autoptr(AsIcon) icon = NULL; icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "application-x-executable"); gs_app_set_icon (app, icon); } /* not quite true: this just means we can update this specific app */ if (xdg_app_bundle_ref_get_origin (xref_bundle)) gs_app_add_quirk (app, AS_APP_QUIRK_HAS_SOURCE); g_debug ("created local app: %s", gs_app_to_string (app)); gs_app_list_add (list, app); return TRUE; }
gboolean ostree_content_stream_parse (gboolean compressed, GInputStream *input, guint64 input_length, gboolean trusted, GInputStream **out_input, GFileInfo **out_file_info, GVariant **out_xattrs, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint32 archive_header_size; guchar dummy[4]; gsize bytes_read; ot_lobj GInputStream *ret_input = NULL; ot_lobj GFileInfo *content_file_info = NULL; ot_lobj GFileInfo *ret_file_info = NULL; ot_lvariant GVariant *ret_xattrs = NULL; ot_lvariant GVariant *file_header = NULL; ot_lfree guchar *buf = NULL; if (!g_input_stream_read_all (input, &archive_header_size, 4, &bytes_read, cancellable, error)) goto out; archive_header_size = GUINT32_FROM_BE (archive_header_size); if (archive_header_size > input_length) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "File header size %u exceeds size %" G_GUINT64_FORMAT, (guint)archive_header_size, input_length); goto out; } if (archive_header_size == 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "File header size is zero"); goto out; } /* Skip over padding */ if (!g_input_stream_read_all (input, dummy, 4, &bytes_read, cancellable, error)) goto out; buf = g_malloc (archive_header_size); if (!g_input_stream_read_all (input, buf, archive_header_size, &bytes_read, cancellable, error)) goto out; file_header = g_variant_new_from_data (compressed ? OSTREE_ZLIB_FILE_HEADER_GVARIANT_FORMAT : OSTREE_FILE_HEADER_GVARIANT_FORMAT, buf, archive_header_size, trusted, g_free, buf); buf = NULL; if (compressed) { if (!ostree_zlib_file_header_parse (file_header, out_file_info ? &ret_file_info : NULL, out_xattrs ? &ret_xattrs : NULL, error)) goto out; } else { if (!ostree_file_header_parse (file_header, out_file_info ? &ret_file_info : NULL, out_xattrs ? &ret_xattrs : NULL, error)) goto out; if (ret_file_info) g_file_info_set_size (ret_file_info, input_length - archive_header_size - 8); } if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR && out_input) { /* Give the input stream at its current position as return value; * assuming the caller doesn't seek, this should be fine. We might * want to wrap it though in a non-seekable stream. **/ if (compressed) { ot_lobj GConverter *zlib_decomp = (GConverter*)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); ret_input = g_converter_input_stream_new (input, zlib_decomp); } else ret_input = g_object_ref (input); } ret = TRUE; ot_transfer_out_value (out_input, &ret_input); ot_transfer_out_value (out_file_info, &ret_file_info); ot_transfer_out_value (out_xattrs, &ret_xattrs); out: return ret; }