aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-12-16 11:22:50 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2024-12-16 11:22:50 -0500
commit7f4f49687b1f1b7aed0d6626b24f214e8a800439 (patch)
tree3eacd4d956d88e4e3fc59ea0f3c926477c1c55ed
parent2af541920787e333a25b6524e6b94200f128ba13 (diff)
downloadgcc-7f4f49687b1f1b7aed0d6626b24f214e8a800439.zip
gcc-7f4f49687b1f1b7aed0d6626b24f214e8a800439.tar.gz
gcc-7f4f49687b1f1b7aed0d6626b24f214e8a800439.tar.bz2
sarif-replay: handle embedded links (§3.11.6)
Handle embedded links in plain text messages. For now, merely use the link text and discard the destination. gcc/ChangeLog: * libsarifreplay.cc (struct embedded_link): New. (maybe_consume_embedded_link): New. (sarif_replayer::make_plain_text_within_result_message): Handle embedded links by using the link text, for now. gcc/testsuite/ChangeLog: * sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif: New test. * sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif: Update expected output for handling the embedded links. * sarif-replay.dg/2.1.0-valid/spec-example-4.sarif: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r--gcc/libsarifreplay.cc91
-rw-r--r--gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif25
-rw-r--r--gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif5
-rw-r--r--gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif2
4 files changed, 117 insertions, 6 deletions
diff --git a/gcc/libsarifreplay.cc b/gcc/libsarifreplay.cc
index f1374ec4..074ea90 100644
--- a/gcc/libsarifreplay.cc
+++ b/gcc/libsarifreplay.cc
@@ -1176,11 +1176,91 @@ maybe_consume_placeholder (const char *&iter_src, unsigned *out_arg_idx)
return false;
}
+struct embedded_link
+{
+ std::string text;
+ std::string destination;
+};
+
+/* If ITER_SRC starts with an embedded link as per §3.11.6, advance ITER_SRC
+ to immediately beyond the link, and return the link.
+
+ Otherwise, leave ITER_SRC untouched and return nullptr. */
+
+static std::unique_ptr<embedded_link>
+maybe_consume_embedded_link (const char *&iter_src)
+{
+ if (*iter_src != '[')
+ return nullptr;
+
+ /* This *might* be an embedded link.
+ See §3.11.6 ("Messages with embedded links") and
+ https://github.com/oasis-tcs/sarif-spec/issues/657 */
+
+ /* embedded link = "[", link text, "](", link destination, ")"; */
+
+ embedded_link result;
+
+ /* Try to get the link text. */
+ const char *iter = iter_src + 1;
+ while (char ch = *(iter++))
+ {
+ if (ch == '\\')
+ {
+ char next_ch = *iter;
+ switch (next_ch)
+ {
+ case '\\':
+ case '[':
+ case ']':
+ /* escaped link character = "\" | "[" | "]"; */
+ result.text += next_ch;
+ iter++;
+ continue;
+
+ default:
+ /* Malformed link text; assume this is not an
+ embedded link. */
+ return nullptr;
+ }
+ }
+ else if (ch == ']')
+ /* End of link text. */
+ break;
+ else
+ result.text += ch;
+ }
+
+ if (*iter++ != '(')
+ return nullptr;
+
+ /* Try to get the link destination. */
+ while (1)
+ {
+ char ch = *(iter++);
+ if (ch == '\0')
+ {
+ /* String ended before terminating ')'.
+ Assume this is not an embedded link. */
+ return nullptr;
+ }
+ else if (ch == ')')
+ /* Terminator. */
+ break;
+ else
+ result.destination += ch;
+ }
+
+ iter_src = iter;
+ return ::make_unique<embedded_link> (std::move (result));
+}
+
/* Lookup the plain text string within a result.message (§3.27.11),
- and substitute for any placeholders (§3.11.5).
+ and substitute for any placeholders (§3.11.5) and handle any
+ embedded links (§3.11.6).
Limitations:
- - we don't yet support embedded links
+ - we don't preserve destinations within embedded links
MESSAGE_OBJ is "theMessage"
RULE_OBJ is "theRule". */
@@ -1255,6 +1335,13 @@ make_plain_text_within_result_message (const json::object *tool_component_obj,
return label_text::borrow (nullptr);
}
}
+ else if (auto link = maybe_consume_embedded_link (iter_src))
+ {
+ accum += link->text;
+ /* TODO: use the destination. */
+ /* TODO: potentially could try to convert
+ intra-sarif links into event ids. */
+ }
else
{
accum += ch;
diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif
new file mode 100644
index 0000000..bc64521
--- /dev/null
+++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif
@@ -0,0 +1,25 @@
+{"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json",
+ "version": "2.1.0",
+ "runs": [{"tool": {"driver": {"name": "hand-written"}},
+ "results": [{"message": {"text": "001: this is a test"},
+ "locations": []},
+/* { dg-begin-multiline-output "" }
+hand-written: warning: 001: this is a test
+ { dg-end-multiline-output "" } */
+
+ /* Without the fix from https://github.com/oasis-tcs/sarif-spec/issues/656 */
+ {"message": {"text": "002: Prohibited term used in [para\\[0\\]\\\\spans\\[2\\](1)."},
+ "locations": []},
+/* { dg-begin-multiline-output "" }
+hand-written: warning: 002: Prohibited term used in [para\[0\]\\spans\[2\](1).
+ { dg-end-multiline-output "" } */
+
+ /* With the fix from https://github.com/oasis-tcs/sarif-spec/issues/656 */
+ {"message": {"text": "003: Prohibited term used in [para\\[0\\]\\\\spans\\[2\\]](1)."},
+ "locations": []}
+/* { dg-begin-multiline-output "" }
+hand-written: warning: 003: Prohibited term used in para[0]\spans[2].
+ { dg-end-multiline-output "" } */
+
+]}]}
+
diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif
index 5fd8e62..55c646b 100644
--- a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif
+++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif
@@ -334,7 +334,6 @@
"nestingLevel": 1,
"executionOrder": 5}]}]}]}]}]}
// TODO: show the CWEs
-// TODO: fix URL in message
/* { dg-begin-multiline-output "" }
In function 'callee_1':
@@ -372,7 +371,7 @@ In function 'callee_1':
| 5 | *ptr = 42;
| | ~~~~~~~~~~
| | |
- | | (7) ‘ptr’ could be NULL: unchecked value from [(4)](sarif:/runs/0/results/0/codeFlows/0/threadFlows/0/locations/3)
+ | | (7) ‘ptr’ could be NULL: unchecked value from (4)
|
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
@@ -398,5 +397,5 @@ In function 'test_2':
38 | free (ptr);
| ~~~~~~~~~~~
| |
- | (5) second ‘free’ here; first ‘free’ was at [(4)](sarif:/runs/0/results/1/codeFlows/0/threadFlows/0/locations/3)
+ | (5) second ‘free’ here; first ‘free’ was at (4)
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif
index 60c8731..27a0767 100644
--- a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif
+++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/spec-example-4.sarif
@@ -748,7 +748,7 @@
/* { dg-begin-multiline-output "" }
In function 'collections::list::add':
-collections/list.h:15:9: error: Variable "ptr" was used without being initialized. It was declared [here](0). [C2001]
+collections/list.h:15:9: error: Variable "ptr" was used without being initialized. It was declared here. [C2001]
events 1-3
......
{ dg-end-multiline-output "" } */