mirror of
https://github.com/ianlancetaylor/libbacktrace.git
synced 2026-06-13 18:19:09 +08:00
libbacktrace: support compressed block with no sequences
* elf.c (elf_zstd_decompress_frame): Support a compressed block with no sequences, only literals. Fixes #164
This commit is contained in:
113
elf.c
113
elf.c
@@ -4620,6 +4620,11 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
|
||||
pin += 2;
|
||||
}
|
||||
|
||||
pback = NULL;
|
||||
bits = 0;
|
||||
literal_state = 0;
|
||||
offset_state = 0;
|
||||
match_state = 0;
|
||||
if (seq_count > 0)
|
||||
{
|
||||
int (*pfn)(const struct elf_zstd_fse_entry *,
|
||||
@@ -4659,28 +4664,28 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
|
||||
match_fse_table, 9, pfn,
|
||||
&match_decode))
|
||||
return 0;
|
||||
|
||||
pback = pblockend - 1;
|
||||
if (!elf_fetch_backward_init (&pback, pin, &val, &bits))
|
||||
return 0;
|
||||
|
||||
bits -= literal_decode.table_bits;
|
||||
literal_state = ((val >> bits)
|
||||
& ((1U << literal_decode.table_bits) - 1));
|
||||
|
||||
if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
|
||||
return 0;
|
||||
bits -= offset_decode.table_bits;
|
||||
offset_state = ((val >> bits)
|
||||
& ((1U << offset_decode.table_bits) - 1));
|
||||
|
||||
if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
|
||||
return 0;
|
||||
bits -= match_decode.table_bits;
|
||||
match_state = ((val >> bits)
|
||||
& ((1U << match_decode.table_bits) - 1));
|
||||
}
|
||||
|
||||
pback = pblockend - 1;
|
||||
if (!elf_fetch_backward_init (&pback, pin, &val, &bits))
|
||||
return 0;
|
||||
|
||||
bits -= literal_decode.table_bits;
|
||||
literal_state = ((val >> bits)
|
||||
& ((1U << literal_decode.table_bits) - 1));
|
||||
|
||||
if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
|
||||
return 0;
|
||||
bits -= offset_decode.table_bits;
|
||||
offset_state = ((val >> bits)
|
||||
& ((1U << offset_decode.table_bits) - 1));
|
||||
|
||||
if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
|
||||
return 0;
|
||||
bits -= match_decode.table_bits;
|
||||
match_state = ((val >> bits)
|
||||
& ((1U << match_decode.table_bits) - 1));
|
||||
|
||||
seq = 0;
|
||||
while (1)
|
||||
{
|
||||
@@ -4701,6 +4706,40 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
|
||||
uint32_t need;
|
||||
uint32_t add;
|
||||
|
||||
if (unlikely (seq >= seq_count))
|
||||
{
|
||||
/* Copy remaining literals. */
|
||||
if (literal_count > 0 && plit != pout)
|
||||
{
|
||||
if (unlikely ((size_t)(poutend - pout)
|
||||
< literal_count))
|
||||
{
|
||||
elf_uncompress_failed ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((size_t)(plit - pout) < literal_count)
|
||||
{
|
||||
uint32_t move;
|
||||
|
||||
move = plit - pout;
|
||||
while (literal_count > move)
|
||||
{
|
||||
memcpy (pout, plit, move);
|
||||
pout += move;
|
||||
plit += move;
|
||||
literal_count -= move;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (pout, plit, literal_count);
|
||||
}
|
||||
|
||||
pout += literal_count;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
pt = &offset_decode.table[offset_state];
|
||||
offset_basebits = pt->basebits;
|
||||
offset_baseline = pt->baseline;
|
||||
@@ -4938,40 +4977,6 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely (seq >= seq_count))
|
||||
{
|
||||
/* Copy remaining literals. */
|
||||
if (literal_count > 0 && plit != pout)
|
||||
{
|
||||
if (unlikely ((size_t)(poutend - pout)
|
||||
< literal_count))
|
||||
{
|
||||
elf_uncompress_failed ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((size_t)(plit - pout) < literal_count)
|
||||
{
|
||||
uint32_t move;
|
||||
|
||||
move = plit - pout;
|
||||
while (literal_count > move)
|
||||
{
|
||||
memcpy (pout, plit, move);
|
||||
pout += move;
|
||||
plit += move;
|
||||
literal_count -= move;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (pout, plit, literal_count);
|
||||
}
|
||||
|
||||
pout += literal_count;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pin = pblockend;
|
||||
|
||||
Reference in New Issue
Block a user