diff --git a/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll b/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll index 3891fcf13a1..4b4a31d6950 100644 --- a/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -239,12 +239,24 @@ private string getColumnString(TColumn column) { /** * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or - * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character - * must not be a digit), optionally followed by `=` and the expected value. + * more comma-separated tags optionally followed by `=` and the expected value. + * + * Tags must be only letters, digits, `-` and `_` (note that the first character + * must not be a digit), but can contain anything enclosed in a single set of + * square brackets. + * + * Examples: + * - `tag` + * - `tag=value` + * - `tag,tag2=value` + * - `tag[foo bar]=value` + * + * Not allowed: + * - `tag[[[foo bar]` */ private string expectationPattern() { exists(string tag, string tags, string value | - tag = "[A-Za-z-_][A-Za-z-_0-9]*" and + tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`. // For example, `b"foo"`. diff --git a/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll b/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll index 3891fcf13a1..4b4a31d6950 100644 --- a/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -239,12 +239,24 @@ private string getColumnString(TColumn column) { /** * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or - * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character - * must not be a digit), optionally followed by `=` and the expected value. + * more comma-separated tags optionally followed by `=` and the expected value. + * + * Tags must be only letters, digits, `-` and `_` (note that the first character + * must not be a digit), but can contain anything enclosed in a single set of + * square brackets. + * + * Examples: + * - `tag` + * - `tag=value` + * - `tag,tag2=value` + * - `tag[foo bar]=value` + * + * Not allowed: + * - `tag[[[foo bar]` */ private string expectationPattern() { exists(string tag, string tags, string value | - tag = "[A-Za-z-_][A-Za-z-_0-9]*" and + tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`. // For example, `b"foo"`. diff --git a/go/ql/test/TestUtilities/InlineExpectationsTest.qll b/go/ql/test/TestUtilities/InlineExpectationsTest.qll index 3891fcf13a1..4b4a31d6950 100644 --- a/go/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/go/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -239,12 +239,24 @@ private string getColumnString(TColumn column) { /** * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or - * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character - * must not be a digit), optionally followed by `=` and the expected value. + * more comma-separated tags optionally followed by `=` and the expected value. + * + * Tags must be only letters, digits, `-` and `_` (note that the first character + * must not be a digit), but can contain anything enclosed in a single set of + * square brackets. + * + * Examples: + * - `tag` + * - `tag=value` + * - `tag,tag2=value` + * - `tag[foo bar]=value` + * + * Not allowed: + * - `tag[[[foo bar]` */ private string expectationPattern() { exists(string tag, string tags, string value | - tag = "[A-Za-z-_][A-Za-z-_0-9]*" and + tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`. // For example, `b"foo"`. diff --git a/java/ql/test/TestUtilities/InlineExpectationsTest.qll b/java/ql/test/TestUtilities/InlineExpectationsTest.qll index 3891fcf13a1..4b4a31d6950 100644 --- a/java/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/java/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -239,12 +239,24 @@ private string getColumnString(TColumn column) { /** * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or - * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character - * must not be a digit), optionally followed by `=` and the expected value. + * more comma-separated tags optionally followed by `=` and the expected value. + * + * Tags must be only letters, digits, `-` and `_` (note that the first character + * must not be a digit), but can contain anything enclosed in a single set of + * square brackets. + * + * Examples: + * - `tag` + * - `tag=value` + * - `tag,tag2=value` + * - `tag[foo bar]=value` + * + * Not allowed: + * - `tag[[[foo bar]` */ private string expectationPattern() { exists(string tag, string tags, string value | - tag = "[A-Za-z-_][A-Za-z-_0-9]*" and + tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`. // For example, `b"foo"`. diff --git a/python/ql/test/TestUtilities/InlineExpectationsTest.qll b/python/ql/test/TestUtilities/InlineExpectationsTest.qll index 3891fcf13a1..4b4a31d6950 100644 --- a/python/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/python/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -239,12 +239,24 @@ private string getColumnString(TColumn column) { /** * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or - * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character - * must not be a digit), optionally followed by `=` and the expected value. + * more comma-separated tags optionally followed by `=` and the expected value. + * + * Tags must be only letters, digits, `-` and `_` (note that the first character + * must not be a digit), but can contain anything enclosed in a single set of + * square brackets. + * + * Examples: + * - `tag` + * - `tag=value` + * - `tag,tag2=value` + * - `tag[foo bar]=value` + * + * Not allowed: + * - `tag[[[foo bar]` */ private string expectationPattern() { exists(string tag, string tags, string value | - tag = "[A-Za-z-_][A-Za-z-_0-9]*" and + tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`. // For example, `b"foo"`. diff --git a/python/ql/test/experimental/meta/MaDTest.qll b/python/ql/test/experimental/meta/MaDTest.qll index 345fc973284..3d75ba0d2e7 100644 --- a/python/ql/test/experimental/meta/MaDTest.qll +++ b/python/ql/test/experimental/meta/MaDTest.qll @@ -11,7 +11,9 @@ class MadSinkTest extends InlineExpectationsTest { MadSinkTest() { this = "MadSinkTest" } override string getARelevantTag() { - exists(string kind | exists(ModelOutput::getASinkNode(kind)) | result = "mad-sink__" + kind) + exists(string kind | exists(ModelOutput::getASinkNode(kind)) | + result = "mad-sink[" + kind + "]" + ) } override predicate hasActualResult(Location location, string element, string tag, string value) { @@ -21,7 +23,7 @@ class MadSinkTest extends InlineExpectationsTest { location = sink.getLocation() and element = sink.toString() and value = prettyNodeForInlineTest(sink) and - tag = "mad-sink__" + kind + tag = "mad-sink[" + kind + "]" ) } } diff --git a/python/ql/test/library-tests/frameworks/asyncpg/test.py b/python/ql/test/library-tests/frameworks/asyncpg/test.py index e2e5e1c5826..ad99751ba3d 100644 --- a/python/ql/test/library-tests/frameworks/asyncpg/test.py +++ b/python/ql/test/library-tests/frameworks/asyncpg/test.py @@ -7,17 +7,17 @@ async def test_connection(): try: # The file-like object is passed in as a keyword-only argument. # See https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.connection.Connection.copy_from_query - await conn.copy_from_query("sql", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__path-injection="filepath" - await conn.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__path-injection="filepath" + await conn.copy_from_query("sql", output="filepath") # $ mad-sink[sql-injection]="sql" mad-sink[path-injection]="filepath" + await conn.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ mad-sink[sql-injection]="sql" mad-sink[path-injection]="filepath" - await conn.copy_from_table("table", output="filepath") # $ mad-sink__path-injection="filepath" - await conn.copy_to_table("table", source="filepath") # $ mad-sink__path-injection="filepath" + await conn.copy_from_table("table", output="filepath") # $ mad-sink[path-injection]="filepath" + await conn.copy_to_table("table", source="filepath") # $ mad-sink[path-injection]="filepath" - await conn.execute("sql") # $ mad-sink__sql-injection="sql" - await conn.executemany("sql") # $ mad-sink__sql-injection="sql" - await conn.fetch("sql") # $ mad-sink__sql-injection="sql" - await conn.fetchrow("sql") # $ mad-sink__sql-injection="sql" - await conn.fetchval("sql") # $ mad-sink__sql-injection="sql" + await conn.execute("sql") # $ mad-sink[sql-injection]="sql" + await conn.executemany("sql") # $ mad-sink[sql-injection]="sql" + await conn.fetch("sql") # $ mad-sink[sql-injection]="sql" + await conn.fetchrow("sql") # $ mad-sink[sql-injection]="sql" + await conn.fetchval("sql") # $ mad-sink[sql-injection]="sql" finally: await conn.close() @@ -27,7 +27,7 @@ async def test_prepared_statement(): conn = await asyncpg.connect() try: - pstmt = await conn.prepare("psql") # $ mad-sink__sql-injection="psql" + pstmt = await conn.prepare("psql") # $ mad-sink[sql-injection]="psql" pstmt.executemany() pstmt.fetch() pstmt.fetchrow() @@ -46,7 +46,7 @@ async def test_cursor(): cursor = await conn.cursor("sql") # $ getSql="sql" constructedSql="sql" await cursor.fetch() - pstmt = await conn.prepare("psql") # $ mad-sink__sql-injection="psql" + pstmt = await conn.prepare("psql") # $ mad-sink[sql-injection]="psql" pcursor = await pstmt.cursor() # $ getSql="psql" await pcursor.fetch() @@ -69,23 +69,23 @@ async def test_connection_pool(): pool = await asyncpg.create_pool() try: - await pool.copy_from_query("sql", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__path-injection="filepath" - await pool.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__path-injection="filepath" - await pool.copy_from_table("table", output="filepath") # $ mad-sink__path-injection="filepath" - await pool.copy_to_table("table", source="filepath") # $ mad-sink__path-injection="filepath" + await pool.copy_from_query("sql", output="filepath") # $ mad-sink[sql-injection]="sql" mad-sink[path-injection]="filepath" + await pool.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ mad-sink[sql-injection]="sql" mad-sink[path-injection]="filepath" + await pool.copy_from_table("table", output="filepath") # $ mad-sink[path-injection]="filepath" + await pool.copy_to_table("table", source="filepath") # $ mad-sink[path-injection]="filepath" - await pool.execute("sql") # $ mad-sink__sql-injection="sql" - await pool.executemany("sql") # $ mad-sink__sql-injection="sql" - await pool.fetch("sql") # $ mad-sink__sql-injection="sql" - await pool.fetchrow("sql") # $ mad-sink__sql-injection="sql" - await pool.fetchval("sql") # $ mad-sink__sql-injection="sql" + await pool.execute("sql") # $ mad-sink[sql-injection]="sql" + await pool.executemany("sql") # $ mad-sink[sql-injection]="sql" + await pool.fetch("sql") # $ mad-sink[sql-injection]="sql" + await pool.fetchrow("sql") # $ mad-sink[sql-injection]="sql" + await pool.fetchval("sql") # $ mad-sink[sql-injection]="sql" async with pool.acquire() as conn: - await conn.execute("sql") # $ mad-sink__sql-injection="sql" + await conn.execute("sql") # $ mad-sink[sql-injection]="sql" conn = await pool.acquire() try: - await conn.fetch("sql") # $ mad-sink__sql-injection="sql" + await conn.fetch("sql") # $ mad-sink[sql-injection]="sql" finally: await pool.release(conn) @@ -93,13 +93,13 @@ async def test_connection_pool(): await pool.close() async with asyncpg.create_pool() as pool: - await pool.execute("sql") # $ mad-sink__sql-injection="sql" + await pool.execute("sql") # $ mad-sink[sql-injection]="sql" async with pool.acquire() as conn: - await conn.execute("sql") # $ mad-sink__sql-injection="sql" + await conn.execute("sql") # $ mad-sink[sql-injection]="sql" conn = await pool.acquire() try: - await conn.fetch("sql") # $ mad-sink__sql-injection="sql" + await conn.fetch("sql") # $ mad-sink[sql-injection]="sql" finally: await pool.release(conn) diff --git a/ql/ql/test/TestUtilities/InlineExpectationsTest.qll b/ql/ql/test/TestUtilities/InlineExpectationsTest.qll index 3891fcf13a1..4b4a31d6950 100644 --- a/ql/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/ql/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -239,12 +239,24 @@ private string getColumnString(TColumn column) { /** * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or - * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character - * must not be a digit), optionally followed by `=` and the expected value. + * more comma-separated tags optionally followed by `=` and the expected value. + * + * Tags must be only letters, digits, `-` and `_` (note that the first character + * must not be a digit), but can contain anything enclosed in a single set of + * square brackets. + * + * Examples: + * - `tag` + * - `tag=value` + * - `tag,tag2=value` + * - `tag[foo bar]=value` + * + * Not allowed: + * - `tag[[[foo bar]` */ private string expectationPattern() { exists(string tag, string tags, string value | - tag = "[A-Za-z-_][A-Za-z-_0-9]*" and + tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`. // For example, `b"foo"`. diff --git a/ruby/ql/test/TestUtilities/InlineExpectationsTest.qll b/ruby/ql/test/TestUtilities/InlineExpectationsTest.qll index 3891fcf13a1..4b4a31d6950 100644 --- a/ruby/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/ruby/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -239,12 +239,24 @@ private string getColumnString(TColumn column) { /** * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or - * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character - * must not be a digit), optionally followed by `=` and the expected value. + * more comma-separated tags optionally followed by `=` and the expected value. + * + * Tags must be only letters, digits, `-` and `_` (note that the first character + * must not be a digit), but can contain anything enclosed in a single set of + * square brackets. + * + * Examples: + * - `tag` + * - `tag=value` + * - `tag,tag2=value` + * - `tag[foo bar]=value` + * + * Not allowed: + * - `tag[[[foo bar]` */ private string expectationPattern() { exists(string tag, string tags, string value | - tag = "[A-Za-z-_][A-Za-z-_0-9]*" and + tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`. // For example, `b"foo"`.