Ejemplo n.º 1
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 (_artifactLocationToIndexMap == 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 scheme 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 artifactLocation = new ArtifactLocation
            {
                Uri       = fileLocation.Uri,
                UriBaseId = fileLocation.UriBaseId
            };

            if (!_artifactLocationToIndexMap.TryGetValue(artifactLocation, out int artifactIndex))
            {
                if (addToFilesTableIfNotPresent)
                {
                    this.Artifacts = this.Artifacts ?? new List <Artifact>();
                    artifactIndex  = this.Artifacts.Count;

                    Uri artifactUri = artifactLocation.TryReconstructAbsoluteUri(this.OriginalUriBaseIds, out Uri resolvedUri)
                        ? resolvedUri
                        : artifactLocation.Uri;

                    var artifact = Artifact.Create(
                        artifactUri,
                        dataToInsert,
                        hashData: hashData,
                        encoding: encoding);

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

                    this.Artifacts.Add(artifact);

                    _artifactLocationToIndexMap[artifactLocation] = artifactIndex;
                }
                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.
                    artifactIndex = -1;
                }
            }

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