Skip to content

Commit 858d0b2

Browse files
committed
stage1/decompressor: Ensure limlz streams always end on a literal token
1 parent e9a95e0 commit 858d0b2

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

stage1/decompressor.asm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ _start:
7575
mov esi, ecx
7676
lea ecx, [eax+0x4] ; count = matchlen + 4
7777
rep movsb ; copy match
78+
cmp edx, ebx ; guard against streams that end on a match
79+
jae .Lcrc
7880
jmp .Ltoken
7981
; CRC32 verification
8082
.Lcrc:

tools/limlzpack.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ static size_t limlzpack(void * dst, size_t dstcap, const void * srcv, size_t src
218218
dp[i] = best_cost; pick[i].lit = best_lit;
219219
pick[i].mlen = best_len; pick[i].off = best_off;
220220
}
221+
int terminated = 0;
221222
for (i = 0; i < srcsz; ) {
222223
byte * tokenp;
223224
size_t lit = pick[i].lit, ml = pick[i].mlen;
@@ -241,6 +242,7 @@ static size_t limlzpack(void * dst, size_t dstcap, const void * srcv, size_t src
241242
i += lit;
242243
if (i >= srcsz) {
243244
*tokenp = (byte)(token_hi << 3);
245+
terminated = 1;
244246
break;
245247
}
246248
unsigned mode_bit = (off > 255) ? 1u : 0u;
@@ -260,6 +262,14 @@ static size_t limlzpack(void * dst, size_t dstcap, const void * srcv, size_t src
260262
goto fail;
261263
i += ml;
262264
}
265+
/* A match-ended parse leaves no trailing token; the decompressor keys
266+
* termination off a zero-or-more-byte literal copy reaching ipe, so always
267+
* emit a final lit=0 token when the main loop didn't already. */
268+
if (!terminated) {
269+
if (out >= out_end)
270+
goto fail;
271+
*out++ = 0;
272+
}
263273
free(mch); free(pick); free(bestm); free(dp);
264274
return (size_t)(out - dstp);
265275
fail:

0 commit comments

Comments
 (0)