コード例 #1
0
        /// <summary>Reads a "hints" element, consuming the element.</summary>
        /// <exception cref="XmlException">Thrown when the Android Studio file is incorrect.</exception>
        /// <param name="reader">The reader from which the hints shall be parsed.</param>
        /// <param name="strings">NameTable strings used to parse Android Studio files.</param>
        /// <returns>The set of hint values from <paramref name="reader"/>.</returns>
        public static ImmutableArray <string> ReadHints(XmlReader reader, AndroidStudioStrings strings)
        {
            Debug.Assert(Ref.Equal(reader.LocalName, strings.Hints), "ReadHints didn't have hints");

            var result = ImmutableArray.CreateBuilder <string>();

            if (!reader.IsEmptyElement)
            {
                int hintsDepth = reader.Depth;
                reader.Read(); // Consume start element
                while (reader.Depth > hintsDepth)
                {
                    if (!Ref.Equal(reader.LocalName, strings.Hint))
                    {
                        throw reader.CreateException(ConverterResources.AndroidStudioHintsElementContainedNonHint);
                    }

                    string hintContent = reader.GetAttribute(strings.Value);
                    if (hintContent == null)
                    {
                        throw reader.CreateException(ConverterResources.AndroidStudioHintElementMissingValue);
                    }

                    if (hintContent.Length != 0)
                    {
                        result.Add(hintContent);
                    }

                    reader.Skip();
                }
            }

            reader.Read(); // Consume the end / empty element
            return(result.ToImmutable());
        }
コード例 #2
0
ファイル: CppCheckError.cs プロジェクト: tosmolka/sarif-sdk
        /// <summary>
        /// Parses the element on which an <see cref="XmlReader"/> is positioned as a CppCheck error node.
        /// </summary>
        /// <param name="reader">The reader from which a CppCheck error shall be read.</param>
        /// <param name="strings">Strings used to parse the CppCheck log.</param>
        /// <returns>
        /// A <see cref="CppCheckError"/> parsed from the XML on which <paramref name="reader"/> is
        /// positioned.
        /// </returns>
        /// <exception cref="XmlException">The xml on which <paramref name="reader"/> is placed is
        /// in an incorrect format.</exception>
        public static CppCheckError Parse(XmlReader reader, CppCheckStrings strings)
        {
            if (!reader.IsStartElement(strings.Error))
            {
                throw reader.CreateException(ConverterResources.CppCheckElementNotError);
            }

            string id             = null;
            string message        = null;
            string verboseMessage = null;
            string severity       = null;

            while (reader.MoveToNextAttribute())
            {
                string attributeName = reader.LocalName;
                if (StringReference.AreEqual(attributeName, strings.Id))
                {
                    id = reader.Value;
                }
                else if (StringReference.AreEqual(attributeName, strings.Msg))
                {
                    message = reader.Value;
                }
                else if (StringReference.AreEqual(attributeName, strings.Verbose))
                {
                    verboseMessage = reader.Value;
                }
                else if (StringReference.AreEqual(attributeName, strings.Severity))
                {
                    severity = reader.Value;
                }
            }

            reader.MoveToElement();
            ImmutableArray <CppCheckLocation> locations = ParseLocationsSubtree(reader, strings);

            reader.Read(); // Consumes the end element or self closing element and positions the reader on the next node

            try
            {
                return(new CppCheckError(
                           id,
                           message,
                           verboseMessage,
                           severity,
                           locations
                           ));
            }
            catch (ArgumentException ex)
            {
                throw reader.CreateException(ex.Message);
            }
        }
