Skip to content

Commit c4aa5e6

Browse files
committed
std/xz: enforce BCJ offset alignment
1 parent d446e71 commit c4aa5e6

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

release/c/wuffs-unsupported-snapshot.c

+22-1
Original file line numberDiff line numberDiff line change
@@ -14061,6 +14061,7 @@ struct wuffs_xxhash64__hasher__struct {
1406114061

1406214062
// ---------------- Status Codes
1406314063

14064+
extern const char wuffs_xz__error__bad_bcj_offset[];
1406414065
extern const char wuffs_xz__error__bad_block_header[];
1406514066
extern const char wuffs_xz__error__bad_checksum[];
1406614067
extern const char wuffs_xz__error__bad_filter[];
@@ -14250,6 +14251,7 @@ struct wuffs_xz__decoder__struct {
1425014251
} s_decode_block_header_with_padding;
1425114252
struct {
1425214253
uint8_t v_flags;
14254+
uint8_t v_filter_id;
1425314255
uint32_t v_shift;
1425414256
uint32_t v_f;
1425514257
uint64_t scratch;
@@ -69501,6 +69503,7 @@ wuffs_xxhash64__hasher__checksum_u64(
6950169503

6950269504
// ---------------- Status Codes Implementations
6950369505

69506+
const char wuffs_xz__error__bad_bcj_offset[] = "#xz: bad BCJ offset";
6950469507
const char wuffs_xz__error__bad_block_header[] = "#xz: bad block header";
6950569508
const char wuffs_xz__error__bad_checksum[] = "#xz: bad checksum";
6950669509
const char wuffs_xz__error__bad_filter[] = "#xz: bad filter";
@@ -69552,6 +69555,12 @@ WUFFS_XZ__ZEROES[3] WUFFS_BASE__POTENTIALLY_UNUSED = {
6955269555
0u, 0u, 0u,
6955369556
};
6955469557

69558+
static const uint8_t
69559+
WUFFS_XZ__BCJ_OFFSET_ALIGNMENT[12] WUFFS_BASE__POTENTIALLY_UNUSED = {
69560+
0u, 0u, 0u, 0u, 1u, 4u, 16u, 4u,
69561+
2u, 4u, 4u, 2u,
69562+
};
69563+
6955569564
// ---------------- Private Initializer Prototypes
6955669565

6955769566
// ---------------- Private Function Prototypes
@@ -71352,6 +71361,8 @@ wuffs_xz__decoder__decode_block_header_sans_padding(
7135271361
wuffs_base__status status = wuffs_base__make_status(NULL);
7135371362

7135471363
uint8_t v_c8 = 0;
71364+
uint32_t v_c32 = 0;
71365+
uint32_t v_alignment = 0;
7135571366
uint8_t v_flags = 0;
7135671367
uint8_t v_filter_id = 0;
7135771368
wuffs_base__status v_status = wuffs_base__make_status(NULL);
@@ -71373,6 +71384,7 @@ wuffs_xz__decoder__decode_block_header_sans_padding(
7137371384
uint32_t coro_susp_point = self->private_impl.p_decode_block_header_sans_padding;
7137471385
if (coro_susp_point) {
7137571386
v_flags = self->private_data.s_decode_block_header_sans_padding.v_flags;
71387+
v_filter_id = self->private_data.s_decode_block_header_sans_padding.v_filter_id;
7137671388
v_shift = self->private_data.s_decode_block_header_sans_padding.v_shift;
7137771389
v_f = self->private_data.s_decode_block_header_sans_padding.v_f;
7137871390
}
@@ -71575,8 +71587,16 @@ wuffs_xz__decoder__decode_block_header_sans_padding(
7157571587
*scratch |= ((uint64_t)(num_bits_7)) << 56;
7157671588
}
7157771589
}
71578-
self->private_impl.f_bcj_pos = t_7;
71590+
v_c32 = t_7;
71591+
}
71592+
v_alignment = ((uint32_t)(WUFFS_XZ__BCJ_OFFSET_ALIGNMENT[v_filter_id]));
71593+
if (v_alignment > 0u) {
71594+
if ((v_c32 % v_alignment) != 0u) {
71595+
status = wuffs_base__make_status(wuffs_xz__error__bad_bcj_offset);
71596+
goto exit;
71597+
}
7157971598
}
71599+
self->private_impl.f_bcj_pos = v_c32;
7158071600
} else {
7158171601
status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter);
7158271602
goto exit;
@@ -71643,6 +71663,7 @@ wuffs_xz__decoder__decode_block_header_sans_padding(
7164371663
suspend:
7164471664
self->private_impl.p_decode_block_header_sans_padding = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
7164571665
self->private_data.s_decode_block_header_sans_padding.v_flags = v_flags;
71666+
self->private_data.s_decode_block_header_sans_padding.v_filter_id = v_filter_id;
7164671667
self->private_data.s_decode_block_header_sans_padding.v_shift = v_shift;
7164771668
self->private_data.s_decode_block_header_sans_padding.v_f = v_f;
7164871669

std/xz/decode_xz.wuffs

+28-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use "std/crc64"
1717
use "std/lzma"
1818
use "std/sha256"
1919

20+
pub status "#bad BCJ offset"
2021
pub status "#bad block header"
2122
pub status "#bad checksum"
2223
pub status "#bad filter"
@@ -512,6 +513,8 @@ pri func decoder.decode_block_header_with_padding?(src: base.io_reader) {
512513

513514
pri func decoder.decode_block_header_sans_padding?(src: base.io_reader) {
514515
var c8 : base.u8
516+
var c32 : base.u32
517+
var alignment : base.u32
515518
var flags : base.u8
516519
var filter_id : base.u8
517520
var status : base.status
@@ -633,7 +636,14 @@ pri func decoder.decode_block_header_sans_padding?(src: base.io_reader) {
633636
if c8 == 0x00 {
634637
this.bcj_pos = 0
635638
} else if c8 == 0x04 {
636-
this.bcj_pos = args.src.read_u32le?()
639+
c32 = args.src.read_u32le?()
640+
alignment = BCJ_OFFSET_ALIGNMENT[filter_id] as base.u32
641+
if alignment > 0 {
642+
if (c32 % alignment) <> 0 {
643+
return "#bad BCJ offset"
644+
}
645+
}
646+
this.bcj_pos = c32
637647
} else {
638648
return "#unsupported filter"
639649
}
@@ -800,3 +810,20 @@ pri const CHECKSUM_LENGTH : roarray[4] base.u8 = [
800810
]
801811

802812
pri const ZEROES : roarray[3] base.u8 = [0, 0, 0]
813+
814+
// See https://tukaani.org/xz/xz-file-format.txt section 5.3.2.
815+
// Branch/Call/Jump Filters for Executables.
816+
pri const BCJ_OFFSET_ALIGNMENT : roarray[12] base.u8 = [
817+
0x00, // 0x00: Unused.
818+
0x00, // 0x01: Unused.
819+
0x00, // 0x02: Unused.
820+
0x00, // 0x03: Unused.
821+
0x01, // 0x04: x86.
822+
0x04, // 0x05: powerpc.
823+
0x10, // 0x06: ia64.
824+
0x04, // 0x07: arm.
825+
0x02, // 0x08: armthumb.
826+
0x04, // 0x09: sparc.
827+
0x04, // 0x0A: arm64.
828+
0x02, // 0x0B: riscv.
829+
]

0 commit comments

Comments
 (0)