From 757ac4e27ef5654453eda392a2d31792462c3ee6 Mon Sep 17 00:00:00 2001 From: nattthebear Date: Wed, 23 Sep 2020 22:03:37 -0400 Subject: [PATCH] Fix crash saving zwinder state manager when things align a certain way --- .../rewind/ZwinderBuffer.cs | 2 +- .../Movie/ZwinderStateManagerTests.cs | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs b/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs index 0c8629a5a8..3f0a421677 100644 --- a/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs +++ b/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs @@ -256,7 +256,7 @@ namespace BizHawk.Client.Common if (Count != 0) { var startByte = _states[_firstStateIndex].Start; - var endByte = _states[HeadStateIndex].Start + _states[HeadStateIndex].Size; + var endByte = (_states[HeadStateIndex].Start + _states[HeadStateIndex].Size) & _sizeMask; // TODO: Use spans to avoid these extra copies in .net core if (startByte > endByte) { diff --git a/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs b/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs index 8683d2c028..6d6e88282d 100644 --- a/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs +++ b/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs @@ -418,6 +418,30 @@ namespace BizHawk.Tests.Client.Common.Movie Assert.AreEqual(0, zw.AllStates().Single().Frame); } + [TestMethod] + public void WhatIfTheHeadStateWrapsAround() + { + var ss = new StateSource + { + PaddingData = new byte[400 * 1000] + }; + using var zw = new ZwinderBuffer(new RewindConfig + { + BufferSize = 1, + TargetFrameLength = 1 + }); + + // Need to get data in the zwinderbuffer so that the last state, and the last state in particular, wraps around + ss.Frame = 1; + zw.Capture(1, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); + ss.Frame = 2; + zw.Capture(2, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); + ss.Frame = 3; + zw.Capture(3, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); + + zw.SaveStateBinary(new BinaryWriter(new MemoryStream())); + } + private class StateSource : IStatable { public int Frame { get; set; }