diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs index 7b327c9974..b2b7f20450 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs @@ -146,9 +146,16 @@ namespace CSNetwork.Security { if (!PassBits(8)) break; + // Defer if writing this literal would cross the end of the linear window. + // We only wrap at EOB to match the original C++ semantics. + if (historyPos + 1 > MPPC_HIST_LEN) + { + bitPos = adjust_bitPos; + readPos = adjust_readPos; + break; + } history[historyPos++] = (byte)(val >> 24); - if (historyPos == MPPC_HIST_LEN) - historyPos = 0; + // Do not wrap here; wrapping is handled only at EOB. continue; } @@ -156,9 +163,15 @@ namespace CSNetwork.Security { if (!PassBits(9)) break; + // Defer if writing this literal would cross the end of the linear window. + if (historyPos + 1 > MPPC_HIST_LEN) + { + bitPos = adjust_bitPos; + readPos = adjust_readPos; + break; + } history[historyPos++] = (byte)(((val >> 23) | 0x80) & 0xFF); - if (historyPos == MPPC_HIST_LEN) - historyPos = 0; + // Do not wrap here; wrapping is handled only at EOB. continue; } @@ -316,19 +329,19 @@ namespace CSNetwork.Security break; } - // 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) + // Validate match boundaries against the current linear window. Defer if it would cross. + // This mirrors the C++ check: if (histptr - off < history || histptr + len > history + MPPC_HIST_LEN) break; + if (offset == 0 || offset > MPPC_HIST_LEN || historyPos - (int)offset < 0 || historyPos + (int)length > MPPC_HIST_LEN) { - // Invalid backreference relative to the sliding window; defer until more data - // by restoring bit/read positions to the last safe checkpoint. + // Not enough room in the current linear window; rollback and wait for more data. bitPos = adjust_bitPos; readPos = adjust_readPos; break; } - // Circular, overlap-safe copy as required by MPPC (LZ77-style) semantics. - CopyFromHistoryCircular((int)offset, (int)length); + // Linear, overlap-safe copy within current window. No mid-block wrap. + LameCopy(historyPos, historyPos - (int)offset, (int)length); + historyPos += (int)length; } // Copy remaining history segment to output