Ejemplo n.º 1
0
        public int GetFileIndex(
            ArtifactLocation fileLocation,
            bool addToFilesTableIfNotPresent   = true,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            Encoding encoding = null)
        {
            if (fileLocation == null)
            {
                throw new ArgumentNullException(nameof(fileLocation));
            }

            if (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;

                    string mimeType = Writers.MimeType.DetermineFromFileExtension(filesTableKey.Uri.ToString());

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

                    fileData.Location = 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);
        }
Ejemplo n.º 2
0
 public Artifact(Microsoft.CodeAnalysis.Sarif.Artifact artifact)
 {
     File = artifact.Location.Uri.ToString();
     Size = artifact.Length;
 }
Ejemplo n.º 3
0
        public static Artifact Create(
            Uri uri,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            Encoding encoding      = null,
            HashData hashData      = null,
            IFileSystem fileSystem = null)
        {
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri));
            }

            fileSystem = fileSystem ?? new FileSystem();

            var artifact = new Artifact()
            {
                Encoding = encoding?.WebName,
            };

            string mimeType = SarifWriters.MimeType.DetermineFromFileExtension(uri);

            // Attempt to persist file contents and/or compute file hash and persist
            // this information to the log file. In the event that there is some issue
            // accessing the file, for example, due to ACLs applied to a directory,
            // we currently swallow these exceptions without populating any requested
            // data or putting a notification in the log file that a problem
            // occurred. Something to discuss moving forward.
            try
            {
                bool workTodo = dataToInsert.HasFlag(OptionallyEmittedData.Hashes) ||
                                dataToInsert.HasFlag(OptionallyEmittedData.TextFiles) ||
                                dataToInsert.HasFlag(OptionallyEmittedData.BinaryFiles);

                if (!workTodo ||
                    !uri.IsAbsoluteUri ||
                    !uri.IsFile ||
                    !fileSystem.FileExists(uri.LocalPath))
                {
                    return(artifact);
                }

                string filePath = uri.LocalPath;

                if (dataToInsert.HasFlag(OptionallyEmittedData.BinaryFiles) &&
                    SarifWriters.MimeType.IsBinaryMimeType(mimeType))
                {
                    artifact.Contents = GetEncodedFileContents(fileSystem, filePath, mimeType, encoding);
                }

                if (dataToInsert.HasFlag(OptionallyEmittedData.TextFiles) &&
                    SarifWriters.MimeType.IsTextualMimeType(mimeType))
                {
                    artifact.Contents = GetEncodedFileContents(fileSystem, filePath, mimeType, encoding);
                }

                if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
                {
                    HashData hashes = hashData ?? HashUtilities.ComputeHashes(filePath);
                    artifact.Hashes = new Dictionary <string, string>
                    {
                        { "md5", hashes.MD5 },
                        { "sha-1", hashes.Sha1 },
                        { "sha-256", hashes.Sha256 },
                    };
                }
            }
            catch (Exception e) when(e is IOException || e is UnauthorizedAccessException)
            {
            }

            return(artifact);
        }
Ejemplo n.º 4
0
 public bool ValueEquals(Artifact other) => ValueComparer.Equals(this, other);
Ejemplo n.º 5
0
        public void Artifact_DeserializeMultipleFileRoles()
        {
            Artifact actual = JsonConvert.DeserializeObject("{\"roles\":[\"responseFile\",\"resultFile\"],\"mimeType\":\"text/x-csharp\"}", typeof(Artifact)) as Artifact;

            actual.Roles.Should().Be(ArtifactRoles.ResponseFile | ArtifactRoles.ResultFile);
        }
Ejemplo n.º 6
0
        public void Artifact_DeserializeSingleFileRole()
        {
            Artifact actual = JsonConvert.DeserializeObject("{\"roles\":[\"analysisTarget\"],\"mimeType\":\"text/x-csharp\"}", typeof(Artifact)) as Artifact;

            actual.Roles.Should().Be(ArtifactRoles.AnalysisTarget);
        }
Ejemplo n.º 7
0
        public void Artifact_Create_NullUri()
        {
            Action action = () => { Artifact.Create(null, OptionallyEmittedData.None); };

            action.Should().Throw <ArgumentNullException>();
        }