Пример #1
0
        public void InvalidDll_Throws()
        {
            var path = BaseDir.Combine("test.txt").WriteAllText("this is definitely not a valid dll");

            File.Exists(path).ShouldBeTrue();
            Should.Throw <PeVerifyException>(() => PeVerify.Verify(path));
        }
Пример #2
0
        public void MissingDll_Throws()
        {
            var badPath = GetType().Assembly.Location + ".xyzzy";

            File.Exists(badPath).ShouldBeFalse();
            Should.Throw <PeVerifyException>(() => PeVerify.Verify(badPath));
        }
Пример #3
0
        public void ValidDll_VerifiesClean()
        {
            var dllPath = typeof(TestAttribute).Assembly.Location; // pick nunit, why not

            File.Exists(dllPath).ShouldBeTrue();
            Should.NotThrow(() => PeVerify.Verify(dllPath));
        }
Пример #4
0
        void Write(AssemblyDefinition assemblyToPatch, NPath assemblyToPatchPath, PatchOptions patchOptions = default)
        {
            // atomic write of file with backup
            // TODO: skip backup if existing file already patched. want the .orig to only be the unpatched file.

            // write to tmp and release the lock
            var tmpPath = assemblyToPatchPath.ChangeExtension(".tmp");

            tmpPath.DeleteIfExists();
            assemblyToPatch.Write(tmpPath); // $$$ , new WriterParameters { WriteSymbols = true }); see https://github.com/jbevain/cecil/issues/421
            assemblyToPatch.Dispose();

            // TODO: peverify obviously won't work with memory written streams. also needs all the dependencies.
            // solution is to create a temp folder, write the patched dll there as well as any of its direct dependencies, and run peverify

            if ((patchOptions & PatchOptions.SkipPeVerify) == 0)
            {
                PeVerify.Verify(tmpPath);
            }

            // move the actual file to backup, and move the tmp to actual
            var backupPath = ElevatedWeaver.GetPatchBackupPathFor(assemblyToPatchPath);

            File.Replace(tmpPath, assemblyToPatchPath, backupPath);
        }
        protected NPath Compile(string testAssemblyName, string sourceCode, params string[] dependentAssemblyNames)
        {
            // prefix the assembly name because they are globally unique and don't want to ever collide
            var testAssemblyPath = BaseDir
                                   .Combine($"{TestContext.CurrentContext.GetFixtureName()}_{testAssemblyName}")
                                   .ChangeExtension(".dll");

            // set up to compile

            var compiler     = new Microsoft.CSharp.CSharpCodeProvider();
            var compilerArgs = new CompilerParameters
            {
                OutputAssembly          = testAssemblyPath,
                IncludeDebugInformation = true,
                CompilerOptions         = "/o- /debug+ /warn:0"
            };

            compilerArgs.ReferencedAssemblies.Add(typeof(int).Assembly.Location); // mscorlib

            // TODO: use typecache
            var assemblies = AppDomain.CurrentDomain
                             .GetAssemblies()
                             .Where(a => !a.IsDynamic)
                             .ToDictionary(a => a.GetName().Name, a => a.Location.ToNPath(), StringComparer.OrdinalIgnoreCase);

            foreach (var dependentAssemblyName in dependentAssemblyNames)
            {
                // we may have already copied it in
                var path = BaseDir.Combine(dependentAssemblyName).ChangeExtension(".dll");

                // if not,
                if (!path.Exists() && assemblies.TryGetValue(dependentAssemblyName, out path))
                {
                    path.Copy(BaseDir.Combine(path.FileName));
                }

                compilerArgs.ReferencedAssemblies.Add(path);
            }

            // compile and handle errors

            var compilerResult = compiler.CompileAssemblyFromSource(compilerArgs, sourceCode);

            if (compilerResult.Errors.Count > 0)
            {
                var errorText = compilerResult.Errors
                                .OfType <CompilerError>()
                                .Select(e => $"({e.Line},{e.Column}): error {e.ErrorNumber}: {e.ErrorText}")
                                .Prepend("Compiler errors:")
                                .StringJoin("\n");
                throw new Exception(errorText);
            }

            testAssemblyPath.ShouldBe(new NPath(compilerResult.PathToAssembly));

            PeVerify.Verify(testAssemblyPath); // sanity check on what the compiler generated

            return(testAssemblyPath);
        }