diff --git a/src/sarif_v2.1.0_schema.json b/src/sarif-schema-2.1.0.json similarity index 96% rename from src/sarif_v2.1.0_schema.json rename to src/sarif-schema-2.1.0.json index 41b12d4af..5020cc166 100644 --- a/src/sarif_v2.1.0_schema.json +++ b/src/sarif-schema-2.1.0.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Static Analysis Results Format (SARIF) Version 2.1.0 JSON Schema", "$id": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", "description": "Static Analysis Results Format (SARIF) Version 2.1.0 JSON Schema: a standard format for the output of static analysis tools.", @@ -15,13 +15,15 @@ "version": { "description": "The SARIF format version of this log file.", - "enum": [ "2.1.0" ] + "enum": [ "2.1.0" ], + "type": "string" }, "runs": { "description": "The set of runs contained in this log file.", - "type": "array", + "type": [ "array", "null" ], "minItems": 0, + "uniqueItems": false, "items": { "$ref": "#/definitions/run" } @@ -180,7 +182,8 @@ "userSpecifiedConfiguration", "toolSpecifiedConfiguration", "debugOutputFile" - ] + ], + "type": "string" } }, @@ -241,6 +244,7 @@ "description": "An array of replacement objects, each of which represents the replacement of a single region in a single artifact specified by 'artifactLocation'.", "type": "array", "minItems": 1, + "uniqueItems": false, "items": { "$ref": "#/definitions/replacement" } @@ -382,6 +386,7 @@ "description": "An array of one or more unique threadFlow objects, each of which describes the progress of a program through a thread of execution.", "type": "array", "minItems": 1, + "uniqueItems": false, "items": { "$ref": "#/definitions/threadFlow" } @@ -556,6 +561,7 @@ "description": "An array of exception objects each of which is considered a cause of this exception.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/exception" @@ -583,17 +589,18 @@ "version": { "description": "The SARIF format version of this external properties object.", - "enum": [ "2.1.0" ] + "enum": [ "2.1.0" ], + "type": "string" }, "guid": { - "description": "A stable, unique identifer for this external properties object, in the form of a GUID.", + "description": "A stable, unique identifier for this external properties object, in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, "runGuid": { - "description": "A stable, unique identifer for the run associated with this external properties object, in the form of a GUID.", + "description": "A stable, unique identifier for the run associated with this external properties object, in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, @@ -633,6 +640,7 @@ "description": "Describes the invocation of the analysis tool that will be merged with a separate run.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/invocation" @@ -665,6 +673,7 @@ "description": "An array of result objects that will be merged with a separate run.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/result" @@ -724,6 +733,7 @@ "description": "Addresses that will be merged with a separate run.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/address" @@ -771,7 +781,7 @@ }, "guid": { - "description": "A stable, unique identifer for the external property file in the form of a GUID.", + "description": "A stable, unique identifier for the external property file in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, @@ -1079,6 +1089,7 @@ "description": "The sequences of edges traversed by this graph traversal.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/edgeTraversal" @@ -1111,6 +1122,7 @@ "description": "An array of strings, containing in order the command line arguments passed to the tool from the operating system.", "type": "array", "minItems": 0, + "uniqueItems": false, "items": { "type": "string" } @@ -1127,13 +1139,13 @@ }, "startTimeUtc": { - "description": "The Coordinated Universal Time (UTC) date and time at which the run started. See \"Date/time properties\" in the SARIF spec for the required format.", + "description": "The Coordinated Universal Time (UTC) date and time at which the invocation started. See \"Date/time properties\" in the SARIF spec for the required format.", "type": "string", "format": "date-time" }, "endTimeUtc": { - "description": "The Coordinated Universal Time (UTC) date and time at which the run ended. See \"Date/time properties\" in the SARIF spec for the required format.", + "description": "The Coordinated Universal Time (UTC) date and time at which the invocation ended. See \"Date/time properties\" in the SARIF spec for the required format.", "type": "string", "format": "date-time" }, @@ -1169,6 +1181,7 @@ "description": "A list of runtime conditions detected by the tool during the analysis.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/notification" @@ -1179,6 +1192,7 @@ "description": "A list of conditions detected by the tool that are relevant to the tool's configuration.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/notification" @@ -1211,27 +1225,27 @@ }, "machine": { - "description": "The machine that hosted the analysis tool run.", + "description": "The machine on which the invocation occurred.", "type": "string" }, "account": { - "description": "The account that ran the analysis tool.", + "description": "The account under which the invocation occurred.", "type": "string" }, "processId": { - "description": "The process id for the analysis tool run.", + "description": "The id of the process in which the invocation occurred.", "type": "integer" }, "executableLocation": { - "description": "An absolute URI specifying the location of the analysis tool's executable.", + "description": "An absolute URI specifying the location of the executable that was invoked.", "$ref": "#/definitions/artifactLocation" }, "workingDirectory": { - "description": "The working directory for the analysis tool run.", + "description": "The working directory for the invocation.", "$ref": "#/definitions/artifactLocation" }, @@ -1442,6 +1456,7 @@ "description": "An array of strings to substitute into the message string.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "type": "string" @@ -1551,7 +1566,8 @@ "level": { "description": "A value specifying the severity level of the notification.", "default": "warning", - "enum": [ "none", "note", "warning", "error" ] + "enum": [ "none", "note", "warning", "error" ], + "type": "string" }, "threadId": { @@ -1762,7 +1778,13 @@ "properties": { "description": "Key/value pairs that provide additional information about the region.", "$ref": "#/definitions/propertyBag" - } + }, + + "anyOf": [ + { "required": [ "startLine" ] }, + { "required": [ "charOffset" ] }, + { "required": [ "byteOffset" ] } + ] } }, @@ -1813,7 +1835,7 @@ }, "guid": { - "description": "A unique identifer for the reporting descriptor in the form of a GUID.", + "description": "A unique identifier for the reporting descriptor in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, @@ -1912,7 +1934,8 @@ "level": { "description": "Specifies the failure level for the report.", "default": "warning", - "enum": [ "none", "note", "warning", "error" ] + "enum": [ "none", "note", "warning", "error" ], + "type": "string" }, "rank": { @@ -2017,7 +2040,7 @@ "properties": { "ruleId": { - "description": "The stable, unique identifier of the rule, if any, to which this notification is relevant. This member can be used to retrieve rule metadata from the rules dictionary, if it exists.", + "description": "The stable, unique identifier of the rule, if any, to which this result is relevant.", "type": "string" }, @@ -2036,13 +2059,15 @@ "kind": { "description": "A value that categorizes results by evaluation state.", "default": "fail", - "enum": [ "notApplicable", "pass", "fail", "review", "open", "informational" ] + "enum": [ "notApplicable", "pass", "fail", "review", "open", "informational" ], + "type": "string" }, "level": { "description": "A value specifying the severity level of the result.", "default": "warning", - "enum": [ "none", "note", "warning", "error" ] + "enum": [ "none", "note", "warning", "error" ], + "type": "string" }, "message": { @@ -2059,6 +2084,7 @@ "description": "The set of locations where the result was detected. Specify only one location unless the problem indicated by the result can only be corrected by making a change at every specified location.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/location" @@ -2066,7 +2092,7 @@ }, "guid": { - "description": "A stable, unique identifer for the result in the form of a GUID.", + "description": "A stable, unique identifier for the result in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, @@ -2114,6 +2140,7 @@ "description": "An array of 'codeFlow' objects relevant to the result.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/codeFlow" @@ -2170,7 +2197,8 @@ "unchanged", "updated", "absent" - ] + ], + "type": "string" }, "rank": { @@ -2324,6 +2352,7 @@ "description": "Describes the invocation of the analysis tool.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/invocation" @@ -2339,8 +2368,9 @@ "description": "The language of the messages emitted into the log file during this run (expressed as an ISO 639-1 two-letter lowercase culture code) and an optional region (expressed as an ISO 3166-1 two-letter uppercase subculture code associated with a country or region). The casing is recommended but not required (in order for this data to conform to RFC5646).", "type": "string", "default": "en-US", - "pattern": "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$" + "pattern": "^(?i)[a-zA]{2}(-[a-z]{2})?$" }, + "versionControlProvenance": { "description": "Specifies the revision in version control of the artifacts that were scanned.", "type": "array", @@ -2396,6 +2426,7 @@ "description": "The set of results contained in an SARIF log. The results array can be omitted when a run is solely exporting rules metadata. It must be present (but may be empty) if a log file represents an actual scan.", "type": "array", "minItems": 0, + "uniqueItems": false, "items": { "$ref": "#/definitions/result" } @@ -2457,7 +2488,8 @@ "columnKind": { "description": "Specifies the unit in which the tool measures columns.", - "enum": [ "utf16CodeUnits", "unicodeCodePoints" ] + "enum": [ "utf16CodeUnits", "unicodeCodePoints" ], + "type": "string" }, "externalPropertyFileReferences": { @@ -2491,6 +2523,7 @@ "description": "Addresses associated with this run instance, if any.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "$ref": "#/definitions/address" @@ -2572,7 +2605,7 @@ }, "guid": { - "description": "A stable, unique identifer for this object's containing run object in the form of a GUID.", + "description": "A stable, unique identifier for this object's containing run object in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, @@ -2623,6 +2656,7 @@ "description": "An array of stack frames that represents a sequence of calls, rendered in reverse chronological order, that comprise the call stack.", "type": "array", "minItems": 0, + "uniqueItems": false, "items": { "$ref": "#/definitions/stackFrame" } @@ -2661,6 +2695,7 @@ "description": "The parameters of the call that is executing.", "type": "array", "minItems": 0, + "uniqueItems": false, "default": [], "items": { "type": "string", @@ -2682,7 +2717,7 @@ "properties": { "guid": { - "description": "A stable, unique identifer for the suprression in the form of a GUID.", + "description": "A stable, unique identifier for the suprression in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, @@ -2692,16 +2727,18 @@ "enum": [ "inSource", "external" - ] + ], + "type": "string" }, - "state": { - "description": "A string that indicates the state of the suppression.", + "status": { + "description": "A string that indicates the review status of the suppression.", "enum": [ "accepted", "underReview", "rejected" - ] + ], + "type": "string" }, "justification": { @@ -2759,6 +2796,7 @@ "description": "A temporally ordered array of 'threadFlowLocation' objects, each of which describes a location visited by the tool while producing the result.", "type": "array", "minItems": 1, + "uniqueItems": false, "items": { "$ref": "#/definitions/threadFlowLocation" } @@ -2853,7 +2891,8 @@ "importance": { "description": "Specifies the importance of this location in understanding the code flow in which it occurs. The order from most to least important is \"essential\", \"important\", \"unimportant\". Default: \"important\".", "enum": [ "important", "essential", "unimportant" ], - "default": "important" + "default": "important", + "type": "string" }, "webRequest": { @@ -2911,7 +2950,7 @@ "properties": { "guid": { - "description": "A unique identifer for the tool component in the form of a GUID.", + "description": "A unique identifier for the tool component in the form of a GUID.", "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" }, @@ -3039,7 +3078,7 @@ "description": "The language of the messages emitted into the log file during this run (expressed as an ISO 639-1 two-letter lowercase language code) and an optional region (expressed as an ISO 3166-1 two-letter uppercase subculture code associated with a country or region). The casing is recommended but not required (in order for this data to conform to RFC5646).", "type": "string", "default": "en-US", - "pattern": "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$" + "pattern": "^(?i)[a-zA]{2}(-[a-z]{2})?$" }, "contents": { @@ -3051,7 +3090,8 @@ "enum": [ "localizedData", "nonLocalizedData" - ] + ], + "type": "string" } }, @@ -3346,4 +3386,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/upload-lib.ts b/src/upload-lib.ts index fe9652ab0..41d48aeae 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -225,8 +225,7 @@ export function countResultsInSarif(sarif: string): number { // Throws an error if the file is invalid. export function validateSarifFileSchema(sarifFilePath: string, logger: Logger) { const sarif = JSON.parse(fs.readFileSync(sarifFilePath, "utf8")); - const schema = - require("../src/sarif_v2.1.0_schema.json") as jsonschema.Schema; + const schema = require("../src/sarif-schema-2.1.0.json") as jsonschema.Schema; const result = new jsonschema.Validator().validate(sarif, schema); if (!result.valid) {