コード例 #3
0
        private void ProcessCppCheckLog(XmlReader reader, IResultLogWriter issueWriter)
        {
            reader.ReadStartElement(_strings.Results);

            if (!Ref.Equal(reader.LocalName, _strings.CppCheck))
            {
                throw reader.CreateException(SarifResources.CppCheckCppCheckElementMissing);
            }

            string version = reader.GetAttribute(_strings.Version);

            if (String.IsNullOrWhiteSpace(version))
            {
                throw reader.CreateException(SarifResources.CppCheckCppCheckElementMissing);
            }

            issueWriter.WriteToolAndRunInfo(new ToolInfo
            {
                Name    = "CppCheck",
                Version = version,
            }, null);

            reader.Skip(); // <cppcheck />

            if (!Ref.Equal(reader.LocalName, _strings.Errors))
            {
                throw reader.CreateException(SarifResources.CppCheckErrorsElementMissing);
            }

            if (reader.IsEmptyElement)
            {
                reader.Skip(); // <errors />
            }
            else
            {
                int errorsDepth = reader.Depth;
                reader.Read(); // <errors>
                while (reader.Depth > errorsDepth)
                {
                    var parsedError = CppCheckError.Parse(reader, _strings);
                    issueWriter.WriteResult(parsedError.ToSarifIssue());
                }

                reader.ReadEndElement(); // </errors>
            }

            reader.ReadEndElement(); // </results>
        }
コード例 #4
0
        public void Extensions_XmlCreateException_WithFormat()
        {
            var testData = new XElement("hello", new XElement("world"));

            using (XmlReader unitUnderTest = testData.CreateReader())
            {
                XmlException result = unitUnderTest.CreateException("hungry {0} zombies", "evil");
                Assert.Equal("hungry evil zombies", result.Message);
            }
        }
コード例 #5
0
        /// <summary>
        /// Parses a "location" node from the supplied instance of <see cref="XmlReader"/>.
        /// </summary>
        /// <exception cref="XmlException">Thrown if <paramref name="reader"/> points to XML of an
        /// incorrect format.</exception>
        /// <param name="reader">The reader from which XML will be parsed. Upon entry to this method, this
        /// XML reader must be positioned on the location node to parse. Upon completion of this method,
        /// the reader will be positioned on the node following the location node.</param>
        /// <param name="strings">Strings used to parse the CppCheck log.</param>
        /// <returns>
        /// A <see cref="CppCheckLocation"/> instance containing data from the current node of
        /// <paramref name="reader"/>.
        /// </returns>
        public static CppCheckLocation Parse(XmlReader reader, CppCheckStrings strings)
        {
            if (!reader.IsStartElement(strings.Location))
            {
                throw reader.CreateException(ConverterResources.CppCheckLocationElementNameIncorrect);
            }

            string file     = null;
            string lineText = null;

            while (reader.MoveToNextAttribute())
            {
                string name = reader.LocalName;
                if (StringReference.AreEqual(name, strings.File))
                {
                    file = reader.Value;
                }
                else if (StringReference.AreEqual(name, strings.Line))
                {
                    lineText = reader.Value;
                }
            }

            if (file == null)
            {
                throw reader.CreateException(ConverterResources.CppCheckLocationMissingName);
            }

            if (lineText == null)
            {
                throw reader.CreateException(ConverterResources.CppCheckLocationMissingLine);
            }

            int line = XmlConvert.ToInt32(lineText);

            reader.MoveToElement();
            reader.Skip();

            return(new CppCheckLocation(file, line));
        }
