public static void PrintDocuments(CommandLineApplication command) { command.Description = "print the documents stored in the pdb or dll"; var pdbArgument = command.Argument("path", "set path to pdb or dll", false); command.HelpOption("-h|--help"); command.OnExecute(() => { var path = pdbArgument.Value; if (path == null) { command.ShowHelp(); return(2); } if (!File.Exists(path)) { Console.WriteLine("file does not exist: " + path); return(3); } using (var drp = new DebugReaderProvider(path)) { foreach (var doc in GetDocuments(drp)) { Console.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); } } return(0); }); }
public static void PrintUrls(CommandLineApplication command) { command.Description = "print the URLs for each document based on the Source Link JSON"; var pdbArgument = command.Argument("path", "set path to pdb or dll", false); command.HelpOption("-h|--help"); command.OnExecute(() => { var path = pdbArgument.Value; if (path == null) { command.ShowHelp(); return(2); } if (!File.Exists(path)) { Console.Error.WriteLine("file does not exist: " + path); return(3); } using (var drp = DebugReaderProvider.Create(path)) { if (drp == null) { Console.Error.WriteLine("unable to read debug info: " + path); return(5); } var missingDocs = new List <Document>(); foreach (var doc in GetDocumentsWithUrls(drp)) { if (doc.IsEmbedded) { Console.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); Console.WriteLine("embedded"); } else if (doc.Url != null) { Console.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); Console.WriteLine(doc.Url); } else { missingDocs.Add(doc); } } if (missingDocs.Count > 0) { Console.Error.WriteLine("" + missingDocs.Count + " Documents without URLs:"); foreach (var doc in missingDocs) { Console.Error.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); } return(4); } } return(0); }); }
public static int TestFile(string path, IAuthenticationHeaderValueProvider authenticationHeaderValueProvider = null) { using (var drp = new DebugReaderProvider(path)) { return(TestFile(drp, authenticationHeaderValueProvider)); } }
public static void PrintJson(CommandLineApplication command) { command.Description = "print the Source Link JSON stored in the pdb or dll"; var pdbArgument = command.Argument("path", "set path to pdb or dll", false); command.HelpOption("-h|--help"); command.OnExecute(() => { var path = pdbArgument.Value; if (path == null) { command.ShowHelp(); return(2); } if (!File.Exists(path)) { Console.WriteLine("file does not exist: " + path); return(3); } using (var drp = new DebugReaderProvider(path)) { var bytes = GetSourceLinkBytes(drp); if (bytes == null || bytes.Length == 0) { Console.WriteLine("Source Link JSON not found in file: " + path); return(4); } Console.WriteLine(Encoding.UTF8.GetString(bytes)); } return(0); }); }
static async Task <IEnumerable <Document> > GetDocumentsWithUrlHashes(DebugReaderProvider drp) { // https://github.com/ctaggart/SourceLink/blob/v1/Exe/Http.fs // https://github.com/ctaggart/SourceLink/blob/v1/Exe/Checksums.fs var handler = new HttpClientHandler(); if (handler.SupportsAutomaticDecompression) { handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; } using (var hc = new HttpClient(handler)) { hc.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("SourceLink", "2.0.0")); // TODO Basic Auth support, ASCII or UTF8 //hc.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue("Basic", // Convert.ToBase64String(Encoding.ASCII.GetBytes("username:password"))); var tasks = GetDocumentsWithUrls(drp) .Select(doc => CheckDocumentHash(hc, doc)) .ToArray(); await Task.WhenAll(tasks); return(tasks.Select(x => x.Result)); } }
public static DebugReaderProvider Create(string path, Stream stream) { var drp = new DebugReaderProvider(); drp.Path = path; drp.stream = stream; if (path.EndsWith(".dll")) { var reader = new PEReader(stream); if (!reader.HasMetadata) { return(null); } // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/tests/PortableExecutable/PEReaderTests.cs var debugDirectoryEntries = reader.ReadDebugDirectory(); var embeddedPdb = debugDirectoryEntries.Where(dde => dde.Type == DebugDirectoryEntryType.EmbeddedPortablePdb).FirstOrDefault(); if (embeddedPdb.Equals(default(DebugDirectoryEntry))) { return(null); } drp.provider = reader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdb); } else { drp.provider = MetadataReaderProvider.FromPortablePdbStream(stream); } return(drp); }
public static IEnumerable <Document> GetDocuments(DebugReaderProvider drp) { var mr = drp.GetMetaDataReader(); foreach (var dh in mr.Documents) { if (dh.IsNil) { continue; } var d = mr.GetDocument(dh); if (d.Name.IsNil || d.Language.IsNil || d.HashAlgorithm.IsNil || d.Hash.IsNil) { continue; } yield return(new Document { Name = mr.GetString(d.Name), Language = mr.GetGuid(d.Language), HashAlgorithm = mr.GetGuid(d.HashAlgorithm), Hash = mr.GetBlobBytes(d.Hash), IsEmbedded = IsEmbedded(mr, dh) }); } }
public static int TestFile(string path) { using (var drp = new DebugReaderProvider(path)) { return(TestFile(drp)); } }
public static int TestFile(DebugReaderProvider drp, IAuthenticationHeaderValueProvider authenticationHeaderValueProvider = null) { var missingDocs = new List <Document>(); var erroredDocs = new List <Document>(); var documents = GetDocumentsWithUrlHashes(drp, authenticationHeaderValueProvider).GetAwaiter().GetResult(); foreach (var doc in documents) { if (doc.IsEmbedded) { //Console.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); //Console.WriteLine("embedded"); } else if (doc.Url != null) { if (doc.Error == null) { //Console.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); //Console.WriteLine(doc.Url); } else { erroredDocs.Add(doc); } } else { missingDocs.Add(doc); } } if (missingDocs.Count > 0) { Console.WriteLine("" + missingDocs.Count + " Documents without URLs:"); foreach (var doc in missingDocs) { Console.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); } } if (erroredDocs.Count > 0) { Console.WriteLine("" + erroredDocs.Count + " Documents with errors:"); foreach (var doc in erroredDocs) { Console.WriteLine("{0} {1} {2} {3}", doc.Hash.ToHex(), HashAlgorithmGuids.GetName(doc.HashAlgorithm), LanguageGuids.GetName(doc.Language), doc.Name); Console.WriteLine(doc.Url); Console.WriteLine("error: " + doc.Error); } } if (missingDocs.Count > 0 || erroredDocs.Count > 0) { Console.WriteLine("sourcelink test failed"); return(4); } Console.WriteLine("sourcelink test passed: " + drp.Path); return(0); }
public static int TestFile(string path, IAuthenticationHeaderValueProvider authenticationHeaderValueProvider = null) { using (var drp = DebugReaderProvider.Create(path)) { if (drp == null) { Console.Error.WriteLine("unable to read debug info: " + path); return(5); } return(TestFile(drp, authenticationHeaderValueProvider)); } }
public static IEnumerable <Document> GetDocumentsWithUrls(DebugReaderProvider drp) { var bytes = GetSourceLinkBytes(drp); if (bytes != null) { var text = Encoding.UTF8.GetString(bytes); var json = JsonConvert.DeserializeObject <SourceLinkJson>(text); foreach (var doc in GetDocuments(drp)) { if (!doc.IsEmbedded) { doc.Url = GetUrl(doc.Name, json); } yield return(doc); } } }
public static byte[] GetSourceLinkBytes(DebugReaderProvider drp) { var mr = drp.GetMetaDataReader(); if (mr == null) { return(null); } var blobh = default(BlobHandle); foreach (var cdih in mr.GetCustomDebugInformation(EntityHandle.ModuleDefinition)) { var cdi = mr.GetCustomDebugInformation(cdih); if (mr.GetGuid(cdi.Kind) == SourceLinkId) { blobh = cdi.Value; } } if (blobh.IsNil) { return(Array.Empty <byte>()); } return(mr.GetBlobBytes(blobh)); }
public static int TestNupkg(string path, List <string> files, IAuthenticationHeaderValueProvider authenticationHeaderValueProvider = null) { var errors = 0; using (var p = new PackageArchiveReader(File.OpenRead(path))) { var dlls = new List <string>(); var pdbs = new HashSet <string>(); foreach (var f in p.GetFiles()) { switch (Path.GetExtension(f)) { case ".dll": dlls.Add(f); break; case ".pdb": pdbs.Add(f); break; } } if (files.Count == 0) { foreach (var dll in dlls) { var pdb = Path.ChangeExtension(dll, ".pdb"); if (pdbs.Contains(pdb)) { files.Add(pdb); } else if (!IsSatelliteAssembly(dll, dlls)) { files.Add(dll); } } } foreach (var file in files) { try { using (var stream = p.GetStream(file)) using (var ms = new MemoryStream()) // seek required { stream.CopyTo(ms); ms.Position = 0; using (var drp = DebugReaderProvider.Create(file, ms)) { if (drp == null) { Console.Error.WriteLine("unable to read debug info: " + path); return(5); } if (TestFile(drp, authenticationHeaderValueProvider) != 0) { Console.WriteLine("failed for " + file); errors++; } } } } catch (FileNotFoundException) { Console.WriteLine("file not found: " + file); errors++; } } } return(errors); }
public static int TestNupkg(string path, List <string> files) { var errors = 0; using (var p = new PackageArchiveReader(File.OpenRead(path))) { var dlls = new List <string>(); var pdbs = new HashSet <string>(); foreach (var f in p.GetFiles()) { switch (Path.GetExtension(f)) { case ".dll": dlls.Add(f); break; case ".pdb": pdbs.Add(f); break; } } if (files.Count == 0) { foreach (var dll in dlls) { var pdb = Path.ChangeExtension(dll, ".pdb"); if (pdbs.Contains(pdb)) { files.Add(pdb); } else { files.Add(dll); } } } foreach (var file in files) { try { var ext = Path.GetExtension(file); if (ext == ".pdb") { using (var drp = new DebugReaderProvider(file, p.GetStream(file))) { if (TestFile(drp) != 0) { Console.WriteLine("failed for " + file); errors++; } } } else { using (var stream = p.GetStream(file)) using (var ms = new MemoryStream()) // PEReader requires seek { stream.CopyTo(ms); ms.Position = 0; using (var drp = new DebugReaderProvider(file, ms)) { if (TestFile(drp) != 0) { Console.WriteLine("failed for " + file); errors++; } } } } } catch (FileNotFoundException) { Console.WriteLine("file not found: " + file); errors++; } } } return(errors); }