lzma_filter_flags_decode(
    lzma_filter *filter, lzma_allocator *allocator,
    const uint8_t *in, size_t *in_pos, size_t in_size)
{
    lzma_vli props_size;
    lzma_ret ret;

    // Set the pointer to NULL so the caller can always safely free it.
    filter->options = NULL;

    // Filter ID
    return_if_error(lzma_vli_decode(&filter->id, NULL,
                                    in, in_pos, in_size));

    if (filter->id >= LZMA_FILTER_RESERVED_START)
        return LZMA_DATA_ERROR;

    // Size of Properties
    return_if_error(lzma_vli_decode(&props_size, NULL,
                                    in, in_pos, in_size));

    // Filter Properties
    if (in_size - *in_pos < props_size)
        return LZMA_DATA_ERROR;

    ret = lzma_properties_decode(
              filter, allocator, in + *in_pos, props_size);

    *in_pos += props_size;

    return ret;
}
Esempio n. 2
0
File: coder.c Progetto: Garen/xz
/// Return true if the data in in_buf seems to be in the .lzma format.
static bool
is_format_lzma(void)
{
	// The .lzma header is 13 bytes.
	if (strm.avail_in < 13) {
		return false;
	}
	// Decode the LZMA1 properties.
	lzma_filter filter = { .id = LZMA_FILTER_LZMA1 };
	if (lzma_properties_decode(&filter, NULL, in_buf.u8, 5) != LZMA_OK) {
		return false;
	}
	// A hack to ditch tons of false positives: We allow only dictionary
	// sizes that are 2^n or 2^n + 2^(n-1) or UINT32_MAX. LZMA_Alone
	// created only files with 2^n, but accepts any dictionary size.
	// If someone complains, this will be reconsidered.
	lzma_options_lzma *opt = filter.options;
	const uint32_t dict_size = opt->dict_size;
	free(opt);

	if (dict_size != UINT32_MAX) {
		uint32_t d = dict_size - 1;
		d |= d >> 2;
		d |= d >> 3;
		d |= d >> 4;
		d |= d >> 8;
		d |= d >> 16;
		++d;
		if (d != dict_size || dict_size == 0)
			return false;
	}
Esempio n. 3
0
// refer to src/xz/coder.c in XZ Utils.
int CTarArcFile_Lzma::check_head_format(unsigned char *buf, size_t buf_size, int format_type)
{
	if(buf_size>=6 && memcmp(buf, "\3757zXZ", 6) == 0){
		if(format_type>=0) {
			return format_type==ARCHIVETYPE_XZ;
		} else {
			return ARCHIVETYPE_XZ;
		}
	}
	while(buf_size>=13){
		lzma_filter filter;
		filter.id = LZMA_FILTER_LZMA1;
		if(lzma_properties_decode(&filter, NULL, buf, 5) != LZMA_OK){
			break;
		}
		lzma_options_lzma *opt = (lzma_options_lzma *)(filter.options);
		const uint32_t dict_size = opt->dict_size;
//		free(opt);

		if (dict_size != UINT32_MAX) {
			uint32_t d = dict_size - 1;
			d |= d >> 2;
			d |= d >> 3;
			d |= d >> 4;
			d |= d >> 8;
			d |= d >> 16;
			++d;
			if (d != dict_size || dict_size == 0)
				break;
		}

		uint64_t uncompressed_size = 0;
		for (size_t i = 0; i < 8; ++i)
			uncompressed_size |= (uint64_t)(buf[5 + i]) << (i * 8);

		if (uncompressed_size != UINT64_MAX && uncompressed_size > (UINT64_C(1) << 38)){
			break;
		}
		if(format_type>=0) {
			return format_type==ARCHIVETYPE_LZMA;
		} else {
			return ARCHIVETYPE_LZMA;
		}
	}
Esempio n. 4
0
static PyObject *
_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props)
/*[clinic end generated code: output=235f7f5345d48744 input=246410800782160c]*/
{
    lzma_filter filter;
    lzma_ret lzret;
    PyObject *result = NULL;
    filter.id = filter_id;

    lzret = lzma_properties_decode(
            &filter, NULL, encoded_props->buf, encoded_props->len);
    if (catch_lzma_error(lzret))
        return NULL;

    result = build_filter_spec(&filter);

    /* We use vanilla free() here instead of PyMem_Free() - filter.options was
       allocated by lzma_properties_decode() using the default allocator. */
    free(filter.options);
    return result;
}
Esempio n. 5
0
/// Parse the .lzma header and display information about it.
static bool
lzmainfo(const char *name, FILE *f)
{
	uint8_t buf[13];
	const size_t size = fread(buf, 1, sizeof(buf), f);
	if (size != 13) {
		fprintf(stderr, "%s: %s: %s\n", progname, name,
				ferror(f) ? strerror(errno)
				: _("File is too small to be a .lzma file"));
		return true;
	}

	lzma_filter filter = { .id = LZMA_FILTER_LZMA1 };

	// Parse the first five bytes.
	switch (lzma_properties_decode(&filter, NULL, buf, 5)) {
	case LZMA_OK:
		break;

	case LZMA_OPTIONS_ERROR:
		fprintf(stderr, "%s: %s: %s\n", progname, name,
				_("Not a .lzma file"));
		return true;

	case LZMA_MEM_ERROR:
		fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM));
		exit(EXIT_FAILURE);

	default:
		fprintf(stderr, "%s: %s\n", progname,
				_("Internal error (bug)"));
		exit(EXIT_FAILURE);
	}

	// Uncompressed size
	uint64_t uncompressed_size = 0;
	for (size_t i = 0; i < 8; ++i)
		uncompressed_size |= (uint64_t)(buf[5 + i]) << (i * 8);

	// Display the results. We don't want to translate these and also
	// will use MB instead of MiB, because someone could be parsing
	// this output and we don't want to break that when people move
	// from LZMA Utils to XZ Utils.
	if (f != stdin)
		printf("%s\n", name);

	printf("Uncompressed size:             ");
	if (uncompressed_size == UINT64_MAX)
		printf("Unknown");
	else
		printf("%" PRIu64 " MB (%" PRIu64 " bytes)",
				(uncompressed_size + 512 * 1024)
					/ (1024 * 1024),
				uncompressed_size);

	lzma_options_lzma *opt = filter.options;

	printf("\nDictionary size:               "
			"%" PRIu32 " MB (2^%" PRIu32 " bytes)\n"
			"Literal context bits (lc):     %" PRIu32 "\n"
			"Literal pos bits (lp):         %" PRIu32 "\n"
			"Number of pos bits (pb):       %" PRIu32 "\n",
			(opt->dict_size + 512 * 1024) / (1024 * 1024),
			my_log2(opt->dict_size), opt->lc, opt->lp, opt->pb);

	free(opt);

	return false;
}