]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
SARIF output: fix schema URL [§3.13.3, PR116603]
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 9 Sep 2024 23:38:11 +0000 (19:38 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Mon, 9 Sep 2024 23:38:11 +0000 (19:38 -0400)
We were using
  https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json
as the URL for the SARIF 2.1 schema, but this is now a 404.

Update it to the URL listed in the spec (§3.13.3 "$schema property"),
which is:
  https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json
and update the copy in
  gcc/testsuite/lib/sarif-schema-2.1.0.json
used by the "verify-sarif-file" DejaGnu directive to the version found at
that latter URL; the sha256 sum changes
from: 2b19d2358baef0251d7d24e208d05ffabf1b2a3ab5e1b3a816066fc57fd4a7e8
  to: c3b4bb2d6093897483348925aaa73af03b3e3f4bd4ca38cef26dcb4212a2682e

Doing so added a validation error on
  c-c++-common/diagnostic-format-sarif-file-pr111700.c
for which we emit this textual output:
  this-file-does-not-exist.c: warning: #warning message [-Wcpp]
with no line number, and these invalid SARIF regions within the
physical location of the warning:
  "region": {"startColumn": 2,
             "endColumn": 9},
  "contextRegion": {}

This is due to this directive:
  # 0 "this-file-does-not-exist.c"
with line number 0.

The patch fixes this by not creating regions that have startLine <= 0.

gcc/ChangeLog:
PR other/116603
* diagnostic-format-sarif.cc (SARIF_SCHEMA): Update URL.
(sarif_builder::maybe_make_region_object): Don't create regions
with startLine <= 0.
(sarif_builder::maybe_make_region_object_for_context): Likewise.

gcc/testsuite/ChangeLog:
PR other/116603
* gcc.dg/plugin/diagnostic-test-metadata-sarif.py (test_basics):
Update expected schema URL.
* gcc.dg/plugin/diagnostic-test-paths-multithreaded-sarif.py:
Likewise.
* gcc.dg/sarif-output/test-include-chain-1.py: Likewise.
* gcc.dg/sarif-output/test-include-chain-2.py: Likewise.
* gcc.dg/sarif-output/test-missing-semicolon.py: Likewise.
* gcc.dg/sarif-output/test-no-diagnostics.py: Likewise.
* gcc.dg/sarif-output/test-werror.py: Likewise.
* lib/sarif-schema-2.1.0.json: Update with copy downloaded from
https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/diagnostic-format-sarif.cc
gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-sarif.py
gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-multithreaded-sarif.py
gcc/testsuite/gcc.dg/sarif-output/test-include-chain-1.py
gcc/testsuite/gcc.dg/sarif-output/test-include-chain-2.py
gcc/testsuite/gcc.dg/sarif-output/test-missing-semicolon.py
gcc/testsuite/gcc.dg/sarif-output/test-no-diagnostics.py
gcc/testsuite/gcc.dg/sarif-output/test-werror.py
gcc/testsuite/lib/sarif-schema-2.1.0.json

index 9d9e7ae607343eeb22641bd7e7795dad398e4c64..e95f18f31bda09f8dd0168821f59579e05360506 100644 (file)
@@ -2221,7 +2221,10 @@ sarif_builder::get_sarif_column (expanded_location exploc) const
    or return nullptr.
 
    If COLUMN_OVERRIDE is non-zero, then use it as the column number
-   if LOC has no column information.  */
+   if LOC has no column information.
+
+   We only support text properties of regions ("text regions"),
+   not binary properties ("binary regions"); see 3.30.1.  */
 
 std::unique_ptr<sarif_region>
 sarif_builder::maybe_make_region_object (location_t loc,
@@ -2244,11 +2247,16 @@ sarif_builder::maybe_make_region_object (location_t loc,
   if (exploc_finish.file !=exploc_caret.file)
     return nullptr;
 
+  /* We can have line == 0 in the presence of "#" lines.
+     SARIF requires lines > 0, so if we hit this case we don't have a
+     way of validly representing the region as SARIF; bail out.  */
+  if (exploc_start.line <= 0)
+    return nullptr;
+
   auto region_obj = ::make_unique<sarif_region> ();
 
   /* "startLine" property (SARIF v2.1.0 section 3.30.5) */
-  if (exploc_start.line > 0)
-    region_obj->set_integer ("startLine", exploc_start.line);
+  region_obj->set_integer ("startLine", exploc_start.line);
 
   /* "startColumn" property (SARIF v2.1.0 section 3.30.6).
 
@@ -2316,11 +2324,16 @@ maybe_make_region_object_for_context (location_t loc,
   if (exploc_finish.file !=exploc_caret.file)
     return nullptr;
 
+  /* We can have line == 0 in the presence of "#" lines.
+     SARIF requires lines > 0, so if we hit this case we don't have a
+     way of validly representing the region as SARIF; bail out.  */
+  if (exploc_start.line <= 0)
+    return nullptr;
+
   auto region_obj = ::make_unique<sarif_region> ();
 
   /* "startLine" property (SARIF v2.1.0 section 3.30.5) */
-  if (exploc_start.line > 0)
-    region_obj->set_integer ("startLine", exploc_start.line);
+  region_obj->set_integer ("startLine", exploc_start.line);
 
   /* "endLine" property (SARIF v2.1.0 section 3.30.7) */
   if (exploc_finish.line != exploc_start.line
@@ -2627,7 +2640,7 @@ sarif_builder::make_multiformat_message_string (const char *msg) const
   return message_obj;
 }
 
-#define SARIF_SCHEMA "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+#define SARIF_SCHEMA "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 #define SARIF_VERSION "2.1.0"
 
 /* Make a top-level "sarifLog" object (SARIF v2.1.0 section 3.13).  */
index 959e6f2e994224493312d546d7337ef0c40cb90f..2c3858786ecabcf524de780ec971dd422802fb22 100644 (file)
@@ -13,7 +13,7 @@ def sarif():
 
 def test_basics(sarif):
     schema = sarif['$schema']
-    assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 
     version = sarif['version']
     assert version == "2.1.0"
index cb00faf1532a57d74828fd07c0d4a814a63fde03..43d40cea372bc2bcac8a8f524a329a3b92d99457 100644 (file)
@@ -45,7 +45,7 @@ def sarif():
 
 def test_basics(sarif):
     schema = sarif['$schema']
-    assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 
     version = sarif['version']
     assert version == "2.1.0"
index 4bb2ebf614732c971efa2a3b140ceaf1125cd213..87e7627dcbd6db678cb5dc541e4b69b0fa7b7671 100644 (file)
@@ -8,7 +8,7 @@ def sarif():
 
 def test_basics(sarif):
     schema = sarif['$schema']
-    assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 
     version = sarif['version']
     assert version == "2.1.0"
index 843f89a948535811ffea8bbc314d18edafdd75e8..3671e8d7d8d3dce537a794579591eab11f736e95 100644 (file)
@@ -26,7 +26,7 @@ def sarif():
 
 def test_basics(sarif):
     schema = sarif['$schema']
-    assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 
     version = sarif['version']
     assert version == "2.1.0"
index 17759d35a468574caf4330dfd162696b6ea5bac7..58c0a7d02cd8cfa129be88ba3e8bc0a3d907b95b 100644 (file)
@@ -8,7 +8,7 @@ def sarif():
 
 def test_basics(sarif):
     schema = sarif['$schema']
-    assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 
     version = sarif['version']
     assert version == "2.1.0"
index f5812df17dc02804668a07df2a5d308fd46abb61..a3e052f100a0597fade96414b4c8dbd79af7c95a 100644 (file)
@@ -8,7 +8,7 @@ def sarif():
 
 def test_basics(sarif):
     schema = sarif['$schema']
-    assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 
     version = sarif['version']
     assert version == "2.1.0"
index 99c2c2c979190d5bd1eedad2989f9b67f65d00d9..291a26b55880e8201980ae68f851f07f490673dd 100644 (file)
@@ -8,7 +8,7 @@ def sarif():
 
 def test_basics(sarif):
     schema = sarif['$schema']
-    assert schema == "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
 
     version = sarif['version']
     assert version == "2.1.0"
index e0b652457104e3c59b6445d9e09110e1bca84826..0f58372b548f60c84d20fca77687435e71b3b3a3 100644 (file)
@@ -1,7 +1,7 @@
 {
-  "$schema": "http://json-schema.org/draft-07/schema#",
+  "$schema": "http://json-schema.org/draft-04/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",
+  "id": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/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.",
   "additionalProperties": false,
   "type": "object",
 
     "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": {
               "userSpecifiedConfiguration",
               "toolSpecifiedConfiguration",
               "debugOutputFile"
-            ]
+            ],
+            "type": "string"
           }
         },
 
 
         "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}$"
         },
         },
 
         "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}$"
         },
         "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": {
           "description": "Key/value pairs that provide additional information about the region.",
           "$ref": "#/definitions/propertyBag"
         }
