fix decompress algorithm

This commit is contained in:
Le Duc Anh
2025-10-14 10:35:43 +07:00
parent 3674ffba43
commit 5199df61f0
@@ -93,6 +93,34 @@ namespace CSNetwork.Security
}
}
// Copy bytes from history using MPPC's 8 KB circular window semantics.
// Source starts at (historyPos - offset) modulo window size and may overlap
// destination; freshly written bytes must be visible to subsequent reads.
private void CopyFromHistoryCircular(int offset, int length)
{
int srcPos = historyPos - offset;
if (srcPos < 0)
srcPos += MPPC_HIST_LEN; // wrap source into window
int dstPos = historyPos;
while (length-- > 0)
{
history[dstPos] = history[srcPos];
dstPos++;
if (dstPos == MPPC_HIST_LEN)
dstPos = 0; // wrap destination
srcPos++;
if (srcPos == MPPC_HIST_LEN)
srcPos = 0; // wrap source
}
// Advance history head to the end of the copied sequence
historyPos = dstPos;
}
public Octets Update(Octets input)
{
// Add input to legacy buffer
@@ -288,13 +316,19 @@ namespace CSNetwork.Security
break;
}
if (historyPos - (int)offset < 0 || historyPos + (int)length > MPPC_HIST_LEN)
// Perform match copy in the 8 KB circular history buffer.
// Valid offsets are in 1..MPPC_HIST_LEN; offset==0 would be EOB (handled above).
if (offset == 0 || offset > MPPC_HIST_LEN)
{
// Invalid backreference relative to the sliding window; defer until more data
// by restoring bit/read positions to the last safe checkpoint.
bitPos = adjust_bitPos;
readPos = adjust_readPos;
break;
}
LameCopy(historyPos, historyPos - (int)offset, (int)length);
historyPos += (int)length;
if (historyPos >= MPPC_HIST_LEN)
historyPos = 0;
// Circular, overlap-safe copy as required by MPPC (LZ77-style) semantics.
CopyFromHistoryCircular((int)offset, (int)length);
}
// Copy remaining history segment to output