Skip to content

Commit d744cee

Browse files
committed
FIX: memory corruption when used crush compression
1 parent b7fb49b commit d744cee

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/core/u-crush.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static inline int get_penalty(int a, int b) {
162162

163163
level = MAX(0, MIN(2, level));
164164

165-
ser = Make_Series(size + 4, sizeof(REBYTE), FALSE);
165+
ser = Make_Series(MAX(16, size+4), sizeof(REBYTE), FALSE);
166166
ctx.data = BIN_HEAD(ser);
167167

168168
((REBCNT *)ctx.data)[0] = size;
@@ -261,10 +261,11 @@ static inline int get_penalty(int a, int b) {
261261
}
262262
}
263263

264-
if (ctx.index >= SERIES_AVAIL(ser)) {
265-
// If input is already well compressed, output from the Crush may be larger!
264+
// If input is already well compressed, output from the Crush may be larger!
265+
// Instead of adding this check to each `put_bits` call, count with some hopefuly safe range (16bytes)
266+
if (ctx.index+16 >= SERIES_REST(ser)) {
266267
SERIES_TAIL(ser) = ctx.index;
267-
Expand_Series(ser, ctx.index, SERIES_AVAIL(ser) >> 3); // using 1/4 of the current size for the delta
268+
Expand_Series(ser, ctx.index, MAX(16, SERIES_REST(ser) >> 3)); // using 1/4 of the current size for the delta
268269
ctx.data = BIN_DATA(ser);
269270
}
270271

src/tests/units/compress-test.r3

+10-1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ text: {Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempo
186186

187187
--test-- "CRUSH decompress when not at head"
188188
--assert data = to string! decompress next join #{00} compress data 'crush 'crush
189+
190+
--test-- "CRUSH with bad compression ratio"
191+
; CRUSH algorithm does not work well if there is no repeatable pattern
192+
; These asserts also validates, that there is no memory coruption as internal extension is used
193+
--assert #{0400000062C8984103} = compress "1234" 'crush
194+
--assert #{0800000062C89841A3868D1B38} = compress "12345678" 'crush
195+
--assert #{0D00000062C89841A3868D1B38720411328408} = compress "123456789ABCD" 'crush
196+
--assert #{1100000062C89841A3868D1B387204113284481123479000} = compress "123456789ABCDEFGH" 'crush
197+
--assert #{1500000062C89841A3868D1B38720411328448112347902451B28409} = compress "123456789ABCDEFGHIJKL" 'crush
189198
]
190199
===end-group===
191200

@@ -195,7 +204,7 @@ text: {Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempo
195204
--assert (a: compress "a" 'zlib) = #{789C4B040000620062}
196205
--assert (b: encloak a "a") = #{2CD6F679DCDC44E141}
197206
--assert (c: decloak b "a") = #{789C4B040000620062}
198-
--assert (d: decompress c 'zlib) = #{61}
207+
--assert (d: decompress a 'zlib) = #{61}
199208

200209
===end-group===
201210

0 commit comments

Comments
 (0)