From b6f472ab25207749d30cd6e3b246dad9d8599348 Mon Sep 17 00:00:00 2001 From: morkt Date: Sun, 25 Dec 2016 06:51:33 +0400 Subject: [PATCH] (InputCryptoStream): new class derived from CryptoStream. properly dispose transformations used by CryptoStream. --- ArcFormats/ArcKogado.cs | 2 +- ArcFormats/ArcSPack.cs | 2 +- ArcFormats/CaramelBox/ArcARC3.cs | 2 +- ArcFormats/Crowd/ImageGAX.cs | 4 ++-- ArcFormats/Irrlicht/ArcARK.cs | 2 +- ArcFormats/Musica/ArcPAZ.cs | 6 +++--- ArcFormats/NSystem/ArcFJSYS.cs | 2 +- ArcFormats/Nags/ArcNFS.cs | 2 +- ArcFormats/NitroPlus/ArcNPK.cs | 4 ++-- ArcFormats/Primel/ArcPCF.cs | 2 +- ArcFormats/Selene/ArcKCAP.cs | 2 +- ArcFormats/SimpleEncryption.cs | 24 ++++++++++++++++++++++++ ArcFormats/Slg/ImageTIG.cs | 4 ++-- ArcFormats/Tactics/ArcTactics.cs | 2 +- 14 files changed, 42 insertions(+), 18 deletions(-) diff --git a/ArcFormats/ArcKogado.cs b/ArcFormats/ArcKogado.cs index 1b529155..8eb9e75e 100644 --- a/ArcFormats/ArcKogado.cs +++ b/ArcFormats/ArcKogado.cs @@ -135,7 +135,7 @@ namespace GameRes.Formats.Kogado return input; } if (3 == packed_entry.CompressionType) - return new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read); + return new InputCryptoStream (input, new NotTransform()); try { if (2 == packed_entry.CompressionType) diff --git a/ArcFormats/ArcSPack.cs b/ArcFormats/ArcSPack.cs index 7d759c4d..f5a7e22f 100644 --- a/ArcFormats/ArcSPack.cs +++ b/ArcFormats/ArcSPack.cs @@ -102,7 +102,7 @@ namespace GameRes.Formats.SPack if (null == packed_entry || !packed_entry.IsPacked) return input; if (1 == packed_entry.Method) - return new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read); + return new InputCryptoStream (input, new NotTransform()); if (2 == packed_entry.Method) { using (var reader = new PackedReader (packed_entry, input)) diff --git a/ArcFormats/CaramelBox/ArcARC3.cs b/ArcFormats/CaramelBox/ArcARC3.cs index f62309d4..a378b904 100644 --- a/ArcFormats/CaramelBox/ArcARC3.cs +++ b/ArcFormats/CaramelBox/ArcARC3.cs @@ -193,7 +193,7 @@ namespace GameRes.Formats.CaramelBox return input; if (a3ent.IsEncrypted) { - input = new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read); + input = new InputCryptoStream (input, new NotTransform()); } if (!a3ent.IsPacked) return input; diff --git a/ArcFormats/Crowd/ImageGAX.cs b/ArcFormats/Crowd/ImageGAX.cs index 1d5aa19c..cb08a2e0 100644 --- a/ArcFormats/Crowd/ImageGAX.cs +++ b/ArcFormats/Crowd/ImageGAX.cs @@ -48,7 +48,7 @@ namespace GameRes.Formats.Crowd if (key.Length != stream.Read (key, 0, key.Length)) return null; using (var enc = new InputProxyStream (stream.AsStream, true)) - using (var crypto = new CryptoStream (enc, new GaxTransform (key), CryptoStreamMode.Read)) + using (var crypto = new InputCryptoStream (enc, new GaxTransform (key))) using (var input = new BinaryStream (crypto, stream.Name)) { var info = Png.ReadMetaData (input); @@ -70,7 +70,7 @@ namespace GameRes.Formats.Crowd { var meta = (GaxMetaData)info; using (var enc = new StreamRegion (stream.AsStream, 0x14, true)) - using (var crypto = new CryptoStream (enc, new GaxTransform (meta.Key), CryptoStreamMode.Read)) + using (var crypto = new InputCryptoStream (enc, new GaxTransform (meta.Key))) using (var input = new BinaryStream (crypto, stream.Name)) return Png.Read (input, info); } diff --git a/ArcFormats/Irrlicht/ArcARK.cs b/ArcFormats/Irrlicht/ArcARK.cs index 8a106639..51759c09 100644 --- a/ArcFormats/Irrlicht/ArcARK.cs +++ b/ArcFormats/Irrlicht/ArcARK.cs @@ -74,7 +74,7 @@ namespace GameRes.Formats.Irrlicht public override Stream OpenEntry (ArcFile arc, Entry entry) { var input = arc.File.CreateStream (entry.Offset, entry.Size); - return new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read); + return new InputCryptoStream (input, new NotTransform()); } } } diff --git a/ArcFormats/Musica/ArcPAZ.cs b/ArcFormats/Musica/ArcPAZ.cs index 97fc1338..2e8df409 100644 --- a/ArcFormats/Musica/ArcPAZ.cs +++ b/ArcFormats/Musica/ArcPAZ.cs @@ -158,7 +158,7 @@ namespace GameRes.Formats.Musica { input = new XoredStream (input, xor_key); var enc = new Blowfish (scheme.ArcKeys[arc_name].IndexKey); - input = new CryptoStream (input, enc.CreateDecryptor(), CryptoStreamMode.Read); + input = new InputCryptoStream (input, enc.CreateDecryptor()); using (var index = new ArcView.Reader (input)) { int count = index.ReadInt32(); @@ -291,7 +291,7 @@ namespace GameRes.Formats.Musica Stream DecryptEntry (Stream input, PazArchive arc, PazEntry entry) { - input = new CryptoStream (input, arc.Encryption.CreateDecryptor(), CryptoStreamMode.Read); + input = new InputCryptoStream (input, arc.Encryption.CreateDecryptor()); var key = entry.Key; if (null == key) return input; @@ -305,7 +305,7 @@ namespace GameRes.Formats.Musica rc4.NextByte(); } } - return new CryptoStream (input, rc4, CryptoStreamMode.Read); + return new InputCryptoStream (input, rc4); } PazScheme QueryEncryption (string arc_name, uint signature) diff --git a/ArcFormats/NSystem/ArcFJSYS.cs b/ArcFormats/NSystem/ArcFJSYS.cs index a2e16a1c..446277df 100644 --- a/ArcFormats/NSystem/ArcFJSYS.cs +++ b/ArcFormats/NSystem/ArcFJSYS.cs @@ -104,7 +104,7 @@ namespace GameRes.Formats.NSystem || arc.File.View.AsciiEqual (entry.Offset, "MSCENARIO FILE ")) return base.OpenEntry (arc, entry); var input = arc.File.CreateStream (entry.Offset, entry.Size); - return new CryptoStream (input, new MsdTransform (msarc.Key), CryptoStreamMode.Read); + return new InputCryptoStream (input, new MsdTransform (msarc.Key)); } string QueryPassword (string arc_name) diff --git a/ArcFormats/Nags/ArcNFS.cs b/ArcFormats/Nags/ArcNFS.cs index 70d88d8a..9d928a71 100644 --- a/ArcFormats/Nags/ArcNFS.cs +++ b/ArcFormats/Nags/ArcNFS.cs @@ -83,7 +83,7 @@ namespace GameRes.Formats.Nags var input = arc.File.CreateStream (entry.Offset, entry.Size); if (!entry.Name.EndsWith (".scb", StringComparison.InvariantCultureIgnoreCase)) return input; - return new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read); + return new InputCryptoStream (input, new NotTransform()); } } } diff --git a/ArcFormats/NitroPlus/ArcNPK.cs b/ArcFormats/NitroPlus/ArcNPK.cs index 656e7d8e..90471ee0 100644 --- a/ArcFormats/NitroPlus/ArcNPK.cs +++ b/ArcFormats/NitroPlus/ArcNPK.cs @@ -195,7 +195,7 @@ namespace GameRes.Formats.NitroPlus { var input = narc.File.CreateStream (nent.Segments[0].Offset, nent.Segments[0].AlignedSize); var decryptor = narc.Encryption.CreateDecryptor(); - return new CryptoStream (input, decryptor, CryptoStreamMode.Read); + return new InputCryptoStream (input, decryptor); } return new NpkStream (narc, nent); } @@ -443,7 +443,7 @@ namespace GameRes.Formats.NitroPlus var segment = m_segment.Current; m_stream = m_file.CreateStream (segment.Offset, segment.AlignedSize); var decryptor = m_encryption.CreateDecryptor(); - m_stream = new CryptoStream (m_stream, decryptor, CryptoStreamMode.Read); + m_stream = new InputCryptoStream (m_stream, decryptor); if (segment.IsCompressed) m_stream = new DeflateStream (m_stream, CompressionMode.Decompress); } diff --git a/ArcFormats/Primel/ArcPCF.cs b/ArcFormats/Primel/ArcPCF.cs index edc93b74..5641119e 100644 --- a/ArcFormats/Primel/ArcPCF.cs +++ b/ArcFormats/Primel/ArcPCF.cs @@ -142,7 +142,7 @@ namespace GameRes.Formats.Primel default: // not encrypted return input; } - input = new CryptoStream (input, decryptor, CryptoStreamMode.Read); + input = new InputCryptoStream (input, decryptor); try { if (0 != (flags & 0xFF)) diff --git a/ArcFormats/Selene/ArcKCAP.cs b/ArcFormats/Selene/ArcKCAP.cs index b5c780f4..ad1646bb 100644 --- a/ArcFormats/Selene/ArcKCAP.cs +++ b/ArcFormats/Selene/ArcKCAP.cs @@ -127,7 +127,7 @@ namespace GameRes.Formats.Selene var kpe = entry as KcapEntry; if (null == kpa || null == kpe || !kpe.Encrypted) return input; - return new CryptoStream (input, new KcapTransform(kpa.KeyTable), CryptoStreamMode.Read); + return new InputCryptoStream (input, new KcapTransform(kpa.KeyTable)); } public static string GetPassPhrase (string title) diff --git a/ArcFormats/SimpleEncryption.cs b/ArcFormats/SimpleEncryption.cs index 119018f7..c3665b06 100644 --- a/ArcFormats/SimpleEncryption.cs +++ b/ArcFormats/SimpleEncryption.cs @@ -137,4 +137,28 @@ namespace GameRes.Formats return b; } } + + /// + /// CryptoStream that disposes transformation object upon close. + /// + public class InputCryptoStream : CryptoStream + { + ICryptoTransform m_transform; + + public InputCryptoStream (Stream input, ICryptoTransform transform) + : base (input, transform, CryptoStreamMode.Read) + { + m_transform = transform; + } + + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + if (disposing && m_transform != null) + { + m_transform.Dispose(); + m_transform = null; + } + } + } } diff --git a/ArcFormats/Slg/ImageTIG.cs b/ArcFormats/Slg/ImageTIG.cs index f952830c..2b075f47 100644 --- a/ArcFormats/Slg/ImageTIG.cs +++ b/ArcFormats/Slg/ImageTIG.cs @@ -40,7 +40,7 @@ namespace GameRes.Formats.Slg public override ImageMetaData ReadMetaData (IBinaryStream stream) { using (var proxy = new ProxyStream (stream.AsStream, true)) - using (var crypt = new CryptoStream (proxy, new TigTransform(), CryptoStreamMode.Read)) + using (var crypt = new InputCryptoStream (proxy, new TigTransform())) using (var input = new BinaryStream (crypt, stream.Name)) return base.ReadMetaData (input); } @@ -48,7 +48,7 @@ namespace GameRes.Formats.Slg public override ImageData Read (IBinaryStream stream, ImageMetaData info) { using (var proxy = new ProxyStream (stream.AsStream, true)) - using (var crypt = new CryptoStream (proxy, new TigTransform(), CryptoStreamMode.Read)) + using (var crypt = new InputCryptoStream (proxy, new TigTransform())) using (var input = new BinaryStream (crypt, stream.Name)) return base.Read (input, info); } diff --git a/ArcFormats/Tactics/ArcTactics.cs b/ArcFormats/Tactics/ArcTactics.cs index 3a72a20c..46837e58 100644 --- a/ArcFormats/Tactics/ArcTactics.cs +++ b/ArcFormats/Tactics/ArcTactics.cs @@ -162,7 +162,7 @@ namespace GameRes.Formats.Tactics { // NOTE CryptoStream will close an input stream using (var proxy = new InputProxyStream (input, true)) - using (var xored = new CryptoStream (proxy, new NotTransform(), CryptoStreamMode.Read)) + using (var xored = new InputCryptoStream (proxy, new NotTransform())) using (var lzss = new LzssStream (xored)) if (m_index.Length != lzss.Read (m_index, 0, m_index.Length)) return false;