コード例 #6
0
        /// <summary>Parses an element as a Fortify PathElement node, consuming the node.</summary>
        /// <param name="xmlReader">The <see cref="XmlReader"/> from which a node shall be parsed. When
        /// this function returns, this reader is placed directly after the element on which it is
        /// currently placed.</param>
        /// <param name="strings">Strings used in processing Fortify logs.</param>
        /// <returns>A <see cref="FortifyPathElement"/> parsed from the element on which
        /// <paramref name="xmlReader"/> is positioned when this method is called.</returns>
        public static FortifyPathElement Parse(XmlReader xmlReader, FortifyStrings strings)
        {
            //<xs:complexType name="PathElement">
            //    <xs:sequence>
            //        <xs:element name="FileName" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //        <xs:element name="FilePath" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //        <xs:element name="LineStart" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //        <xs:element name="Snippet" type="xs:string" minOccurs="0" maxOccurs="1"/>
            //        <xs:element name="SnippetLine" type="xs:int" minOccurs="0" maxOccurs="1"/>
            //        <xs:element name="TargetFunction" type="xs:string" minOccurs="0" maxOccurs="1"/>
            //    </xs:sequence>
            //</xs:complexType>

            if (xmlReader.NodeType != XmlNodeType.Element || xmlReader.IsEmptyElement)
            {
                throw xmlReader.CreateException(SarifResources.FortifyNotValidPathElement);
            }

            int pathElementDepth = xmlReader.Depth;

            xmlReader.Read(); // Always true because !IsEmptyElement
            xmlReader.IgnoreElement(strings.FileName, IgnoreOptions.Required);
            string filePath  = xmlReader.ReadElementContentAsString(strings.FilePath, String.Empty);
            int    lineStart = xmlReader.ReadElementContentAsInt(strings.LineStart, String.Empty);

            xmlReader.IgnoreElement(strings.Snippet, IgnoreOptions.Optional);
            xmlReader.IgnoreElement(strings.SnippetLine, IgnoreOptions.Optional);
            string targetFunction = xmlReader.ReadOptionalElementContentAsString(strings.TargetFunction);

            xmlReader.ReadEndElement();

            try
            {
                return(new FortifyPathElement(filePath, lineStart, targetFunction));
            }
            catch (ArgumentException ex)
            {
                throw xmlReader.CreateException(ex.Message);
            }
        }
コード例 #7
0
 public void Extensions_XmlCreateException_WithLineInfo()
 {
     // 0000000001111111111222222
     // 1234567890123456789012345
     using (XmlReader unitUnderTest = Utilities.CreateXmlReaderFromString("<hello> <world/> </hello>"))
     {
         unitUnderTest.Read(); // <hello>
         unitUnderTest.Read(); // <world>
         XmlException result = unitUnderTest.CreateException("cute fluffy kittens");
         Assert.Equal(1, result.LineNumber);
         Assert.Equal(8, result.LinePosition);
     }
 }
コード例 #8
0
        public void Extensions_XmlCreateException_WithoutLineInfo()
        {
            var testData = new XElement("hello", new XElement("world"));

            using (XmlReader unitUnderTest = testData.CreateReader())
            {
                unitUnderTest.Read(); // <hello>
                unitUnderTest.Read(); // <world />
                XmlException result = unitUnderTest.CreateException("hungry EVIL zombies");
                Assert.Equal(0, result.LineNumber);
                Assert.Equal(0, result.LinePosition);
            }
        }
コード例 #9
0
ファイル: Extensions.cs プロジェクト: tosmolka/sarif-sdk
        /// <summary>Asserts that the local name of a given element is the name indicated, and ignores the
        /// element's contents.</summary>
        /// <exception cref="XmlException">Thrown when the XML content pointed to by
        /// <paramref name="xmlReader"/> does not match the indicated <paramref name="elementName"/> and
        /// <paramref name="options"/>.</exception>
        /// <param name="xmlReader">The XML reader from which the element shall be read.</param>
        /// <param name="elementName">Name of the element.</param>
        /// <param name="options">Options deciding what content to skip.</param>
        internal static void IgnoreElement(this XmlReader xmlReader, string elementName, IgnoreOptions options)
        {
            if (!IsOnElement(xmlReader, elementName))
            {
                if (options.HasFlag(IgnoreOptions.Optional))
                {
                    return;
                }
                else
                {
                    throw xmlReader.CreateException(ConverterResources.ExpectedElementNamed, elementName);
                }
            }

            xmlReader.Skip();
            if (options.HasFlag(IgnoreOptions.Multiple))
            {
                while (IsOnElement(xmlReader, elementName))
                {
                    xmlReader.Skip();
                }
            }
        }