-      }
+      },
+
+      "anyOf": [
+        { "required": [ "startLine" ] },
+        { "required": [ "charOffset" ] },
+        { "required": [ "byteOffset" ] }
+      ]
     },
 
     "replacement": {
         },
 
         "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}$"
         },
         "level": {
           "description": "Specifies the failure level for the report.",
           "default": "warning",
-          "enum": [ "none", "note", "warning", "error" ]
+          "enum": [ "none", "note", "warning", "error" ],
+          "type": "string"
         },
 
         "rank": {
         "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": {
         },
 
         "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}$"
         },
             "unchanged",
             "updated",
             "absent"
-          ]
+          ],
+          "type": "string"
         },
 
         "rank": {
           "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}-[a-zA-Z]{2}]?$"
+          "pattern": "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$"
         },
 
         "versionControlProvenance": {
 
         "columnKind": {
           "description": "Specifies the unit in which the tool measures columns.",
-          "enum": [ "utf16CodeUnits", "unicodeCodePoints" ]
+          "enum": [ "utf16CodeUnits", "unicodeCodePoints" ],
+          "type": "string"
         },
 
         "externalPropertyFileReferences": {
         },
 
         "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}$"
         },
       "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}$"
         },
           "enum": [
             "inSource",
             "external"
-          ]
+          ],
+          "type": "string"
         },
 
         "status": {
             "accepted",
             "underReview",
             "rejected"
-          ]
+          ],
+          "type": "string"
         },
 
         "justification": {
         "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": {
       "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}$"
         },
           "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}-[a-zA-Z]{2}]?$"
+          "pattern": "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$"
         },
 
         "contents": {
             "enum": [
               "localizedData",
               "nonLocalizedData"
-            ]
+            ],
+            "type": "string"
           }
         },