MakeValidUri() public static method

Create a syntactically valid URI from a path that might be absolute or relative, and that might require percent-encoding.
In general, path might be: 1. Possible to interpret as an absolute path / absolute URI 2. Possible to interpret as a relative path / relative URI 3. Neither We must create a valid URI to persist in the SARIF log. We proceed as follows: 1. Try to create an absolute System.Uri. If that succeeds, take its AbsoluteUri, which (unlike Uri.ToString()) will be properly percent-encoded. 2. Try to create a relative System.Uri. If that succeeds, we want to write it out, but since this is a relative URI, we can't access its AbsoluteUri or AbsolutePath property -- and again, Uri.ToString() does not perform percent encoding. We use this workaround: a. Combine the relative path with an arbitrary scheme and host to form an absolute URI. b. Extract the AbsolutePath property, which will be percent encoded. 3. If all else fails, we have a string that we can't convert to a System.Uri, so just percent encode the whole thing. This should be extremely rare in practice. Thanks and a tip o' the hat to @nguerrera for this code (and for the comment).
public static MakeValidUri ( string path ) : string
path string /// The path to be transformed into a syntactically valid URI. ///
return string
Esempio n. 1
0
        public static ArtifactLocation CreateFromFilesDictionaryKey(string key, string parentKey = null)
        {
            string uriBaseId   = null;
            string originalKey = key;

            // A parent key indicates we're looking at an item that's nested within a container
            if (!string.IsNullOrEmpty(parentKey))
            {
                key = originalKey.Substring(parentKey.Length).Trim(new[] { '#' });
            }
            else if (key.StartsWith("#"))
            {
                string[] tokens = key.Split(new[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
                uriBaseId = tokens[0];

                // +2 to skip past leading and trailing octothorpes
                key = key.Substring(uriBaseId.Length + 2);
            }

            // At this point, if the key still contains an octothorpe, we are dealing with a
            // reference to a nested item (which we didn't identify because the caller to this
            // utility did not have the parent key in hand).
            if (key.Contains("#"))
            {
                key = key.Substring(key.IndexOf('#')).Trim(new[] { '#' });

                // A uriBaseId is only valid for a location that refers to a root container
                uriBaseId = null;
            }

            return(new ArtifactLocation()
            {
                Uri = new Uri(UriHelper.MakeValidUri(key), UriKind.RelativeOrAbsolute),
                UriBaseId = uriBaseId
            });
        }
Esempio n. 2
0
        public int GetFileIndex(
            ArtifactLocation fileLocation,
            bool addToFilesTableIfNotPresent   = true,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            Encoding encoding = null,
            HashData hashData = null)
        {
            if (fileLocation == null)
            {
                throw new ArgumentNullException(nameof(fileLocation));
            }

            if (this.Artifacts == null || this.Artifacts.Count == 0)
            {
                if (!addToFilesTableIfNotPresent)
                {
                    return(-1);
                }
            }

            if (_fileToIndexMap == null)
            {
                InitializeFileToIndexMap();
            }

            if (fileLocation.Uri == null)
            {
                // We only have a file index, so just return it.
                return(fileLocation.Index);
            }

            // Strictly speaking, some elements that may contribute to a files table
            // key are case sensitive, e.g., everything but the schema and protocol of a
            // web URI. We don't have a proper comparer implementation that can handle
            // all cases. For now, we cover the Windows happy path, which assumes that
            // most URIs in log files are file paths (which are case-insensitive)
            //
            // Tracking item for an improved comparer:
            // https://github.com/Microsoft/sarif-sdk/issues/973

            // When we perform a files table look-up, only the uri and uriBaseId
            // are relevant; these properties together comprise the unique identity
            // of the file object. The file index, of course, does not relate to the
            // file identity. We consciously exclude the properties bag as well.

            // We will normalize the input fileLocation.Uri to make URIs more consistent
            // throughout the emitted log.
            fileLocation.Uri = new Uri(UriHelper.MakeValidUri(fileLocation.Uri.OriginalString), UriKind.RelativeOrAbsolute);

            var filesTableKey = new ArtifactLocation
            {
                Uri       = fileLocation.Uri,
                UriBaseId = fileLocation.UriBaseId
            };

            if (!_fileToIndexMap.TryGetValue(filesTableKey, out int fileIndex))
            {
                if (addToFilesTableIfNotPresent)
                {
                    this.Artifacts = this.Artifacts ?? new List <Artifact>();
                    fileIndex      = this.Artifacts.Count;

                    var fileData = Artifact.Create(
                        filesTableKey.Uri,
                        dataToInsert,
                        hashData: hashData,
                        encoding: null);

                    // Copy ArtifactLocation to ensure changes to Result copy don't affect new Run.Artifacts copy
                    fileData.Location = new ArtifactLocation(fileLocation);

                    this.Artifacts.Add(fileData);

                    _fileToIndexMap[filesTableKey] = fileIndex;
                }
                else
                {
                    // We did not find the item. The call was not configured to add the entry.
                    // Return the default value that indicates the item isn't present.
                    fileIndex = -1;
                }
            }

            fileLocation.Index = fileIndex;
            return(fileIndex);
        }