コード例 #10
0
ファイル: Extensions.cs プロジェクト: tosmolka/sarif-sdk
 /// <summary>Creates an exception with line number and position data from an
 /// <see cref="XmlReader"/>.</summary>
 /// <param name="xmlReader">The xmlReader from which line data shall be retrieved.</param>
 /// <param name="message">The message to attach to the exception.</param>
 /// <param name="args">A variable-length parameters list containing arguments formatted into
 /// <paramref name="message"/>.</param>
 /// <returns>The new exception with <paramref name="message"/>, and file and line information from
 /// <paramref name="xmlReader"/>.</returns>
 internal static XmlException CreateException(this XmlReader xmlReader, string message, params object[] args)
 {
     return(xmlReader.CreateException(string.Format(CultureInfo.CurrentCulture, message, args)));
 }
コード例 #11
0
        private void ProcessCppCheckLog(XmlReader reader, IResultLogWriter output, OptionallyEmittedData dataToInsert)
        {
            reader.ReadStartElement(_strings.Results);

            if (!StringReference.AreEqual(reader.LocalName, _strings.CppCheck))
            {
                throw reader.CreateException(ConverterResources.CppCheckCppCheckElementMissing);
            }

            string version = reader.GetAttribute(_strings.Version);

            if (version != null && !version.IsSemanticVersioningCompatible())
            {
                // This logic only fixes up simple cases, such as being passed
                // 1.66, where Semantic Versioning 2.0 requires 1.66.0. Also
                // strips Revision member if passed a complete .NET version.
                Version dotNetVersion;
                if (Version.TryParse(version, out dotNetVersion))
                {
                    version =
                        Math.Max(0, dotNetVersion.Major) + "." +
                        Math.Max(0, dotNetVersion.Minor) + "." +
                        Math.Max(0, dotNetVersion.Build);
                }
            }

            if (String.IsNullOrWhiteSpace(version))
            {
                throw reader.CreateException(ConverterResources.CppCheckCppCheckElementMissing);
            }

            reader.Skip(); // <cppcheck />

            if (!StringReference.AreEqual(reader.LocalName, _strings.Errors))
            {
                throw reader.CreateException(ConverterResources.CppCheckErrorsElementMissing);
            }

            var results = new List <Result>();

            if (reader.IsEmptyElement)
            {
                reader.Skip(); // <errors />
            }
            else
            {
                int errorsDepth = reader.Depth;
                reader.Read(); // <errors>

                while (reader.Depth > errorsDepth)
                {
                    var parsedError = CppCheckError.Parse(reader, _strings);
                    results.Add(parsedError.ToSarifIssue());
                }

                reader.ReadEndElement(); // </errors>
            }

            reader.ReadEndElement(); // </results>

            var tool = new Tool
            {
                Name    = "CppCheck",
                Version = version,
            };

            var fileInfoFactory = new FileInfoFactory(uri => MimeType.Cpp, dataToInsert);
            Dictionary <string, FileData> fileDictionary = fileInfoFactory.Create(results);

            var run = new Run()
            {
                Tool = tool
            };

            output.Initialize(run);

            if (fileDictionary != null && fileDictionary.Count > 0)
            {
                output.WriteFiles(fileDictionary);
            }

            output.OpenResults();
            output.WriteResults(results);
            output.CloseResults();
        }
