Ejemplo n.º 1
0
static void
test_header(void)
{
	memcrap(buffer, sizeof(buffer));
	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
	succeed(test_header_decoder(LZMA_OK));
}
Ejemplo n.º 2
0
static void
test_decode_invalid(void)
{
	known_flags.check = LZMA_CHECK_NONE;
	known_flags.backward_size = 1024;

	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);

	// Test 1 (invalid Magic Bytes)
	buffer[5] ^= 1;
	succeed(test_header_decoder(LZMA_FORMAT_ERROR));
	buffer[5] ^= 1;

	// Test 2a (valid CRC32)
	uint32_t crc = lzma_crc32(buffer + 6, 2, 0);
	unaligned_write32le(buffer + 8, crc);
	succeed(test_header_decoder(LZMA_OK));

	// Test 2b (invalid Stream Flags with valid CRC32)
	buffer[6] ^= 0x20;
	crc = lzma_crc32(buffer + 6, 2, 0);
	unaligned_write32le(buffer + 8, crc);
	succeed(test_header_decoder(LZMA_OPTIONS_ERROR));

	// Test 3 (invalid CRC32)
	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
	buffer[9] ^= 1;
	succeed(test_header_decoder(LZMA_DATA_ERROR));

	// Test 4 (invalid Stream Flags with valid CRC32)
	expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
	buffer[9] ^= 0x40;
	crc = lzma_crc32(buffer + 4, 6, 0);
	unaligned_write32le(buffer, crc);
	succeed(test_footer_decoder(LZMA_OPTIONS_ERROR));

	// Test 5 (invalid Magic Bytes)
	expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
	buffer[11] ^= 1;
	succeed(test_footer_decoder(LZMA_FORMAT_ERROR));
}
Ejemplo n.º 3
0
static void
test_encode_invalid(void)
{
	known_flags.check = LZMA_CHECK_ID_MAX + 1;
	known_flags.backward_size = 1024;

	expect(lzma_stream_header_encode(&known_flags, buffer)
			== LZMA_PROG_ERROR);

	expect(lzma_stream_footer_encode(&known_flags, buffer)
			== LZMA_PROG_ERROR);

	known_flags.check = (lzma_check)(-1);

	expect(lzma_stream_header_encode(&known_flags, buffer)
			== LZMA_PROG_ERROR);

	expect(lzma_stream_footer_encode(&known_flags, buffer)
			== LZMA_PROG_ERROR);

	known_flags.check = LZMA_CHECK_NONE;
	known_flags.backward_size = 0;

	// Header encoder ignores backward_size.
	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);

	expect(lzma_stream_footer_encode(&known_flags, buffer)
			== LZMA_PROG_ERROR);

	known_flags.backward_size = LZMA_VLI_MAX;

	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);

	expect(lzma_stream_footer_encode(&known_flags, buffer)
			== LZMA_PROG_ERROR);
}
Ejemplo n.º 4
0
static lzma_ret
stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
		const lzma_filter *filters, lzma_check check)
{
	lzma_next_coder_init(&stream_encoder_init, next, allocator);

	if (filters == NULL)
		return LZMA_PROG_ERROR;

	if (next->coder == NULL) {
		next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
		if (next->coder == NULL)
			return LZMA_MEM_ERROR;

		next->code = &stream_encode;
		next->end = &stream_encoder_end;
		next->update = &stream_encoder_update;

		next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
		next->coder->block_encoder = LZMA_NEXT_CODER_INIT;
		next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
		next->coder->index = NULL;
	}

	// Basic initializations
	next->coder->sequence = SEQ_STREAM_HEADER;
	next->coder->block_options.version = 0;
	next->coder->block_options.check = check;

	// Initialize the Index
	lzma_index_end(next->coder->index, allocator);
	next->coder->index = lzma_index_init(allocator);
	if (next->coder->index == NULL)
		return LZMA_MEM_ERROR;

	// Encode the Stream Header
	lzma_stream_flags stream_flags = {
		.version = 0,
		.check = check,
	};
	return_if_error(lzma_stream_header_encode(
			&stream_flags, next->coder->buffer));

	next->coder->buffer_pos = 0;
	next->coder->buffer_size = LZMA_STREAM_HEADER_SIZE;

	// Initialize the Block encoder. This way we detect unsupported
	// filter chains when initializing the Stream encoder instead of
	// giving an error after Stream Header has already written out.
	return stream_encoder_update(
			next->coder, allocator, filters, NULL);
}


