From a7e1c8fd09c16edd9dea383afe66b7aa05d22d9e Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Wed, 3 Jul 2024 23:37:43 +1000 Subject: [PATCH] Enable MA0060 and fix noncompliance (except in Cores) "The value returned by Stream.Read/Stream.ReadAsync is not used" --- .global.editorconfig.ini | 2 +- src/BizHawk.Bizware.Audio/OpenALSoundOutput.cs | 5 ++--- .../XAudio2SoundOutput.cs | 8 +++++--- src/BizHawk.Client.Common/QuickBmpFile.cs | 12 ++++++++---- src/BizHawk.Client.Common/RomGame.cs | 4 +++- .../SharpCompressDearchivalMethod.cs | 4 ++-- .../movie/import/LsmvImport.cs | 4 +++- .../movie/tasproj/StateDictionary.cs | 4 +++- .../savestates/ZipStateLoader.cs | 2 +- .../RetroAchievements.GameVerification.cs | 7 +++++-- src/BizHawk.Common/Util.cs | 3 ++- .../BizHawk.Emulation.Cores.csproj | 2 +- .../DiscFormats/MDS_Format.cs | 18 ++++++++++++------ .../Movie/ZwinderStateManagerTests.cs | 2 +- 14 files changed, 49 insertions(+), 28 deletions(-) diff --git a/.global.editorconfig.ini b/.global.editorconfig.ini index ae0813136f..47961da7c6 100644 --- a/.global.editorconfig.ini +++ b/.global.editorconfig.ini @@ -219,7 +219,7 @@ dotnet_diagnostic.MA0058.severity = error # Class name should end with 'EventArgs' dotnet_diagnostic.MA0059.severity = silent # The value returned by Stream.Read/Stream.ReadAsync is not used -dotnet_diagnostic.MA0060.severity = silent +dotnet_diagnostic.MA0060.severity = error # Method overrides should not change parameter defaults dotnet_diagnostic.MA0061.severity = silent # Non-flags enums should not be marked with "FlagsAttribute" diff --git a/src/BizHawk.Bizware.Audio/OpenALSoundOutput.cs b/src/BizHawk.Bizware.Audio/OpenALSoundOutput.cs index f7d2c11359..9b53deb798 100644 --- a/src/BizHawk.Bizware.Audio/OpenALSoundOutput.cs +++ b/src/BizHawk.Bizware.Audio/OpenALSoundOutput.cs @@ -4,6 +4,7 @@ using System.Linq; using BizHawk.Client.Common; using BizHawk.Common; +using BizHawk.Common.IOExtensions; using Silk.NET.Core.Native; using Silk.NET.OpenAL; @@ -208,9 +209,7 @@ namespace BizHawk.Bizware.Audio _wavSourceID = _al.GenSource(); _wavBufferID = _al.GenBuffer(); - var tempBuffer = new byte[wavStream.Length]; - wavStream.Read(tempBuffer); - + var tempBuffer = wavStream.ReadAllBytes(); if (wavStream.Format == SDL2WavStream.AudioFormat.S16MSB) { EndiannessUtils.MutatingByteSwap16(tempBuffer); diff --git a/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs b/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs index 02fcabfe5a..974571c544 100644 --- a/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs +++ b/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; @@ -178,11 +179,12 @@ namespace BizHawk.Bizware.Audio StopWav(); _wavVoice = _device.CreateSourceVoice(format); _wavBuffer = new(unchecked((int)wavStream.Length)); - - wavStream.Read(_wavBuffer.AsSpan()); + var bufSpan = _wavBuffer.AsSpan(); + var bytesRead = wavStream.Read(bufSpan); + Debug.Assert(bytesRead == bufSpan.Length, "reached end-of-file while reading .wav"); if (wavStream.Format == SDL2WavStream.AudioFormat.S16MSB) { - EndiannessUtils.MutatingByteSwap16(_wavBuffer.AsSpan()); + EndiannessUtils.MutatingByteSwap16(bufSpan); } _wavVoice.SubmitSourceBuffer(_wavBuffer); diff --git a/src/BizHawk.Client.Common/QuickBmpFile.cs b/src/BizHawk.Client.Common/QuickBmpFile.cs index ec2465072c..752e6b1e5d 100644 --- a/src/BizHawk.Client.Common/QuickBmpFile.cs +++ b/src/BizHawk.Client.Common/QuickBmpFile.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; @@ -94,11 +95,13 @@ namespace BizHawk.Client.Common private static unsafe T GetObject(Stream s) { - byte[] tmp = new byte[Marshal.SizeOf(typeof(T))]; - s.Read(tmp, 0, tmp.Length); + var t = typeof(T); + byte[] tmp = new byte[Marshal.SizeOf(t)]; + var bytesRead = s.Read(tmp, offset: 0, count: tmp.Length); + Debug.Assert(bytesRead == tmp.Length, $"reached end-of-file while reading {t.Name}"); fixed (byte* p = tmp) { - return (T)Marshal.PtrToStructure((IntPtr)p, typeof(T)); + return (T) Marshal.PtrToStructure((IntPtr) p, t); } } @@ -247,7 +250,8 @@ namespace BizHawk.Client.Common int inH = bi.biHeight; byte[] src = new byte[inW * inH * 4]; - s.Read(src, 0, src.Length); + var bytesRead = s.Read(src, offset: 0, count: src.Length); + Debug.Assert(bytesRead == src.Length, "reached end-of-file while reading .bmp"); if (v is LoadedBMP) { var l = v as LoadedBMP; diff --git a/src/BizHawk.Client.Common/RomGame.cs b/src/BizHawk.Client.Common/RomGame.cs index 82fdc75fc7..fb9a7d5f6d 100644 --- a/src/BizHawk.Client.Common/RomGame.cs +++ b/src/BizHawk.Client.Common/RomGame.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Globalization; using System.IO; using System.Threading; @@ -93,7 +94,8 @@ namespace BizHawk.Client.Common // read the entire file into FileData. FileData = new byte[fileLength]; stream.Position = 0; - stream.Read(FileData, 0, fileLength); + var bytesRead = stream.Read(FileData, offset: 0, count: fileLength); + Debug.Assert(bytesRead == fileLength, "failed to read whole rom stream"); string SHA1_check = SHA1Checksum.ComputePrefixedHex(FileData); diff --git a/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs b/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs index ad20e98f58..e994751538 100644 --- a/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs +++ b/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs @@ -40,7 +40,7 @@ namespace BizHawk.Client.Common // looking for magic bytes fs.Seek(0x101, SeekOrigin.Begin); var buffer = new byte[8]; - fs.Read(buffer, 0, 8); + _ = fs.Read(buffer, offset: 0, count: buffer.Length); // if stream is too short, the next check will catch it var s = buffer.BytesToHexString(); if (s == "7573746172003030" || s == "7573746172202000") return true; // "ustar\000" (libarchive's bsdtar) or "ustar \0" (GNU Tar) @@ -69,7 +69,7 @@ namespace BizHawk.Client.Common var seekPos = fileStream.Position; fileStream.Seek(0x101, SeekOrigin.Begin); var buffer = new byte[8]; - fileStream.Read(buffer, 0, 8); + _ = fileStream.Read(buffer, offset: 0, count: buffer.Length); // if stream is too short, the next check will catch it fileStream.Seek(seekPos, SeekOrigin.Begin); var s = buffer.BytesToHexString(); if (s == "7573746172003030" || s == "7573746172202000") return true; // "ustar\000" (libarchive's bsdtar) or "ustar \0" (GNU Tar) diff --git a/src/BizHawk.Client.Common/movie/import/LsmvImport.cs b/src/BizHawk.Client.Common/movie/import/LsmvImport.cs index a863a1369a..ade91fcb2b 100644 --- a/src/BizHawk.Client.Common/movie/import/LsmvImport.cs +++ b/src/BizHawk.Client.Common/movie/import/LsmvImport.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; @@ -35,7 +36,8 @@ namespace BizHawk.Client.Common.movie.import using var fs = new FileStream(SourceFile.FullName, FileMode.Open, FileAccess.Read); { byte[] data = new byte[4]; - fs.Read(data, 0, 4); + var bytesRead = fs.Read(data, offset: 0, count: data.Length); + Debug.Assert(bytesRead == data.Length, "reached end-of-file while reading header"); if (!data.SequenceEqual(Zipheader)) { Result.Errors.Add("This is not a zip file."); diff --git a/src/BizHawk.Client.Common/movie/tasproj/StateDictionary.cs b/src/BizHawk.Client.Common/movie/tasproj/StateDictionary.cs index 24f2a9cc73..4c4455d875 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/StateDictionary.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/StateDictionary.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using BizHawk.Common; @@ -15,7 +16,8 @@ namespace BizHawk.Client.Common { byte[] bytes = new byte[_streams[key].Length]; _streams[key].Seek(0, SeekOrigin.Begin); - _streams[key].Read(bytes, 0, bytes.Length); + var bytesRead = _streams[key].Read(bytes, offset: 0, count: bytes.Length); + Debug.Assert(bytesRead == bytes.Length, "reached end-of-file while reading state"); return bytes; } set => SetState(key, new MemoryStream(value)); diff --git a/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs b/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs index ce900ff0a3..06462dfbd8 100644 --- a/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs +++ b/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs @@ -78,7 +78,7 @@ namespace BizHawk.Client.Common using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { byte[] data = new byte[4]; - fs.Read(data, 0, 4); + _ = fs.Read(data, offset: 0, count: data.Length); // if stream is too short, the next check will catch it if (!data.SequenceEqual(Zipheader)) { return null; diff --git a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs index 086948e3d0..21d9afbb97 100644 --- a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs +++ b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -432,7 +433,8 @@ namespace BizHawk.Client.EmuHawk Marshal.Copy(optional_program_id, programIdBytes, 0, 8); var programId = BitConverter.ToUInt64(programIdBytes, 0); - using var seeddb = new BinaryReader(GetFirmware(new("3DS", "seeddb"))); + FirmwareID seeddbFWID = new("3DS", "seeddb"); + using BinaryReader seeddb = new(GetFirmware(seeddbFWID)); var count = seeddb.ReadUInt32(); seeddb.BaseStream.Seek(12, SeekOrigin.Current); // apparently some padding bytes before actual seeds for (long i = 0; i < count; i++) @@ -446,7 +448,8 @@ namespace BizHawk.Client.EmuHawk var sha256Input = new byte[32]; Marshal.Copy(primary_key_y, sha256Input, 0, 16); - seeddb.BaseStream.Read(sha256Input, 16, 16); + var bytesRead = seeddb.BaseStream.Read(sha256Input, offset: 16, count: 16); + Debug.Assert(bytesRead is 16, $"reached end-of-file while reading {seeddbFWID} firmware"); var sha256Digest = SHA256Checksum.Compute(sha256Input); var secondaryKeyYBytes = new byte[17]; diff --git a/src/BizHawk.Common/Util.cs b/src/BizHawk.Common/Util.cs index 788a95afdd..da11ec93a2 100644 --- a/src/BizHawk.Common/Util.cs +++ b/src/BizHawk.Common/Util.cs @@ -55,7 +55,8 @@ namespace BizHawk.Common if (src.Read(tmp, 0, 2) != 2) throw new InvalidOperationException("Unexpected end of stream"); if (tmp[0] != 0x1F || tmp[1] != 0x8B) throw new InvalidOperationException("GZIP header not present"); src.Seek(-4, SeekOrigin.End); - src.Read(tmp, 0, 4); + var bytesRead = src.Read(tmp, offset: 0, count: tmp.Length); + Debug.Assert(bytesRead == tmp.Length); src.Seek(0, SeekOrigin.Begin); using var gs = new GZipStream(src, CompressionMode.Decompress, true); var data = new byte[BitConverter.ToInt32(tmp, 0)]; diff --git a/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 21e5fe692e..67a8196844 100644 --- a/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -5,7 +5,7 @@ true - $(NoWarn);CA1806;CA1825;CA2214;MA0084;MA0090;MA0140;SA1100;SA1120;SA1129;SA1137;SA1205;SA1208;SA1400 + $(NoWarn);CA1806;CA1825;CA2214;MA0060;MA0084;MA0090;MA0140;SA1100;SA1120;SA1129;SA1137;SA1205;SA1208;SA1400 disable diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs index 2ef3bfa416..1926e36ba3 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs @@ -1,6 +1,7 @@ using System.Text; using System.IO; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using BizHawk.Common.PathExtensions; @@ -114,7 +115,7 @@ namespace BizHawk.Emulation.DiscSystem var bc = EndianBitConverter.CreateForLittleEndian(); var header = new byte[88]; - stream.Read(header, 0, 88); + _ = stream.Read(header, offset: 0, count: header.Length); // stream size checked at callsite this.Signature = Encoding.ASCII.GetString(header.Take(16).ToArray()); this.Version = header.Skip(16).Take(2).ToArray(); @@ -338,7 +339,8 @@ namespace BizHawk.Emulation.DiscSystem for (var se = 0; se < aFile.Header.SessionCount; se++) { var sessionHeader = new byte[24]; - stream.Read(sessionHeader, 0, 24); + var bytesRead = stream.Read(sessionHeader, offset: 0, count: sessionHeader.Length); + Debug.Assert(bytesRead == sessionHeader.Length, "reached end-of-file while reading session header"); //sessionHeader.Reverse().ToArray(); var session = new ASession @@ -374,7 +376,8 @@ namespace BizHawk.Emulation.DiscSystem var trackHeader = new byte[80]; var track = new ATrack(); - stream.Read(trackHeader, 0, 80); + var bytesRead = stream.Read(trackHeader, offset: 0, count: trackHeader.Length); + Debug.Assert(bytesRead == trackHeader.Length, "reached end-of-file while reading track header"); track.Mode = trackHeader[0]; track.SubMode = trackHeader[1]; @@ -404,7 +407,8 @@ namespace BizHawk.Emulation.DiscSystem { var extHeader = new byte[8]; stream.Seek(track.ExtraOffset, SeekOrigin.Begin); - stream.Read(extHeader, 0, 8); + var bytesRead1 = stream.Read(extHeader, offset: 0, count: extHeader.Length); + Debug.Assert(bytesRead1 == extHeader.Length, "reached end-of-file while reading extra block of track"); track.ExtraBlock.Pregap = bc.ToInt32(extHeader.Take(4).ToArray()); track.ExtraBlock.Sectors = bc.ToInt32(extHeader.Skip(4).Take(4).ToArray()); stream.Seek(currPos, SeekOrigin.Begin); @@ -425,7 +429,8 @@ namespace BizHawk.Emulation.DiscSystem var foot = new byte[16]; stream.Seek(track.FooterOffset, SeekOrigin.Begin); - stream.Read(foot, 0, 16); + var bytesRead1 = stream.Read(foot, offset: 0, count: foot.Length); + Debug.Assert(bytesRead1 == foot.Length, "reached end-of-file while reading track footer"); var f = new AFooter { @@ -465,7 +470,8 @@ namespace BizHawk.Emulation.DiscSystem // read the filename - stream.Read(fname, 0, fname.Length); + var bytesRead2 = stream.Read(fname, offset: 0, count: fname.Length); + Debug.Assert(bytesRead2 == fname.Length, "reached end-of-file while reading track filename"); // if widechar is 1 filename is stored using 16-bit, otherwise 8-bit is used if (f.WideChar == 1) diff --git a/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs b/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs index 1e971ed15c..2730b89648 100644 --- a/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs +++ b/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs @@ -511,7 +511,7 @@ namespace BizHawk.Tests.Client.Common.Movie Assert.AreEqual(0, state.Frame); Assert.AreEqual(4, state.Size); var bb = new byte[2]; - state.GetReadStream().Read(bb, 0, 2); + _ = state.GetReadStream().Read(bb, offset: 0, count: bb.Length); Assert.AreEqual(1, bb[0]); Assert.AreEqual(2, bb[1]); }