mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
cd69a5a6c1
This is a quick and slightly dirty fix to make the code conform to the latest file format specification. Without this patch, it's possible to make corrupt files by specifying start offset that is not a multiple of the filter's alignment. Custom start offset is almost never used, so this was only a minor bug. The xz command line tool doesn't validate the start offset, so one will get a bit unclear error message if trying to use an invalid start offset.
74 lines
1.8 KiB
C
74 lines
1.8 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
/// \file armthumb.c
|
|
/// \brief Filter for ARM-Thumb binaries
|
|
///
|
|
// Authors: Igor Pavlov
|
|
// Lasse Collin
|
|
//
|
|
// This file has been put into the public domain.
|
|
// You can do whatever you want with this file.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "simple_private.h"
|
|
|
|
|
|
static size_t
|
|
armthumb_code(lzma_simple *simple lzma_attribute((unused)),
|
|
uint32_t now_pos, bool is_encoder,
|
|
uint8_t *buffer, size_t size)
|
|
{
|
|
size_t i;
|
|
for (i = 0; i + 4 <= size; i += 2) {
|
|
if ((buffer[i + 1] & 0xF8) == 0xF0
|
|
&& (buffer[i + 3] & 0xF8) == 0xF8) {
|
|
uint32_t src = ((buffer[i + 1] & 0x7) << 19)
|
|
| (buffer[i + 0] << 11)
|
|
| ((buffer[i + 3] & 0x7) << 8)
|
|
| (buffer[i + 2]);
|
|
|
|
src <<= 1;
|
|
|
|
uint32_t dest;
|
|
if (is_encoder)
|
|
dest = now_pos + (uint32_t)(i) + 4 + src;
|
|
else
|
|
dest = src - (now_pos + (uint32_t)(i) + 4);
|
|
|
|
dest >>= 1;
|
|
buffer[i + 1] = 0xF0 | ((dest >> 19) & 0x7);
|
|
buffer[i + 0] = (dest >> 11);
|
|
buffer[i + 3] = 0xF8 | ((dest >> 8) & 0x7);
|
|
buffer[i + 2] = (dest);
|
|
i += 2;
|
|
}
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
static lzma_ret
|
|
armthumb_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
|
const lzma_filter_info *filters, bool is_encoder)
|
|
{
|
|
return lzma_simple_coder_init(next, allocator, filters,
|
|
&armthumb_code, 0, 4, 2, is_encoder);
|
|
}
|
|
|
|
|
|
extern lzma_ret
|
|
lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
|
|
lzma_allocator *allocator, const lzma_filter_info *filters)
|
|
{
|
|
return armthumb_coder_init(next, allocator, filters, true);
|
|
}
|
|
|
|
|
|
extern lzma_ret
|
|
lzma_simple_armthumb_decoder_init(lzma_next_coder *next,
|
|
lzma_allocator *allocator, const lzma_filter_info *filters)
|
|
{
|
|
return armthumb_coder_init(next, allocator, filters, false);
|
|
}
|