internal static string GetFileLocationPath(ArtifactLocation artifactLocation, int runId) { string path = null; if (artifactLocation?.Uri != null) { RunDataCache dataCache = CodeAnalysisResultManager.Instance.RunIndexToRunDataCache[runId]; Uri uri = artifactLocation.Uri; // try to resolve path using OriginalUriBasePaths string uriBaseId = artifactLocation.UriBaseId; if (!string.IsNullOrEmpty(uriBaseId) && dataCache.OriginalUriBasePaths.ContainsKey(uriBaseId)) { Uri baseUri = dataCache.OriginalUriBasePaths[uriBaseId]; uri = new Uri(baseUri, uri); } try { path = uri.LocalPath; } catch (InvalidOperationException) { // if cannot resolve local path return original uri string // it will try to resolve the path when user navigates to the error list item path = uri.ToPath(); } } return(path); }
internal bool TryResolveFilePathFromRemappings(string pathFromLogFile, RunDataCache dataCache, out string resolvedPath) { resolvedPath = null; // Traverse our remappings and see if we can // make rebaseline from existing data pathFromLogFile = NormalizeFilePath(pathFromLogFile); foreach (Tuple <string, string> remapping in dataCache.RemappedPathPrefixes) { string remapped; if (!string.IsNullOrEmpty(remapping.Item1)) { remapped = pathFromLogFile.Replace(remapping.Item1, remapping.Item2); } else { remapped = Path.Combine(remapping.Item2, pathFromLogFile); } if (this._fileSystem.FileExists(remapped)) { resolvedPath = remapped; return(true); } } return(false); }
internal static string GetFileLocationPath(ArtifactLocation artifactLocation, int runId) { string path = null; if (artifactLocation?.Uri != null) { RunDataCache dataCache = CodeAnalysisResultManager.Instance.RunDataCaches[runId]; Uri uri = artifactLocation.Uri; string uriBaseId = artifactLocation.UriBaseId; if (!string.IsNullOrEmpty(uriBaseId) && dataCache.OriginalUriBasePaths.ContainsKey(uriBaseId)) { Uri baseUri = dataCache.OriginalUriBasePaths[uriBaseId]; uri = new Uri(baseUri, uri); } path = uri.LocalPath; } return(path); }
// Internal rather than private for unit testability. internal string GetRebaselinedFileName(SarifErrorListItem sarifErrorListItem, string uriBaseId, string pathFromLogFile, RunDataCache dataCache, string solutionFullPath = null) { string originalPath = pathFromLogFile; Uri relativeUri = null; if (!string.IsNullOrEmpty(uriBaseId) && Uri.TryCreate(pathFromLogFile, UriKind.Relative, out relativeUri)) { // If the relative file path is relative to an unknown root, // we need to strip the leading slash, so that we can relate // the file path to an arbitrary remapped disk location. if (pathFromLogFile.StartsWith("/")) { pathFromLogFile = pathFromLogFile.Substring(1); } if (dataCache.RemappedUriBasePaths.ContainsKey(uriBaseId)) { pathFromLogFile = new Uri(dataCache.RemappedUriBasePaths[uriBaseId], pathFromLogFile).LocalPath; } else if (dataCache.OriginalUriBasePaths.ContainsKey(uriBaseId)) { pathFromLogFile = new Uri(dataCache.OriginalUriBasePaths[uriBaseId], pathFromLogFile).LocalPath; } if (this._fileSystem.FileExists(pathFromLogFile)) { return(pathFromLogFile); } } // Traverse our remappings and see if we can // make rebaseline from existing data foreach (Tuple <string, string> remapping in dataCache.RemappedPathPrefixes) { string remapped; if (!string.IsNullOrEmpty(remapping.Item1)) { remapped = pathFromLogFile.Replace(remapping.Item1, remapping.Item2); } else { remapped = Path.Combine(remapping.Item2, pathFromLogFile); } if (this._fileSystem.FileExists(remapped)) { return(remapped); } } string resolvedPath = null; if (!string.IsNullOrEmpty(solutionFullPath)) { this.TryResolveFilePathFromSolution(solutionFullPath, originalPath, this._fileSystem, out resolvedPath); } if (resolvedPath == null) { resolvedPath = this._promptForResolvedPathDelegate(sarifErrorListItem, pathFromLogFile); } if (resolvedPath == null) { return(pathFromLogFile); } string fullPathFromLogFile = pathFromLogFile; if (Uri.TryCreate(pathFromLogFile, UriKind.Absolute, out Uri absoluteUri)) { fullPathFromLogFile = Path.GetFullPath(pathFromLogFile); } else { if (!fullPathFromLogFile.StartsWith("/")) { fullPathFromLogFile = "/" + fullPathFromLogFile; } } string commonSuffix = GetCommonSuffix(fullPathFromLogFile.Replace("/", @"\"), resolvedPath); if (commonSuffix == null) { return(pathFromLogFile); } // Trim the common suffix from both paths, and add a remapping that converts // one prefix to the other. string originalPrefix = fullPathFromLogFile.Substring(0, fullPathFromLogFile.Length - commonSuffix.Length); string resolvedPrefix = resolvedPath.Substring(0, resolvedPath.Length - commonSuffix.Length); int uriBaseIdEndIndex = resolvedPath.IndexOf(originalPath.Replace("/", @"\")); if (relativeUri != null && uriBaseIdEndIndex >= 0) { // If we could determine the uriBaseId substitution value, then add it to the map. dataCache.RemappedUriBasePaths[uriBaseId] = new Uri(resolvedPath.Substring(0, uriBaseIdEndIndex), UriKind.Absolute); } else { // If there's no relativeUri/uriBaseId pair or we couldn't determine the uriBaseId value, // map the original prefix to the new prefix. dataCache.RemappedPathPrefixes.Add(new Tuple <string, string>(originalPrefix, resolvedPrefix)); } return(resolvedPath); }
public bool TryRebaselineAllSarifErrors(int runId, string uriBaseId, string originalFilename) { if (CurrentSarifResult == null) { return(false); } RunDataCache dataCache = RunDataCaches[runId]; string rebaselinedFileName = null; if (dataCache.FileDetails.ContainsKey(originalFilename)) { // File contents embedded in SARIF. rebaselinedFileName = CreateFileFromContents(dataCache.FileDetails, originalFilename); } else { if (uriBaseId != null && dataCache.OriginalUriBasePaths.TryGetValue(uriBaseId, out Uri baseUri) && Uri.TryCreate(baseUri, originalFilename, out Uri uri) && uri.IsHttpScheme()) { bool allow = _allowedDownloadHosts.Contains(uri.Host); // File needs to be downloaded, prompt for confirmation if host is not already allowed if (!allow) { MessageDialogCommand result = MessageDialog.Show(Resources.ConfirmDownloadDialog_Title, string.Format(Resources.ConfirmDownloadDialog_Message, uri), MessageDialogCommandSet.YesNo, string.Format(Resources.ConfirmDownloadDialog_CheckboxLabel, uri.Host), out bool alwaysAllow); if (result != MessageDialogCommand.No) { allow = true; if (alwaysAllow) { AddAllowedDownloadHost(uri.Host); } } } if (allow) { try { rebaselinedFileName = DownloadFile(uri.ToString()); } catch (WebException wex) { VsShellUtilities.ShowMessageBox(SarifViewerPackage.ServiceProvider, Resources.DownloadFail_DialogMessage + Environment.NewLine + wex.Message, null, // title OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); return(false); } } } else { // User needs to locate file. rebaselinedFileName = GetRebaselinedFileName(uriBaseId, originalFilename, dataCache); } if (String.IsNullOrEmpty(rebaselinedFileName) || originalFilename.Equals(rebaselinedFileName, StringComparison.OrdinalIgnoreCase)) { return(false); } } // Update all the paths in this run RemapFileNames(dataCache.SarifErrors, originalFilename, rebaselinedFileName); return(true); }
internal bool SaveResolvedPathToUriBaseMapping(string uriBaseId, string originalPath, string pathFromLogFile, string resolvedPath, RunDataCache dataCache) { Uri.TryCreate(pathFromLogFile, UriKind.Relative, out Uri relativeUri); if (Uri.TryCreate(pathFromLogFile, UriKind.Absolute, out Uri absoluteUri)) { if (absoluteUri.IsHttpScheme()) { // since result's path is full url path, it has no common part of local files return(true); } } else { // if path is relative path, add '/' at beginning if (!pathFromLogFile.StartsWith("/")) { pathFromLogFile = "/" + pathFromLogFile; } } string commonSuffix = GetCommonSuffix(NormalizeFilePath(pathFromLogFile), resolvedPath); if (commonSuffix == null) { return(false); } // Trim the common suffix from both paths, and add a remapping that converts // one prefix to the other. string originalPrefix = pathFromLogFile.Substring(0, pathFromLogFile.Length - commonSuffix.Length); string resolvedPrefix = resolvedPath.Substring(0, resolvedPath.Length - commonSuffix.Length); int uriBaseIdEndIndex = resolvedPath.IndexOf(NormalizeFilePath(originalPath)); if (!string.IsNullOrEmpty(uriBaseId) && relativeUri != null && uriBaseIdEndIndex >= 0) { // If we could determine the uriBaseId substitution value, then add it to the map. dataCache.RemappedUriBasePaths[uriBaseId] = new Uri(resolvedPath.Substring(0, uriBaseIdEndIndex), UriKind.Absolute); } else { // If there's no relativeUri/uriBaseId pair or we couldn't determine the uriBaseId value, // map the original prefix to the new prefix. dataCache.RemappedPathPrefixes.Add(new Tuple <string, string>(originalPrefix, resolvedPrefix)); } return(true); }
internal bool TryResolveFilePathFromUriBasePaths(string uriBaseId, string pathFromLogFile, RunDataCache dataCache, out Uri relativeUri, out string resolvedPath) { relativeUri = null; resolvedPath = null; if (!string.IsNullOrEmpty(uriBaseId) && Uri.TryCreate(pathFromLogFile, UriKind.Relative, out relativeUri)) { // If the relative file path is relative to an unknown root, // we need to strip the leading slash, so that we can relate // the file path to an arbitrary remapped disk location. if (pathFromLogFile.StartsWith("/")) { pathFromLogFile = pathFromLogFile.Substring(1); } if (dataCache.RemappedUriBasePaths.TryGetValue(uriBaseId, out Uri baseUri)) { pathFromLogFile = new Uri(baseUri, pathFromLogFile).LocalPath; } else if (dataCache.OriginalUriBasePaths.TryGetValue(uriBaseId, out Uri originalBaseUri)) { pathFromLogFile = new Uri(originalBaseUri, pathFromLogFile).LocalPath; } if (this._fileSystem.FileExists(pathFromLogFile)) { resolvedPath = pathFromLogFile; return(true); } } return(false); }
internal string GetFilePathFromHttp(SarifErrorListItem sarifErrorListItem, string uriBaseId, RunDataCache dataCache, string pathFromLogFile) { ThreadHelper.ThrowIfNotOnUIThread(); Uri uri = null; if ((uriBaseId != null && dataCache.OriginalUriBasePaths.TryGetValue(uriBaseId, out Uri baseUri) && Uri.TryCreate(baseUri, pathFromLogFile, out uri) && uri.IsHttpScheme()) || // if result location uri is an absolute http url (Uri.TryCreate(pathFromLogFile, UriKind.Absolute, out uri) && uri.IsHttpScheme())) { return(this.HandleHttpFileDownloadRequest( VersionControlParserFactory.ConvertToRawFileLink(uri), sarifErrorListItem.WorkingDirectory)); } return(null); }
// Internal rather than private for unit testability. internal string GetRebaselinedFileName(string uriBaseId, string pathFromLogFile, RunDataCache dataCache, string workingDirectory = null, string solutionFullPath = null) { if (!SarifViewerPackage.IsUnitTesting) { #pragma warning disable VSTHRD108 // Assert thread affinity unconditionally ThreadHelper.ThrowIfNotOnUIThread(); #pragma warning restore VSTHRD108 } string originalPath = pathFromLogFile; Uri relativeUri = null; string resolvedPath = null; if (this.TryResolveFilePathFromUriBasePaths(uriBaseId, pathFromLogFile, dataCache, out relativeUri, out resolvedPath)) { return(resolvedPath); } if (this.TryResolveFilePathFromRemappings(pathFromLogFile, dataCache, out resolvedPath)) { return(resolvedPath); } if (this.TryResolveFilePathFromSolution( solutionPath: solutionFullPath, pathFromLogFile: originalPath, fileSystem: this._fileSystem, resolvedPath: out resolvedPath)) { return(resolvedPath); } // try to resolve using VersionControlProvenance if (this.TryResolveFilePathFromSourceControl(dataCache.SourceControlDetails, pathFromLogFile, workingDirectory, this._fileSystem, out resolvedPath)) { return(resolvedPath); } return(null); }
// return false means cannot resolve local file and will use embedded file. internal bool VerifyFileWithArtifactHash(SarifErrorListItem sarifErrorListItem, string pathFromLogFile, RunDataCache dataCache, string resolvedPath, string embeddedTempFilePath, out string newResolvedPath) { newResolvedPath = null; if (string.IsNullOrEmpty(resolvedPath)) { // cannot find corresponding file in local, then use embedded file newResolvedPath = embeddedTempFilePath; return(true); } if (!dataCache.FileDetails.TryGetValue(pathFromLogFile, out ArtifactDetailsModel fileData)) { // has no embedded file, return the path resolved till now newResolvedPath = resolvedPath; return(true); } string fileHash = this.GetFileHash(this._fileSystem, resolvedPath); if (fileHash.Equals(fileData.Sha256Hash, StringComparison.OrdinalIgnoreCase)) { // found a file in file system which has same hashcode as embeded content. newResolvedPath = resolvedPath; return(true); } bool hasEmbeddedContent = !string.IsNullOrEmpty(embeddedTempFilePath); ResolveEmbeddedFileDialogResult dialogResult = this._promptForEmbeddedFileDelegate(sarifErrorListItem.LogFilePath, hasEmbeddedContent, this.userDialogPreference); switch (dialogResult) { case ResolveEmbeddedFileDialogResult.None: // dialog is cancelled. newResolvedPath = null; return(false); case ResolveEmbeddedFileDialogResult.OpenEmbeddedFileContent: newResolvedPath = embeddedTempFilePath; return(true); case ResolveEmbeddedFileDialogResult.OpenLocalFileFromSolution: newResolvedPath = resolvedPath; return(true); case ResolveEmbeddedFileDialogResult.BrowseAlternateLocation: // if returns null means user cancelled the open file dialog. newResolvedPath = this._promptForResolvedPathDelegate(sarifErrorListItem, pathFromLogFile); return(!string.IsNullOrEmpty(newResolvedPath)); default: return(false); } }