Skip to content

Commit 20d4f9e

Browse files
ematsumiyasmfrench
authored andcommitted
smb: client: compress: fix counting in LZ77 match finding
- lz77_match_len() increments @Cur before checking for equality, leading to off-by-one match len in some cases. Fix by moving pointers increment to inside the loop. Also rename @wnd arg to @match (more accurate name). - both lz77_match_len() and lz77_compress() checked for "buf + step < end" when the correct is "<=" for such cases. Signed-off-by: Enzo Matsumiya <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 4c22171 commit 20d4f9e

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

fs/smb/client/compress/lz77.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ static __always_inline void lz77_write32(u32 *ptr, u32 v)
4848
put_unaligned_le32(v, ptr);
4949
}
5050

51-
static __always_inline u32 lz77_match_len(const void *wnd, const void *cur, const void *end)
51+
static __always_inline u32 lz77_match_len(const void *match, const void *cur, const void *end)
5252
{
5353
const void *start = cur;
5454
u64 diff;
5555

5656
/* Safe for a do/while because otherwise we wouldn't reach here from the main loop. */
5757
do {
58-
diff = lz77_read64(cur) ^ lz77_read64(wnd);
58+
diff = lz77_read64(cur) ^ lz77_read64(match);
5959
if (!diff) {
6060
cur += LZ77_STEP_SIZE;
61-
wnd += LZ77_STEP_SIZE;
61+
match += LZ77_STEP_SIZE;
6262

6363
continue;
6464
}
@@ -67,10 +67,13 @@ static __always_inline u32 lz77_match_len(const void *wnd, const void *cur, cons
6767
cur += count_trailing_zeros(diff) >> 3;
6868

6969
return (cur - start);
70-
} while (likely(cur + LZ77_STEP_SIZE < end));
70+
} while (likely(cur + LZ77_STEP_SIZE <= end));
7171

72-
while (cur < end && lz77_read8(cur++) == lz77_read8(wnd++))
73-
;
72+
/* Fallback to byte-by-byte comparison for last <8 bytes. */
73+
while (cur < end && lz77_read8(cur) == lz77_read8(match)) {
74+
cur++;
75+
match++;
76+
}
7477

7578
return (cur - start);
7679
}
@@ -195,7 +198,7 @@ noinline int lz77_compress(const void *src, u32 slen, void *dst, u32 *dlen)
195198
flag_pos = dstp;
196199
dstp += 4;
197200
}
198-
} while (likely(srcp + LZ77_STEP_SIZE < end));
201+
} while (likely(srcp + LZ77_STEP_SIZE <= end));
199202

200203
while (srcp < end) {
201204
u32 c = umin(end - srcp, 32 - flag_count);

0 commit comments

Comments
 (0)