From 73a780674d8de121800a056446434ba3a3793ac9 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Fri, 22 Jan 2021 06:15:08 +1000 Subject: [PATCH] Add tests for decompressing/extracting archives --- .../SharpCompressArchiveFile.cs | 2 + .../SharpCompressDearchivalMethod.cs | 32 +++++++++++ .../HawkFile/IFileDearchivalMethod.cs | 7 +++ src/BizHawk.Tests/BizHawk.Tests.csproj | 3 + .../dearchive/DearchivalTests.cs | 53 ++++++++++++++++++ src/BizHawk.Tests/EmbeddedData.cs | 17 ++++++ .../data/dearchive/m3_scy_change.7z | Bin 0 -> 1285 bytes .../data/dearchive/m3_scy_change.bsdtar.tar | Bin 0 -> 34304 bytes .../data/dearchive/m3_scy_change.gb | Bin 0 -> 32768 bytes .../data/dearchive/m3_scy_change.gb.gz | Bin 0 -> 1312 bytes .../data/dearchive/m3_scy_change.gnutar.tar | Bin 0 -> 40960 bytes .../data/dearchive/m3_scy_change.rar | Bin 0 -> 1331 bytes .../data/dearchive/m3_scy_change.zip | Bin 0 -> 1399 bytes src/BizHawk.Tests/data/dearchive/readme.md | 2 + 14 files changed, 116 insertions(+) create mode 100644 src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs create mode 100644 src/BizHawk.Tests/EmbeddedData.cs create mode 100644 src/BizHawk.Tests/data/dearchive/m3_scy_change.7z create mode 100644 src/BizHawk.Tests/data/dearchive/m3_scy_change.bsdtar.tar create mode 100644 src/BizHawk.Tests/data/dearchive/m3_scy_change.gb create mode 100644 src/BizHawk.Tests/data/dearchive/m3_scy_change.gb.gz create mode 100644 src/BizHawk.Tests/data/dearchive/m3_scy_change.gnutar.tar create mode 100644 src/BizHawk.Tests/data/dearchive/m3_scy_change.rar create mode 100644 src/BizHawk.Tests/data/dearchive/m3_scy_change.zip create mode 100644 src/BizHawk.Tests/data/dearchive/readme.md diff --git a/src/BizHawk.Client.Common/SharpCompressArchiveFile.cs b/src/BizHawk.Client.Common/SharpCompressArchiveFile.cs index 7cf94c7a6c..3555f50f66 100644 --- a/src/BizHawk.Client.Common/SharpCompressArchiveFile.cs +++ b/src/BizHawk.Client.Common/SharpCompressArchiveFile.cs @@ -24,6 +24,8 @@ namespace BizHawk.Client.Common public SharpCompressArchiveFile(string path) => _archive = ArchiveFactory.Open(path, new()); + public SharpCompressArchiveFile(Stream fileStream) => _archive = ArchiveFactory.Open(fileStream, new()); + public void Dispose() { if (_archive == null) throw new ObjectDisposedException(nameof(SharpCompressArchiveFile)); diff --git a/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs b/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs index d91bd5a7ef..dd4143bf51 100644 --- a/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs +++ b/src/BizHawk.Client.Common/SharpCompressDearchivalMethod.cs @@ -49,8 +49,40 @@ namespace BizHawk.Client.Common return false; } + public bool CheckSignature(Stream fileStream, string? filenameHint) + { + if (!fileStream.CanRead || !fileStream.CanSeek) return false; + + try + { + using var arcTest = ArchiveFactory.Open(fileStream); // should throw for non-archives + if (arcTest.Type != ArchiveType.Tar) return true; // not expecting false positives from anything but .tar for now + } + catch + { + return false; + } + + // as above, SharpCompress seems to overzealously flag files it thinks are the in original .tar format, so we'll check for false positives + + if (fileStream.Length < 512) return false; + // looking for magic bytes + var seekPos = fileStream.Position; + fileStream.Seek(0x101, SeekOrigin.Begin); + var buffer = new byte[8]; + fileStream.Read(buffer, 0, 8); + 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) + + Console.WriteLine($"SharpCompress identified file in stream as original .tar format, probably a false positive, ignoring. Filename hint: {filenameHint}"); + return false; + } + public SharpCompressArchiveFile Construct(string path) => new(path); + public SharpCompressArchiveFile Construct(Stream fileStream) => new(fileStream); + public static readonly SharpCompressDearchivalMethod Instance = new(); public IReadOnlyCollection AllowedArchiveExtensions { get; } = new[] diff --git a/src/BizHawk.Common/HawkFile/IFileDearchivalMethod.cs b/src/BizHawk.Common/HawkFile/IFileDearchivalMethod.cs index ceba27afda..54f2c8df94 100644 --- a/src/BizHawk.Common/HawkFile/IFileDearchivalMethod.cs +++ b/src/BizHawk.Common/HawkFile/IFileDearchivalMethod.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; namespace BizHawk.Common { @@ -8,8 +9,14 @@ namespace BizHawk.Common /// TODO could this receive a itself? possibly handy, in very clever scenarios of mounting fake files bool CheckSignature(string fileName, out int offset, out bool isExecutable); + /// for now, only used in tests + bool CheckSignature(Stream fileStream, string? filenameHint = null); + IReadOnlyCollection AllowedArchiveExtensions { get; } T Construct(string path); + + /// for now, only used in tests + T Construct(Stream fileStream); } } diff --git a/src/BizHawk.Tests/BizHawk.Tests.csproj b/src/BizHawk.Tests/BizHawk.Tests.csproj index c728cd27da..162f96c3e0 100644 --- a/src/BizHawk.Tests/BizHawk.Tests.csproj +++ b/src/BizHawk.Tests/BizHawk.Tests.csproj @@ -14,4 +14,7 @@ + + + diff --git a/src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs b/src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs new file mode 100644 index 0000000000..5201d772b7 --- /dev/null +++ b/src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using System.Linq; + +using BizHawk.Client.Common; +using BizHawk.Common.BufferExtensions; +using BizHawk.Common.IOExtensions; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BizHawk.Tests.Client.Common.Dearchive +{ + [TestClass] + public class DearchivalTests + { + private const string EMBED_GROUP = "dearchive"; + + private static readonly (string Filename, bool HasSharpCompressSupport)[] TestCases = { + ("m3_scy_change.7z", true), + ("m3_scy_change.gb.gz", true), + ("m3_scy_change.rar", true), + ("m3_scy_change.bsdtar.tar", true), + ("m3_scy_change.gnutar.tar", true), + ("m3_scy_change.zip", true), + }; + + private readonly Lazy _rom = new(() => EmbeddedData.GetStream(EMBED_GROUP, "m3_scy_change.gb").ReadAllBytes()); + + private byte[] Rom => _rom.Value; + + [TestMethod] + public void SanityCheck() => Assert.AreEqual("70DCA8E791878BDD32426391E4233EA52B47CDD1", Rom.HashSHA1()); + + [TestMethod] + public void TestSharpCompress() + { + var sc = SharpCompressDearchivalMethod.Instance; + foreach (var filename in TestCases.Where(testCase => testCase.HasSharpCompressSupport) + .Select(testCase => testCase.Filename)) + { + var archive = EmbeddedData.GetStream(EMBED_GROUP, filename); + Assert.IsTrue(sc.CheckSignature(archive, filename), $"{filename} is an archive, but wasn't detected as such"); // puts the seek pos of the Stream param back where it was (in this case at the start), but that may not always be true + var af = sc.Construct(archive); + var items = af.Scan(); + Assert.IsNotNull(items, $"{filename} contains 1 file, but it couldn't be enumerated correctly"); + Assert.AreEqual(1, items!.Count, $"{filename} contains 1 file, but was detected as containing {items.Count} files"); + using MemoryStream ms = new((int) items[0].Size); + af.ExtractFile(items[0].ArchiveIndex, ms); +// Assert.IsTrue(ms.ReadAllBytes().SequenceEqual(Rom), $"the file extracted from {filename} doesn't match the uncompressed file"); //TODO less dumb way of doing this? also it doesn't work + } + } + } +} diff --git a/src/BizHawk.Tests/EmbeddedData.cs b/src/BizHawk.Tests/EmbeddedData.cs new file mode 100644 index 0000000000..dc80be02e0 --- /dev/null +++ b/src/BizHawk.Tests/EmbeddedData.cs @@ -0,0 +1,17 @@ +using System; +using System.IO; +using System.Reflection; + +namespace BizHawk.Tests +{ + public static class EmbeddedData + { + private static readonly Assembly Asm = typeof(EmbeddedData).Assembly; + + public static Stream GetStream(string group, string embedPath) + { + var fullPath = $"BizHawk.Tests.data.{group}.{embedPath}"; + return Asm.GetManifestResourceStream(fullPath) ?? throw new InvalidOperationException($"Could not find the embedded resource {fullPath}"); + } + } +} diff --git a/src/BizHawk.Tests/data/dearchive/m3_scy_change.7z b/src/BizHawk.Tests/data/dearchive/m3_scy_change.7z new file mode 100644 index 0000000000000000000000000000000000000000..e725fa4eb31ca40cccf6c95b0b25276f62d58e0e GIT binary patch literal 1285 zcmV+g1^W6odc3bE8~_BPItJ}~1ONa40001L0000000001IN#vlfByt?T>t=XSqZmw z8SfC&ZQ&u>nqGHdQbLpbkph!Hb8p2=%jI0{eM6p_dj%WiG8sIvS|TeuM>YUgCX@mH zWmVJ92d4!E#%*#4M|ek{4Mb2X)=-O0#{pjjYLnyQRbmRZ`;zWwYrhU7=nwm(rJa4Z z?Z6V-^Y~pYL`gD34Y;z(!6IIADd#VFYuWty=B*0mR0);-DxzI`@?Z8Jsuj_o$VCf)$4DJPOhg%dFbZ54Bdxi}E~@<5xUUGI9@ahtKO-_2$N>wjWi;TMYG?0fjOcTHU zp%aMJN1(M7@L+vZD>IusA70sfUIdTD z(uD5&MPC_R*jRQn-ze+BK3`g_Vt?nz4QaELFRmxl+F^xAcSzn;Pu0-o-QMAq_)ZaG zH+dP%YbveK+ZhVNzPougR5J{n{-&gfr~b8o+avO{q6Hf`HPG^PnFod=i+LdL$)5&x4$AH zn!G{868JabnH&?Km4ppb622tdV-*mfgIsh-1IWTN<=>aI55Z1?bNKC*9br|6s_!{? zhbmVZarrD2;Q6vMl*WBxW+d5XF_>wR54!+mMPU;sQ!smP>tiF)82I$tukpXGFk}yB z%@?zby#Ri-=2hw!Y8`_=0Msr|$iaUE24xOhO%TY``;R0IPo}f`yf?%on`T#p$97<9by1_6X{pN{xPo_GP_^Wo)6`BONSiv@uOu7m zTOa3++9To6>AH9svtJ+EZLA@ispq*c9eG9>tX}ErH|+a97eTb8Cy) zF}GziO6~?X8xGa(llekuzT;pVT8Bj;Up3U1YniQR$;fWc<>-H4XqcW^Jj<0x+yNH0 zL*gEGqL{rE(D&{$#hpnRL*4D9#%=N5XJtOLeG$NU#xQkg`-kmK_5c9{1^@vGgnIx7 z3jqKDAt3<<48Q<@00;^J<1XIm000F683_OY000000000HBLHmxGXP%za{yxic>rGk vV*qFXVE}FbX8>gYE&yi$VgLXD82}Ut0RRA~X`NV#)d3X-0RSL?q=5hczc@(^ literal 0 HcmV?d00001 diff --git a/src/BizHawk.Tests/data/dearchive/m3_scy_change.bsdtar.tar b/src/BizHawk.Tests/data/dearchive/m3_scy_change.bsdtar.tar new file mode 100644 index 0000000000000000000000000000000000000000..3bb70f7bc6da2bea922587bae938834048505087 GIT binary patch literal 34304 zcmeI4UrbYX6vs~i@efi3qj3o-Z3Ae0FhyXnq`4~$T}PZ4wwh%xBDjJXb3mu7S#yiH z7&V5dWE)NVvo{lBMwaZw_@Xw$G+50Z_F$$Rp7T3@KIeCTJlT(Gc7{3+?Ck8`wYTeoja?n|5{Ad)d9}9INghvieVymYJ8P=> z@_3xpHFb5hHEg)a3IpcJmYd-=#yRjoZ5kpL*09x(ayd2C%q~|6{qT% zoB02Jif=Ad1;*bo@Bg`K#>vA!PgNUY>;YX)uJR`r`!#2(QOi$>WP{&DBZZB2XV~p6 zcFq(`yt{tN6)Cj)lNgoHKmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00ck)1VG>g6YzTVpooiuV$xf|ha7wtll&&G2fg01GRGP*#nM4B5bk<o$4sZaeL#)&c2jO?86EwGM@x$-ALB7J zG&p$ot|`~mZQfj2xq5Y1mnjE>fj}_W%)^wcsse!>I|6~qN>dJnDk|J=m#eDEl=Jfo z3i9%7wnFPC7Ah+PfqnY|fwneN-`nf+wYU3xy}hPfU*FW^c9)iRSik16Ze3eje}5Z~ zod4$Lj*iC0{rgS%$$!m$tIl)xi44Oyr4GZi(sePx-By>b6RDMPp5Oe!*CfkA#KbVa zP4Hb1MIy#H%ir^rh(?L#{G0x~-pKCA*04XaHL_dA3y0NHg?bxS@kfnuW00>=gL9Dc zRZO`)+5RanY%hnd>rFDZxe*SB{d}mbSdwPl}_QZCuWYL?X?c ziCp{2zonm2F}WTk$HX5wdyCJY@u#EI;ZXSw8fV2JF)a?se0ANps$|PQ^EoJ{S1eTr z{~u<{Up(h88WmUg`AYNvTd>~ZrM^O0Z%)qfDKC%qiEG)@;##z?yj)hSBFHG5Em0<8 z42gTMzb5V(Lz&EMyyUXZbx%^apF}8n7FTOJ8 ztNxs08>_#nK69^B>&2>P*1sjkxfjm2XNJQTf4VAwV4e47Vk=gxVcE8dz-ra6wMvNQ0A~YgiuL&_Mzs%>4bhB~7 z`8eSsLlgF|-NnvqB1!(SlrOa+^+u{m`!dzS%8@ZQ|6qVPrMbb@^pg}-%X5@RW$ zc~Zm^-d;(GdIW(Rh73_v(;LxY3&?m6<-t=qRZH?Lj0f4?KgVv$HJ*1^M(TUsKKJ$oXN=4MAu zB$}Fn!9bv;#gQv3tEwt0Jf3RzUo12?MbXb;U^1*ta&)8!3h{@8a;z*&OYy?n%k{y3!|eLYl>Mbr@+v=HO?}1|tao|ouTa%nmdkt^8&iGqdg+|Jp6Y9C zR2Az8Dhg*yR4j@idH>BfTzy*ED7}t8DhAm?XHb^Kg~Dlvx46c-GiWAw0n##YW-<`yDZb*<>=l0T-UDFLwV@D z*`NO2)QWe%C1sEPbFUX^|C333M=H_yN-AORNG9j^gZcf+FnD*nSsW2Jc|{mRyk4_% zSbdq#AB7Ha+W#aQAYn-FH^EweDVrm6JRi=l%DE06mT=w~# z@D>C>00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1pZ3`e*^jRh<^Y8 literal 0 HcmV?d00001 diff --git a/src/BizHawk.Tests/data/dearchive/m3_scy_change.gb.gz b/src/BizHawk.Tests/data/dearchive/m3_scy_change.gb.gz new file mode 100644 index 0000000000000000000000000000000000000000..b4ee534c0b3035f31d8aaa9b9f44212382eb7aab GIT binary patch literal 1312 zcmZ|Oi$Bu|003~8Pw(rfWI{TL70si zuwF|Mag`gwaw)H9w(mtsNbO>QEzndgKHe=(UTX|h`8x*}fl-B@1D)$@(NIF3bZx<0 z6NN;cOWs_s)c2K=WhGpOX?OZO8ZBu<25h*j8Ba|W%=+Ndpq-~V1ROe?kRKb-3o~UW z;)u!Qim}dXPTa;AVeE~LUWse(nC9j+;uGS8Scr&e$c97ldKsWcFy+0=uGtE2ajOPVlHYAJX2_kMfyZ%J^EpR;g?ta2RZg~HLwh+Tt4L|S6^R%8U z@*=|br*)N{=(s=o+o9_u2<_I@(M6kcVHbW6IqMjxEzL2|`+rN1wr@jHSsEXiiWlVW%wTp4YaGALPZ`XbRA?}qMDl7`x1S;ggzBAc0(ye^3AV+hOh90}e zccd16dPA>5z`)vR{4+V(ZFOFA__i+fo4dtfgQhE_LXrBs9WWBz9-Sx#sd3LlVotHI zAd(ozaxa;7?OPR0Gis&J8#CwyI0d!6(o!;j0XZyFr)m%X_-(euopQ|D~-j{27 zS|5yLti*mIwMH-#L-U>D78#FKkm?yY2XSf$71Im_BI_vz6aYjKZbgE<_$}!$hp|IB zBNKG+1~XKEneLfiXL(7QMtFmstA1Nq)f=jnNnNpeaa4Ub&Bwb;V?9*{nFkTwDf8pl z@chd~fKg5ng6$5O;IiKrFh&a?ZD83;CaGUSW>&)j$|S5AaJd83NYu2uHDVk&?-|DP zHF!$A!QF%fu)kiDs|+>7z3hqS>(+NRb)q?p$xK5ubMj&IJ86u`6&VY!E47g&rR=p* zHGJ7$I_PROL-Eknz*j8spS5SFtZJ}pYg_RcCwlc#s{NC?kKK#}F;9@3`;LayP4kMg z{UFVdkUDGY!PoZHUfYs@Qmqs7m2!2Mb-GW63=B;HIQlYuB~6M1kD% T|NZ{@qybIY%l_8O(9`=5Q?#EO literal 0 HcmV?d00001 diff --git a/src/BizHawk.Tests/data/dearchive/m3_scy_change.gnutar.tar b/src/BizHawk.Tests/data/dearchive/m3_scy_change.gnutar.tar new file mode 100644 index 0000000000000000000000000000000000000000..79929e79d079350eb5f7aca4fea1baafa3153812 GIT binary patch literal 40960 zcmeI)UuaWT90%}U+FJkArnaIuC}|SfDn3a6*tLUjmv+@<#aZbV8GEs|F0HI{Z8KeD z;ilFhDpJ(4tpT-r6N;=1_9DKhVU|qZw9YNg+vSGG9nA&j9e&^hqR;OhQ6gu`j zH}U4&bMEi_&gY!mKADedcLh5S?&|E`y|3$oOzXt->3#lMCNQY@971FZevZKeye*5~qU+>(x6}@z+t8<_Ix9fLq zM@KJRtko8rhMy{(vqgR{Ii5eVQ}bsO2U_qQU2)k^DxxGvxLZI%o4H-`z0n z3g_E>iA_FjIO)~yC*O2630sbBcERXqfB*y_u*d{rr)`hvvd36)wKd<%Prh5J=JQU@ zas1QXzW!i;U+>?~KNO#~{aBordutW(_^O7-aep8d%Ib0X&D>)hD%F}SwGHYXlQWo?p?E9SGQ$LMa7ym zU0r595b*m0fo3jdy|U8p-?`K8uc$EV!C-m0+wF2yR+{zP+`PP;9GflQ`iX^#3cr8< ze!su1&1~=O^?KXez24qlvtD1{)Z})Tlyq3X=COW#TU&pB8<%YS=H`x$#>N8&%=(l6 zn(M7ro>!m9FpSgcFw9=ME+%=k)mztz)Xq51SAOC56xW4_iebJQ=d&ORhm8rYf6woD zBtkSF-;C$+g!hEEg?!;{;XQJ^P)L0$S64%7{4ry~807bu!8yqL)tGXBa{s5IaDQ2J zU2l@P&6iLp5~!(v7pmig+saaGl=`0R5?%oHtG2mc>tD_$%cFA@<~ z`16&>LGHormY4b#%K2vNS)a19NT0ZtIU}w``pU}WjMWHo6wa0?oi>KVz1Lq8_l%)* zdTzX#NT;UB8Cv5Hi%}j^t&bkio5W9izgj=T;JHN2w>cm7igIsjK302F_L1#s^igAw zd#DVub>m#>r0H#3<+fAYUyaA@@?JTb8c(fVz*8=>Q2R^Hgx5NAKl6Deligp&5#CR# ze=5as`N)p<=#eqBXd{(OcV$EkRzEzL$Z20M^@;S>H%KTJ()y_{=IqJiQR=zSfHn95hla|}%Ggjr# zk@_7adcWzDN~K3KCyWWbL#vVdPx);R`Sk5(yY)O*bC>%eTU6d0PkrCyj<>!`vOm_J z*Lsnze>kjfjRebHi3Ihn;qct^VD5RPY5a7%ksdK_@Q%=kc)!NQu>58|zoeRtlg`I+ z7a5wcf9)=GX5tC*jVHayqU0ONChf~)3pb98yZIMuX5+Pfs(S3DaI%zFQP^1eR1S+;i$y6$WMMQ`orBa2cx*))+lxsysS3(k^iqJ_kp#q{% zK@rf{B(Q08#)S*;3-KvzwwK^rA#Io8y+zyYsT)w&HlJgt96)`pYHO;HOnd#psnWd@u~hAJc=s+ zb<>RaZ!&4Kn(A`=ZMj#!TMby&FmhR2{vj;wF8R`8Rc$76{cudIbIG+~EiY54HE+66 zo@OPLm-hNUXa`!Mf@;H*)|vbmo_ki&S)EIEgvla+;fq4BU$t5zwp>5XI6@~ec>QzO z3yQWP8@b^L<010x@Wcw!#ixOov+;2Ulgq^qY|7nU{(Noj>UaDrTRZ+0t(=Y#NAVi! zn6_SoZPAd7jl_&?OGQSfqKznMHki;KB(|5w-!Yal1VlUSgh2=-j1}Dp z=y{;=f)5v@nlUhjv)~ULA3>n;nzMx6TrSPb-14roGjb_D3ig4un_G2TReo2Mb$P!a zx;!guaH5aj{PZ3cSY7-}{7JKB-=B)sXnhbKXd)qw%PHATR4N;?CZRLyfqm>$C&E!q zfqt!)seoaGY&^aMt+dwgQP9U_j*|1NgIg_i&71T6S313bDH&v=R70`WRFD$TTJf4Q zh@$L-UE*y~?E;h8rjx8q>owqpJUmFgGnz literal 0 HcmV?d00001 diff --git a/src/BizHawk.Tests/data/dearchive/m3_scy_change.zip b/src/BizHawk.Tests/data/dearchive/m3_scy_change.zip new file mode 100644 index 0000000000000000000000000000000000000000..5f99374b8295bb31c06f492c03b375ae1a3dccce GIT binary patch literal 1399 zcmZ{kZ9EeQ9LLuoS4UmtDT!;N6L(uK-I8YIA(v-`jj)iUnH`d+JVl3j3MuAcny1P! z+_sL{xw_OjcyVv;bNzlVe*gdf^ZCE|z4$uW%E_w$z5sj)(5ON> za={$FSRMcXBme+k?*!%yD$Fkm<#*dBIKUqq;42zK-M)s0WNd`Mn*(-RAkT$Q<&eh;}fPa-0aPqy(Waia5zY!z6kt4g{c-(cGr8RsA(8 zDT&tQX)6y{BnFkucrjGF=Y*k;ZH`JYM>2zD3yHj9a1| zv#P5F1F=V)(I%{{{Y0t_v26X+KGKPi)+e*la7&ih(z+&X>R9TECh-!K#rGgOJO62U z{MJs@pOtrTV!}~wU|cR!5&zcb5W);nTERem^Zxw@_8WD}ySb1^s+w<*ZAmG+jdwL;d|wbHq~|b3X`VVR2CVdE`(XECyc$#hQg$ zwlyGi52rtrSA9jc1S%f93}i429CY#ctvCXy(yEQeQ&si%2P5*O5H)-eD2Lk)$|==W zZRfteVXUe2j%&c7)5`x^AdwbCuAitF7)(wM26K>E0#yVe3>F?TMfiy7jmc}-o2ubA z!+Y)09Ju6eG_+)F4{Z7YoW87%W~3G@tLUgZo|)=OQ%Yi_uE&Jj%I(bOnTn65WYVLD zhtXQpQhsv_I@dAWeOsl-$6~6uapVRaA}ogFH+bUa$*j5h5jUbR8mR>w=d$kM=|NSI zb*FQf-LeXa1{~y3MCBMMfo={gkXa6>N8zES4xiw~TdV6z4RDxPJ3Av~SkJ6ST~a^b z-FFk}A2g%R4ax>qQAQCB7xM;iyibS2 zyzaYfwIJ^fs+;P0e78KaO!N#nCx*p#L2&FXbM3L-_{$ZUCcN&|>QeOf&o5%{Z46KJ zNf3fq6L=nwIfaw;J{?RSC-mbaZfkBNmkp~BWUXOkHLtWNdg-Q>Y&bN^w_24S*1K^; zPdQS+*mKrQa^Hs-nZ+oek2s*Eohz}?!(-Kdi=-DS-7M06GoN1jzT%IVURkzed%L&Q zr=XJP$=^&hYgdZ^cG86;(c*8?`E z8D-5Z&!*ta#*)dPSNhcJ%P&WJQV5b7aSf*}L%-Z(d+>UP-OTS)koDBV2y(ZpZ!d;XX65m4Uk+N15^Es7Dvc0>+`+p^Db5KsUd%l3neIAnkepV#zPX9%w TldZzu-TR&$o9!e>VR!one7Uy4 literal 0 HcmV?d00001 diff --git a/src/BizHawk.Tests/data/dearchive/readme.md b/src/BizHawk.Tests/data/dearchive/readme.md new file mode 100644 index 0000000000..e5195a53c8 --- /dev/null +++ b/src/BizHawk.Tests/data/dearchive/readme.md @@ -0,0 +1,2 @@ +All files in this dir are derived from `m3_scy_change.gb`, which is an open source test rom from the [Mealybug Tearoom Tests](https://github.com/mattcurrie/mealybug-tearoom-tests) (specifically, it's the copy from [this bundle](https://github.com/mattcurrie/mealybug-tearoom-tests/blob/bc3430a7c1f5d394764f37a189b85d8ce4bb3c4e/mealybug-tearoom-tests.zip)). +The test suite is made available under the MIT (Expat) license, and the full terms of the license can be found [here](https://github.com/mattcurrie/mealybug-tearoom-tests/blob/bc3430a7c1f5d394764f37a189b85d8ce4bb3c4e/LICENSE).