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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        // 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);
            }
        }