Skip to content

Commit 3ef17f6

Browse files
committed
Fix bug with RANS_ORDER_STRIPE on large blocks.
The meta-data is 2 bytes for order + N, ? bytes for original size, and ?*N bytes for the N compressed sizes. We forgot about the original size so only left room for 2+5*N (with 5 being the maximum size of a 32-bit var int). So blocks larger than 2^28 risked not fitting in the allocated meta-data size. Reported by Divon Lan.
1 parent 3891cb6 commit 3ef17f6

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

NEWS.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Release 1.3.0: 19th July 2022
2-
-----------------------------
1+
Release 1.3.0: 9th August 2022
2+
------------------------------
33

44
The primary change in this release is a new SIMD enabled rANS codec.
55

@@ -49,6 +49,8 @@ Bug fixes
4949
(Additionally blocks above 2GB now error, rather than crashing or
5050
returning incorrect results.)
5151

52+
- Fix encode error with large blocks using RANS_ORDER_STRIPE.
53+
5254

5355
Release 1.2.2: 1st April 2022
5456
-----------------------------

htscodecs/arith_dynamic.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,14 @@
7575
#define MAGIC 8
7676

7777
unsigned int arith_compress_bound(unsigned int size, int order) {
78+
int N = (order>>8) & 0xff;
79+
if (!N) N=4;
7880
return (order == 0
7981
? 1.05*size + 257*3 + 4
80-
: 1.05*size + 257*257*3 + 4 + 257*3+4) +
82+
: 1.05*size + 257*257*3 + 4 + 257*3+4) + 5 +
8183
((order & X_PACK) ? 1 : 0) +
82-
((order & X_RLE) ? 1 + 257*3+4: 0) + 5;
84+
((order & X_RLE) ? 1 + 257*3+4: 0) +
85+
((order & X_STRIPE) ? 7 + 5*N: 0);
8386
}
8487

8588
#ifndef MODEL_256 // see fqzcomp_qual_fuzz.c
@@ -735,7 +738,7 @@ unsigned char *arith_compress_to(unsigned char *in, unsigned int in_size,
735738
c_meta_len += var_put_u32(out+c_meta_len, out_end, in_size);
736739
out[c_meta_len++] = N;
737740

738-
out2_start = out2 = out+2+5*N; // shares a buffer with c_meta
741+
out2_start = out2 = out+7+5*N; // shares a buffer with c_meta
739742
for (i = 0; i < N; i++) {
740743
// Brute force try all methods.
741744
// FIXME: optimise this bit. Maybe learn over time?

htscodecs/rANS_static4x16pr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ unsigned int rans_compress_bound_4x16(unsigned int size, int order) {
9797
((order & RANS_ORDER_PACK) ? 1 : 0) +
9898
((order & RANS_ORDER_RLE) ? 1 + 257*3+4: 0) + 20 +
9999
((order & RANS_ORDER_X32) ? (32-4)*4 : 0) +
100-
((order & RANS_ORDER_STRIPE) ? 1 + 5*N: 0);
100+
((order & RANS_ORDER_STRIPE) ? 7 + 5*N: 0);
101101
return sz + (sz&1) + 2; // make this even so buffers are word aligned
102102
}
103103

@@ -1181,7 +1181,7 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
11811181
unsigned char *out_best = NULL;
11821182
unsigned int out_best_len = 0;
11831183

1184-
out2_start = out2 = out+2+5*N; // shares a buffer with c_meta
1184+
out2_start = out2 = out+7+5*N; // shares a buffer with c_meta
11851185
for (i = 0; i < N; i++) {
11861186
// Brute force try all methods.
11871187
int j, m[] = {1,64,128,0}, best_j = 0, best_sz = in_size+10;

0 commit comments

Comments
 (0)