コード例 #12
0
        /// <summary>Parses a "problem" node from an Android Studio log and consumes that node.</summary>
        /// <exception cref="XmlException">Thrown when the Android Studio file is incorrect.</exception>
        /// <param name="reader">The reader from which the problem shall be parsed.</param>
        /// <param name="strings">NameTable strings used to parse Android Studio files.</param>
        /// <returns>
        /// If the problem node is not empty, an instance of <see cref="AndroidStudioProblem" />;
        /// otherwise, null.
        /// </returns>
        public static AndroidStudioProblem Parse(XmlReader reader, AndroidStudioStrings strings)
        {
            if (!reader.IsStartElement(strings.Problem))
            {
                throw reader.CreateException(ConverterResources.AndroidStudioNotProblemElement);
            }

            Builder b = new Builder();

            if (!reader.IsEmptyElement)
            {
                int problemDepth = reader.Depth;
                reader.Read(); // Get to children
                while (reader.Depth > problemDepth)
                {
                    string nodeName = reader.LocalName;
                    if (Ref.Equal(nodeName, strings.File))
                    {
                        b.File = reader.ReadElementContentAsString();
                    }
                    else if (Ref.Equal(nodeName, strings.Line))
                    {
                        b.Line = Math.Max(1, reader.ReadElementContentAsInt());
                    }
                    else if (Ref.Equal(nodeName, strings.Module))
                    {
                        b.Module = reader.ReadElementContentAsString();
                    }
                    else if (Ref.Equal(nodeName, strings.Package))
                    {
                        b.Package = reader.ReadElementContentAsString();
                    }
                    else if (Ref.Equal(nodeName, strings.EntryPoint))
                    {
                        ReadEntryPointElement(ref b, reader, strings);
                    }
                    else if (Ref.Equal(nodeName, strings.ProblemClass))
                    {
                        ReadProblemClassElement(ref b, reader, strings);
                    }
                    else if (Ref.Equal(nodeName, strings.Hints))
                    {
                        b.Hints = ReadHints(reader, strings);
                    }
                    else if (Ref.Equal(nodeName, strings.Description))
                    {
                        b.Description = reader.ReadElementContentAsString();
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
            }

            reader.Read(); // Consume the empty / end element

            if (b.IsEmpty)
            {
                return(null);
            }

            try
            {
                return(new AndroidStudioProblem(b));
            }
            catch (ArgumentException invalidData)
            {
                throw reader.CreateException(invalidData.Message);
            }
        }
コード例 #13
0
        private void ProcessCppCheckLog(XmlReader reader, IResultLogWriter output, OptionallyEmittedData dataToInsert)
        {
            reader.ReadStartElement(_strings.Results);

            if (!StringReference.AreEqual(reader.LocalName, _strings.CppCheck))
            {
                throw reader.CreateException(ConverterResources.CppCheckCppCheckElementMissing);
            }

            string version = reader.GetAttribute(_strings.Version);

            if (version != null && !version.IsSemanticVersioningCompatible())
            {
                // This logic only fixes up simple cases, such as being passed
                // 1.66, where Semantic Versioning 2.0 requires 1.66.0. Also
                // strips Revision member if passed a complete .NET version.
                Version dotNetVersion;
                if (Version.TryParse(version, out dotNetVersion))
                {
                    version =
                        Math.Max(0, dotNetVersion.Major) + "." +
                        Math.Max(0, dotNetVersion.Minor) + "." +
                        Math.Max(0, dotNetVersion.Build);
                }
            }

            if (string.IsNullOrWhiteSpace(version))
            {
                throw reader.CreateException(ConverterResources.CppCheckCppCheckElementMissing);
            }

            reader.Skip(); // <cppcheck />

            if (!StringReference.AreEqual(reader.LocalName, _strings.Errors))
            {
                throw reader.CreateException(ConverterResources.CppCheckErrorsElementMissing);
            }

            var results = new List <Result>();

            if (reader.IsEmptyElement)
            {
                reader.Skip(); // <errors />
            }
            else
            {
                int errorsDepth = reader.Depth;
                reader.Read(); // <errors>

                while (reader.Depth > errorsDepth)
                {
                    var parsedError = CppCheckError.Parse(reader, _strings);
                    results.Add(parsedError.ToSarifIssue());
                }

                reader.ReadEndElement(); // </errors>
            }

            reader.ReadEndElement(); // </results>

            var run = new Run()
            {
                Tool = new Tool {
                    Driver = new ToolComponent {
                        Name = ToolName, Version = version
                    }
                },
            };

            PersistResults(output, results, run);
        }
コード例 #14
0
        /// <summary>
        /// Parses a Fortify Result element from an <see cref="XmlReader"/>.
        /// </summary>
        /// <param name="xmlReader">The <see cref="XmlReader"/> from which an element containing a Fortify result shall be
        /// consumed. When this method returns, this <see cref="XmlReader"/> is positioned on the following element.</param>
        /// <param name="strings">Strings used in processing a Fortify report.</param>
        /// <returns>A <see cref="FortifyIssue"/> containing data from the node on which <paramref name="xmlReader"/> was
        /// placed when this method was called.</returns>
        public static FortifyIssue Parse(XmlReader xmlReader, FortifyStrings strings)
        {
            //<xs:element name="Result">
            //    <xs:complexType>
            //        <xs:sequence>
            //            <!-- Result Description -->
            //            <xs:element name="Category" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //            <xs:element name="Folder" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //            <xs:element name="Kingdom" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //            <xs:element name="Abstract" type="xs:string" minOccurs="0" maxOccurs="1"/>
            //            <xs:element name="AbstractCustom" type="xs:string" minOccurs="0" maxOccurs="1"/>
            //            <xs:element name="Friority" type="xs:string" minOccurs="0" maxOccurs="1"/>
            //            <!-- custom tags including Analysis -->
            //            <xs:element name="Tag" minOccurs="0" maxOccurs="unbounded">
            //                <xs:complexType>
            //                    <xs:sequence>
            //                        <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //                        <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //                    </xs:sequence>
            //                </xs:complexType>
            //            </xs:element>
            //            <xs:element name="Comment" minOccurs="0" maxOccurs="unbounded">
            //                <xs:complexType>
            //                    <xs:sequence>
            //                        <xs:element name="UserInfo" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //                        <xs:element name="Comment" type="xs:string" minOccurs="1" maxOccurs="1"/>
            //                    </xs:sequence>
            //                </xs:complexType>
            //            </xs:element>
            //            <!-- primary or sink -->
            //            <xs:element name="Primary" type="PathElement" minOccurs="1" maxOccurs="1"/>
            //            <!-- source -->
            //            <xs:element name="Source" type="PathElement" minOccurs="0" maxOccurs="1"/>
            //            <xs:element name="TraceDiagramPath" type="xs:string" minOccurs="0" maxOccurs="1"/>
            //            <!-- optional external category (i.e. STIG) -->
            //            <xs:element name="ExternalCategory" minOccurs="0" maxOccurs="1">
            //                <xs:complexType>
            //                    <xs:simpleContent>
            //                        <xs:extension base="xs:string">
            //                            <xs:attribute name="type" type="xs:string" use="required"/>
            //                        </xs:extension>
            //                    </xs:simpleContent>
            //                </xs:complexType>
            //            </xs:element>
            //        </xs:sequence>
            //        <xs:attribute name="iid" type="xs:string" use="optional"/>
            //        <xs:attribute name="ruleID" type="xs:string" use="optional"/>
            //    </xs:complexType>
            //</xs:element>
            if (!xmlReader.IsStartElement(strings.Issue))
            {
                throw xmlReader.CreateException(ConverterResources.FortifyNotValidResult);
            }

            string iid    = null;
            string ruleId = null;

            while (xmlReader.MoveToNextAttribute())
            {
                string name = xmlReader.LocalName;
                if (StringReference.AreEqual(name, strings.Iid))
                {
                    iid = xmlReader.Value;
                }
                else if (StringReference.AreEqual(name, strings.RuleId))
                {
                    ruleId = xmlReader.Value;
                }
            }

            xmlReader.MoveToElement();
            xmlReader.Read(); // reads start element

            string category = xmlReader.ReadElementContentAsString(strings.Category, String.Empty);

            xmlReader.IgnoreElement(strings.Folder, IgnoreOptions.Required);
            string kingdom        = xmlReader.ReadElementContentAsString(strings.Kingdom, String.Empty);
            string abstract_      = xmlReader.ReadOptionalElementContentAsString(strings.Abstract);
            string abstractCustom = xmlReader.ReadOptionalElementContentAsString(strings.AbstractCustom);
            string friority       = xmlReader.ReadOptionalElementContentAsString(strings.Friority);

            xmlReader.IgnoreElement(strings.Tag, IgnoreOptions.Optional | IgnoreOptions.Multiple);
            xmlReader.IgnoreElement(strings.Comment, IgnoreOptions.Optional | IgnoreOptions.Multiple);
            FortifyPathElement primary = FortifyPathElement.Parse(xmlReader, strings);
            FortifyPathElement source;

            if (xmlReader.NodeType == XmlNodeType.Element && StringReference.AreEqual(xmlReader.LocalName, strings.Source))
            {
                source = FortifyPathElement.Parse(xmlReader, strings);
            }
            else
            {
                source = null;
            }

            xmlReader.IgnoreElement(strings.TraceDiagramPath, IgnoreOptions.Optional);
            ImmutableArray <int> cweIds = ImmutableArray <int> .Empty;

            if (xmlReader.NodeType == XmlNodeType.Element && StringReference.AreEqual(xmlReader.LocalName, strings.ExternalCategory))
            {
                if (xmlReader.GetAttribute(strings.Type) == "CWE")
                {
                    cweIds = ParseCweIds(xmlReader.ReadElementContentAsString());
                }
                else
                {
                    xmlReader.Skip();
                }
            }

            xmlReader.ReadEndElement(); // </Result>

            return(new FortifyIssue(ruleId, iid, category, kingdom, abstract_, abstractCustom, friority, primary, source, cweIds));
        }
コード例 #15
0
        private void ProcessCppCheckLog(XmlReader reader, IResultLogWriter output)
        {
            reader.ReadStartElement(_strings.Results);

            if (!Ref.Equal(reader.LocalName, _strings.CppCheck))
            {
                throw reader.CreateException(ConverterResources.CppCheckCppCheckElementMissing);
            }

            string version = reader.GetAttribute(_strings.Version);

            if (version != null && !version.IsSemanticVersioningCompatible())
            {
                // This logic only fixes up simple cases, such as being passed
                // 1.66, where Semantic Versioning 2.0 requires 1.66.0. Also
                // strips Revision member if passed a complete .NET version.
                Version dotNetVersion;
                if (Version.TryParse(version, out dotNetVersion))
                {
                    version =
                        Math.Max(0, dotNetVersion.Major) + "." +
                        Math.Max(0, dotNetVersion.Minor) + "." +
                        Math.Max(0, dotNetVersion.Build);
                }
            }

            if (String.IsNullOrWhiteSpace(version))
            {
                throw reader.CreateException(ConverterResources.CppCheckCppCheckElementMissing);
            }

            reader.Skip(); // <cppcheck />

            if (!Ref.Equal(reader.LocalName, _strings.Errors))
            {
                throw reader.CreateException(ConverterResources.CppCheckErrorsElementMissing);
            }

            var results = new List<Result>();
            if (reader.IsEmptyElement)
            {
                reader.Skip(); // <errors />
            }
            else
            {
                int errorsDepth = reader.Depth;
                reader.Read(); // <errors>

                while (reader.Depth > errorsDepth)
                {
                    var parsedError = CppCheckError.Parse(reader, _strings);
                    results.Add(parsedError.ToSarifIssue());
                }

                reader.ReadEndElement(); // </errors>
            }

            reader.ReadEndElement(); // </results>

            var tool = new Tool
            {
                Name = "CppCheck",
                Version = version,
            };

            var fileInfoFactory = new FileInfoFactory(uri => MimeType.Cpp);
            Dictionary<string, FileData> fileDictionary = fileInfoFactory.Create(results);

            output.Initialize(id: null, correlationId: null);

            output.WriteTool(tool);
            if (fileDictionary != null && fileDictionary.Count > 0) { output.WriteFiles(fileDictionary); }

            output.OpenResults();
            output.WriteResults(results);
            output.CloseResults();
        }