extern LZMA_API(lzma_ret)
lzma_stream_encoder(lzma_stream *strm,
		const lzma_filter *filters, lzma_check check)
{
	lzma_next_strm_init(stream_encoder_init, strm, filters, check);

	strm->internal->supported_actions[LZMA_RUN] = true;
	strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
	strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
	strm->internal->supported_actions[LZMA_FINISH] = true;

	return LZMA_OK;
}
Ejemplo n.º 5
0
lzma_stream_buffer_encode(lzma_filter *filters, lzma_check check,
		lzma_allocator *allocator, const uint8_t *in, size_t in_size,
		uint8_t *out, size_t *out_pos_ptr, size_t out_size)
{
	// Sanity checks
	if (filters == NULL || (unsigned int)(check) > LZMA_CHECK_ID_MAX
			|| (in == NULL && in_size != 0) || out == NULL
			|| out_pos_ptr == NULL || *out_pos_ptr > out_size)
		return LZMA_PROG_ERROR;

	if (!lzma_check_is_supported(check))
		return LZMA_UNSUPPORTED_CHECK;

	// Note for the paranoids: Index encoder prevents the Stream from
	// getting too big and still being accepted with LZMA_OK, and Block
	// encoder catches if the input is too big. So we don't need to
	// separately check if the buffers are too big.

	// Use a local copy. We update *out_pos_ptr only if everything
	// succeeds.
	size_t out_pos = *out_pos_ptr;

	// Check that there's enough space for both Stream Header and
	// Stream Footer.
	if (out_size - out_pos <= 2 * LZMA_STREAM_HEADER_SIZE)
		return LZMA_BUF_ERROR;

	// Reserve space for Stream Footer so we don't need to check for
	// available space again before encoding Stream Footer.
	out_size -= LZMA_STREAM_HEADER_SIZE;

	// Encode the Stream Header.
	lzma_stream_flags stream_flags = {
		.version = 0,
		.check = check,
	};

	if (lzma_stream_header_encode(&stream_flags, out + out_pos)
			!= LZMA_OK)
		return LZMA_PROG_ERROR;

	out_pos += LZMA_STREAM_HEADER_SIZE;

	// Encode a Block but only if there is at least one byte of input.
	lzma_block block = {
		.version = 0,
		.check = check,
		.filters = filters,
	};

	if (in_size > 0)
		return_if_error(lzma_block_buffer_encode(&block, allocator,
				in, in_size, out, &out_pos, out_size));

	// Index
	{
		// Create an Index. It will have one Record if there was
		// at least one byte of input to encode. Otherwise the
		// Index will be empty.
		lzma_index *i = lzma_index_init(allocator);
		if (i == NULL)
			return LZMA_MEM_ERROR;

		lzma_ret ret = LZMA_OK;

		if (in_size > 0)
			ret = lzma_index_append(i, allocator,
					lzma_block_unpadded_size(&block),
					block.uncompressed_size);

		// If adding the Record was successful, encode the Index
		// and get its size which will be stored into Stream Footer.
		if (ret == LZMA_OK) {
			ret = lzma_index_buffer_encode(
					i, out, &out_pos, out_size);

			stream_flags.backward_size = lzma_index_size(i);
		}

		lzma_index_end(i, allocator);

		if (ret != LZMA_OK)
			return ret;
	}

	// Stream Footer. We have already reserved space for this.
	if (lzma_stream_footer_encode(&stream_flags, out + out_pos)
			!= LZMA_OK)
		return LZMA_PROG_ERROR;

	out_pos += LZMA_STREAM_HEADER_SIZE;

	// Everything went fine, make the new output position available
	// to the application.
	*out_pos_ptr = out_pos;
	return LZMA_OK;
}