stage1/decompressor: Ensure limlz streams always end on a literal token
This commit is contained in:
@@ -75,6 +75,8 @@ _start:
|
|||||||
mov esi, ecx
|
mov esi, ecx
|
||||||
lea ecx, [eax+0x4] ; count = matchlen + 4
|
lea ecx, [eax+0x4] ; count = matchlen + 4
|
||||||
rep movsb ; copy match
|
rep movsb ; copy match
|
||||||
|
cmp edx, ebx ; guard against streams that end on a match
|
||||||
|
jae .Lcrc
|
||||||
jmp .Ltoken
|
jmp .Ltoken
|
||||||
; CRC32 verification
|
; CRC32 verification
|
||||||
.Lcrc:
|
.Lcrc:
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ static size_t limlzpack(void * dst, size_t dstcap, const void * srcv, size_t src
|
|||||||
dp[i] = best_cost; pick[i].lit = best_lit;
|
dp[i] = best_cost; pick[i].lit = best_lit;
|
||||||
pick[i].mlen = best_len; pick[i].off = best_off;
|
pick[i].mlen = best_len; pick[i].off = best_off;
|
||||||
}
|
}
|
||||||
|
int terminated = 0;
|
||||||
for (i = 0; i < srcsz; ) {
|
for (i = 0; i < srcsz; ) {
|
||||||
byte * tokenp;
|
byte * tokenp;
|
||||||
size_t lit = pick[i].lit, ml = pick[i].mlen;
|
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
|
|||||||
i += lit;
|
i += lit;
|
||||||
if (i >= srcsz) {
|
if (i >= srcsz) {
|
||||||
*tokenp = (byte)(token_hi << 3);
|
*tokenp = (byte)(token_hi << 3);
|
||||||
|
terminated = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
unsigned mode_bit = (off > 255) ? 1u : 0u;
|
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
|
|||||||
goto fail;
|
goto fail;
|
||||||
i += ml;
|
i += ml;
|
||||||
}
|
}
|
||||||
|
/* A match-ended parse leaves no trailing token; the decompressor keys
|
||||||
|
* termination off a zero-or-more-byte literal copy reaching ipe, so always
|
||||||
|
* emit a final lit=0 token when the main loop didn't already. */
|
||||||
|
if (!terminated) {
|
||||||
|
if (out >= out_end)
|
||||||
|
goto fail;
|
||||||
|
*out++ = 0;
|
||||||
|
}
|
||||||
free(mch); free(pick); free(bestm); free(dp);
|
free(mch); free(pick); free(bestm); free(dp);
|
||||||
return (size_t)(out - dstp);
|
return (size_t)(out - dstp);
|
||||||
fail:
|
fail:
|
||||||
|
|||||||
Reference in New Issue
Block a user