From 033cd1778e8ff9641978e1d264f41ca4ad38dcb0 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 8 Jan 2025 13:53:19 +0100 Subject: [PATCH 1/3] Rust: Include index in `Format.getArgument` --- rust/ql/.generated.list | 8 +++--- .../lib/codeql/rust/controlflow/CfgNodes.qll | 2 +- .../elements/internal/FormatArgumentImpl.qll | 10 +++++++ .../rust/elements/internal/FormatImpl.qll | 4 ++- .../elements/internal/generated/Format.qll | 13 +++++++--- .../internal/generated/ParentChild.qll | 5 ++-- .../generated/FormatArgsExpr/Format.expected | 22 ++++++++-------- .../generated/FormatArgsExpr/Format.ql | 7 ++--- .../Format_getArgument.expected | 26 +++++++++---------- .../FormatArgsExpr/Format_getArgument.ql | 4 +-- rust/schema/annotations.py | 2 +- 11 files changed, 61 insertions(+), 42 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 879592a5d75d..51a33e1fed32 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -521,7 +521,7 @@ lib/codeql/rust/elements/internal/generated/FieldList.qll 43c13c6e3c9ba75a7a4cb8 lib/codeql/rust/elements/internal/generated/FnPtrTypeRepr.qll d490ab9f2e3654d9abde18a06e534abd99ca62f518ca08670b696a97e9d5c592 01500319820f66cb4bbda6fe7c26270f76ea934efff4bb3cbf88e9b1e07e8be2 lib/codeql/rust/elements/internal/generated/ForExpr.qll 6c1838d952be65acaa9744736e73d9bfdcf58d7b392394223bf6fbfdcc172906 44237a248a5aa326a2544e84bc77f536f118f57a98c51562b71ddc81edfcccb8 lib/codeql/rust/elements/internal/generated/ForTypeRepr.qll 3027879795a6be5bfb370b8c2231b579f9df8afde54345416c6ce2c64bd3dfec f871d73b36f079f473915db298951020e5a05bb5e8e4d570822063afb4807559 -lib/codeql/rust/elements/internal/generated/Format.qll b1c2ce8dc4ee3cee9f637a007aa3d282e2001c754207604c8c4412ed94a20b4b 880e43fdaadae50e8b0e87ccaab93122d48cdbf73c612cbbd748ccacb91ea5a7 +lib/codeql/rust/elements/internal/generated/Format.qll 26f1d63bddf120ef203353bb543a091c1d72dc076f22941cf6b8ba12145f975a 4ce7138b1e221de045ffd1cdcecaad39ee70231402012bded9fa784cd152e1e7 lib/codeql/rust/elements/internal/generated/FormatArgsArg.qll c762a4af8609472e285dd1b1aec8251421aec49f8d0e5ce9df2cc5e2722326f8 c8c226b94b32447634b445c62bd9af7e11b93a706f8fa35d2de4fda3ce951926 lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll 8aed8715a27d3af3de56ded4610c6792a25216b1544eb7e57c8b0b37c14bd9c1 590a2b0063d2ecd00bbbd1ce29603c8fd69972e34e6daddf309c915ce4ec1375 lib/codeql/rust/elements/internal/generated/FormatArgument.qll cd05153276e63e689c95d5537fbc7d892615f62e110323759ef02e23a7587407 be2a4531b498f01625effa4c631d51ee8857698b00cfb829074120a0f2696d57 @@ -579,7 +579,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll 4f168ef5d5bb87a903251cc31b2e44a759b099ec69c90af31783fbb15778c940 0e34f94a45a13396fd57d94c245dc64d1adde2ab0e22b56946f7e94c04e297fc lib/codeql/rust/elements/internal/generated/ParenTypeRepr.qll 40ab5c592e7699c621787793743e33988de71ff42ca27599f5ab3ddb70e3f7d8 12c0a6eed2202ee3e892f61da3b3ce77ac3190854cdf3097e8d2be98aa3cb91d -lib/codeql/rust/elements/internal/generated/ParentChild.qll 668b9079bcb7a055b956cfff94930ba59a7d88d59a95284dd93bd146c4c73d22 60ffda092345f862082b0b61a052b7fad12b4b6431d23794ff2ba3cfd334bd93 +lib/codeql/rust/elements/internal/generated/ParentChild.qll d54053ecf258b0d531482bea7924995677d2a7e02bbc8caa5ba5b89a61be49ec 2ea71ef5e2e8dd8c3a9f95ef7a0e083fd213f7c2630afa17943ee856663e1a5e lib/codeql/rust/elements/internal/generated/ParenthesizedArgList.qll c5fa328ea60d3a3333d7c7bb3480969c1873166c7ac8ebb9d0afad7a8099d1a8 2dbbb6200d96f7db7dea4a55bdeab8d67b14d39a43e0bd54ada019f7e466f163 lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll bf6a86e7fcb7164624cc070dcce86d2bda50a2516b95115b87d0ebb5596e50a1 fd7a9ad4034cdebe8dfe495619c46f464630d38195313072e0bd904061b0fb00 @@ -801,7 +801,7 @@ test/extractor-tests/generated/ForExpr/ForExpr_getPat.ql 1e0205a9b3a58fd2ddba49e test/extractor-tests/generated/ForTypeRepr/ForTypeRepr.ql 38fa18958dc8c1564abf0c38ebc7e76bc64904f9774a99e46504f903e9c19379 8384e007868981dcd8120f4ef52475ca99641a530a487cd9dc7eba98b9391060 test/extractor-tests/generated/ForTypeRepr/ForTypeRepr_getGenericParamList.ql 33535c02c7000e89e4d4e4560499b9512455fae407e72e05615b38f9e950c6bf 35a6aa7de0f627fb96ca7f4f2134b060a820327a3de4970fa2790c8fbea28a2c test/extractor-tests/generated/ForTypeRepr/ForTypeRepr_getTypeRepr.ql f24d02c57af9f4fb4f5c3058e236a8d9b4c4f6f2aff84e65497f693309bdf93e 1c93d6214ee0a89e2bd5d0e02800e29e8a14ebd7efdb6a62380edb97dc902def -test/extractor-tests/generated/FormatArgsExpr/Format.ql 25268dd7ad2a58b071c3a38164944c1b7389dfdda01c99ef2694a475596341b4 0a3f674d5a4f005835b9a5ba11a6e8bf58477829258f30ae7d8f76f8986f7b7f +test/extractor-tests/generated/FormatArgsExpr/Format.ql 975867ea65a95ca49ebaa55b634fd3f885b64ffdd07bda48a3a07367e56f7d4d 04d90ee86312501c1560b4679c45408a42c55f490f700864696c06a980f008de test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.ql a521903c73f79e2616f7b8ef76790e11cbf432f8437825d52d117da232022b9e 4cb195d09ecb51e5bbd5c1c069ec1720f74fc074efc88b0f5c07cfc140167775 test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.ql 7e1a7f902fb661660760d2a2f3f4cb6818a0c9f5b5061ede6ae80223774e4e09 8a50f64cba6f56320631206c801160201e3c98e74367bb035d689baaa9b4e411 test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.ql 0e2f24388d516e14d195957163a2d5d97029c9e11a83ca71cf69e00ecc0bb2a8 dab2969f5ae6a15ec331c0152e7c116d1ee2c3d073b2d4da59ffbcb83404c65f @@ -813,7 +813,7 @@ test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.ql c912 test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql 7a7ee3a3322b4af8cb3b525cfed8cc9719d136ea80aa6b3fb30c7e16394dd93f 5aa8a77d7741b02f8ceb9e5991efa4c2c43c6f1624989218990e985108dae535 test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql 7bd4ec3dde2ef0463585794101e6cc426c368b0e4ab95fbb1f24f8f0a76cf471 e7b01e8b21df5b22c51643e2c909c6fc4ca96fda41b3290c907ba228abe8669b test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql 2793ba1ff52182dab992d82d3767a000928f6b2fbfdb621349cafc183f0d2480 c3777d03214f7feb9020de3ce45af6556129e39e9b30d083de605b70ab9a0a12 -test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql 26d592398a17795427b5b6b51ff4a013ee15c31443e732a000baca5f2e65acca 7940a864b84b89e84d7fb186599cb8b6bcbead7141c592b8ab0c59fcd380d5fb +test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql 90eb75e0186eff7105477b68c60e8d33a1a2e27e0f880a52e9dfa65d9cce6e3f c6dbc117c3ef2e04162125f4da6b8f25931eaf36825534902cee0fa704c99b56 test/extractor-tests/generated/Function/Function.ql c1c2a9b68c35f839ccd2b5e62e87d1acd94dcc2a3dc4c307c269b84b2a0806e6 1c446f19d2f81dd139aa5a1578d1b165e13bddbaeab8cfee8f0430bced3a99ab test/extractor-tests/generated/Function/Function_getAbi.ql e5c9c97de036ddd51cae5d99d41847c35c6b2eabbbd145f4467cb501edc606d8 0b81511528bd0ef9e63b19edfc3cb638d8af43eb87d018fad69d6ef8f8221454 test/extractor-tests/generated/Function/Function_getAttr.ql 44067ee11bdec8e91774ff10de0704a8c5c1b60816d587378e86bf3d82e1f660 b4bebf9441bda1f2d1e34e9261e07a7468cbabf53cf8047384f3c8b11869f04e diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index 0153f7a88e00..6ee6f490061e 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -196,7 +196,7 @@ final class FormatArgsExprCfgNode extends Nodes::FormatArgsExprCfgNode { /** Gets a format argument of the `i`th format of this format arguments expression (0-based). */ FormatTemplateVariableAccessCfgNode getFormatTemplateVariableAccess(int i) { exists(FormatTemplateVariableAccess v | - v.getArgument() = node.getFormat(i).getArgument() and + v.getArgument() = node.getFormat(i).getArgument(_) and result.getFormatTemplateVariableAccess() = v and any(ChildMapping mapping).hasCfgChild(node, v, this, result) ) diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll index 6719d9d8cb3c..90b15addb21c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll @@ -40,6 +40,16 @@ module Impl { override Format getParent() { result = Synth::TFormat(parent, index, _, _) } + /** Gets the position of this argument. */ + int getPosition() { + this = + rank[result + 1](FormatArgument f, int offs | + f = Synth::TFormatArgument(parent, index, _, _, _, offs) + | + f order by offs + ) + } + override FormatTemplateVariableAccess getVariable() { result.getArgument() = this } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll index 19fd59db0040..b5f1bed8d652 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll @@ -42,7 +42,9 @@ module Impl { override int getIndex() { result = index } - override FormatArgument getArgument() { result.getParent() = this } + override FormatArgument getArgument(int i) { + result.getParent() = this and i = result.getPosition() + } /** * Gets the name or position reference of this format, if any. For example `name` and `0` in: diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll index 9c5ba12ab7a3..e552e657f720 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll @@ -41,13 +41,18 @@ module Generated { int getIndex() { none() } /** - * Gets the argument of this format, if it exists. + * Gets the `index`th argument of this format (0-based). */ - FormatArgument getArgument() { none() } + FormatArgument getArgument(int index) { none() } /** - * Holds if `getArgument()` exists. + * Gets any of the arguments of this format. */ - final predicate hasArgument() { exists(this.getArgument()) } + final FormatArgument getAnArgument() { result = this.getArgument(_) } + + /** + * Gets the number of arguments of this format. + */ + final int getNumberOfArguments() { result = count(int i | exists(this.getArgument(i))) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index f2f2f41ae38f..5a230898a7a8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -73,13 +73,14 @@ private module Impl { b = 0 and bLocatable = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocatable(e, i, _)) | i) and n = bLocatable and - nArgument = n + 1 and + nArgument = n + 1 + max(int i | i = -1 or exists(e.getArgument(i)) | i) and ( none() or result = getImmediateChildOfLocatable(e, index - b, partialPredicateCall) or - index = n and result = e.getArgument() and partialPredicateCall = "Argument()" + result = e.getArgument(index - n) and + partialPredicateCall = "Argument(" + (index - n).toString() + ")" ) ) } diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected index 499561ff9e6d..a4fe0acc9061 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected @@ -1,11 +1,11 @@ -| gen_format.rs:5:21:5:22 | {} | getParent: | gen_format.rs:5:14:5:32 | FormatArgsExpr | getIndex: | 1 | hasArgument: | no | -| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | getParent: | gen_format.rs:7:14:7:47 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | -| gen_format_args_arg.rs:5:26:5:27 | {} | getParent: | gen_format_args_arg.rs:5:17:5:39 | FormatArgsExpr | getIndex: | 1 | hasArgument: | no | -| gen_format_args_expr.rs:6:19:6:20 | {} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 1 | hasArgument: | no | -| gen_format_args_expr.rs:6:26:6:29 | {:?} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 3 | hasArgument: | no | -| gen_format_args_expr.rs:7:19:7:21 | {b} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | -| gen_format_args_expr.rs:7:27:7:31 | {a:?} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 3 | hasArgument: | yes | -| gen_format_args_expr.rs:9:19:9:21 | {x} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | -| gen_format_args_expr.rs:9:24:9:26 | {y} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 3 | hasArgument: | yes | -| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | getParent: | gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | -| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | getParent: | gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | getIndex: | 1 | hasArgument: | yes | +| gen_format.rs:5:21:5:22 | {} | getParent: | gen_format.rs:5:14:5:32 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 0 | +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | getParent: | gen_format.rs:7:14:7:47 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 3 | +| gen_format_args_arg.rs:5:26:5:27 | {} | getParent: | gen_format_args_arg.rs:5:17:5:39 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 0 | +| gen_format_args_expr.rs:6:19:6:20 | {} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 0 | +| gen_format_args_expr.rs:6:26:6:29 | {:?} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 3 | getNumberOfArguments: | 0 | +| gen_format_args_expr.rs:7:19:7:21 | {b} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 1 | +| gen_format_args_expr.rs:7:27:7:31 | {a:?} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 3 | getNumberOfArguments: | 1 | +| gen_format_args_expr.rs:9:19:9:21 | {x} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 1 | +| gen_format_args_expr.rs:9:24:9:26 | {y} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 3 | getNumberOfArguments: | 1 | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | getParent: | gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 3 | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | getParent: | gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 3 | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql index fa17b4294f7e..85b7d992af9f 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql @@ -2,11 +2,12 @@ import codeql.rust.elements import TestUtils -from Format x, FormatArgsExpr getParent, int getIndex, string hasArgument +from Format x, FormatArgsExpr getParent, int getIndex, int getNumberOfArguments where toBeTested(x) and not x.isUnknown() and getParent = x.getParent() and getIndex = x.getIndex() and - if x.hasArgument() then hasArgument = "yes" else hasArgument = "no" -select x, "getParent:", getParent, "getIndex:", getIndex, "hasArgument:", hasArgument + getNumberOfArguments = x.getNumberOfArguments() +select x, "getParent:", getParent, "getIndex:", getIndex, "getNumberOfArguments:", + getNumberOfArguments diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected index 251598222279..8bd957fa8df7 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.expected @@ -1,13 +1,13 @@ -| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | gen_format.rs:7:22:7:26 | value | -| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | gen_format.rs:7:29:7:33 | width | -| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | gen_format.rs:7:36:7:44 | precision | -| gen_format_args_expr.rs:7:19:7:21 | {b} | gen_format_args_expr.rs:7:20:7:20 | b | -| gen_format_args_expr.rs:7:27:7:31 | {a:?} | gen_format_args_expr.rs:7:28:7:28 | a | -| gen_format_args_expr.rs:9:19:9:21 | {x} | gen_format_args_expr.rs:9:20:9:20 | x | -| gen_format_args_expr.rs:9:24:9:26 | {y} | gen_format_args_expr.rs:9:25:9:25 | y | -| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:22:5:26 | value | -| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:29:5:33 | width | -| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:36:5:44 | precision | -| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:22:7:22 | 0 | -| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:25:7:25 | 1 | -| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:28:7:28 | 2 | +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | 0 | gen_format.rs:7:22:7:26 | value | +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | 1 | gen_format.rs:7:29:7:33 | width | +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | 2 | gen_format.rs:7:36:7:44 | precision | +| gen_format_args_expr.rs:7:19:7:21 | {b} | 0 | gen_format_args_expr.rs:7:20:7:20 | b | +| gen_format_args_expr.rs:7:27:7:31 | {a:?} | 0 | gen_format_args_expr.rs:7:28:7:28 | a | +| gen_format_args_expr.rs:9:19:9:21 | {x} | 0 | gen_format_args_expr.rs:9:20:9:20 | x | +| gen_format_args_expr.rs:9:24:9:26 | {y} | 0 | gen_format_args_expr.rs:9:25:9:25 | y | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | 0 | gen_format_argument.rs:5:22:5:26 | value | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | 1 | gen_format_argument.rs:5:29:5:33 | width | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | 2 | gen_format_argument.rs:5:36:5:44 | precision | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | 0 | gen_format_argument.rs:7:22:7:22 | 0 | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | 1 | gen_format_argument.rs:7:25:7:25 | 1 | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | 2 | gen_format_argument.rs:7:28:7:28 | 2 | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql index e131365770b6..33738ee81ef6 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql @@ -2,6 +2,6 @@ import codeql.rust.elements import TestUtils -from Format x +from Format x, int index where toBeTested(x) and not x.isUnknown() -select x, x.getArgument() +select x, index, x.getArgument(index) diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index eece1cc85d62..bd539335a4eb 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1878,7 +1878,7 @@ class Format(Locatable): """ parent: FormatArgsExpr index: int - argument: optional["FormatArgument"] | child + argument: list["FormatArgument"] | child @synth.on_arguments(parent=FormatArgsExpr, index=int, kind=int, name=string, positional=boolean, offset=int) From 0dccbb9349a06f9803957f7502a7e9501b961cf1 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 8 Jan 2025 14:16:46 +0100 Subject: [PATCH 2/3] Rust: Add two more AST consistency checks --- rust/ql/lib/codeql/rust/AstConsistency.qll | 27 +++++++++++++++++++ .../diagnostics/AstConsistencyCounts.expected | 2 ++ 2 files changed, 29 insertions(+) diff --git a/rust/ql/lib/codeql/rust/AstConsistency.qll b/rust/ql/lib/codeql/rust/AstConsistency.qll index 2358bddb3b9d..0c9359d6569c 100644 --- a/rust/ql/lib/codeql/rust/AstConsistency.qll +++ b/rust/ql/lib/codeql/rust/AstConsistency.qll @@ -52,6 +52,27 @@ query predicate multipleParents(Element child, string childClass, Element parent parentClass = parent.getPrimaryQlClasses() } +/** Holds if `parent` has multiple children at the same index. */ +query predicate multipleChildren(Element parent, int index, Element child1, Element child2) { + child1 = getChildAndAccessor(parent, index, _) and + child2 = getChildAndAccessor(parent, index, _) and + child1 != child2 +} + +/** + * Holds if `child` has multiple positions amongst the `accessor` children + * of `parent`. + * + * Children are allowed to have multiple positions for _different_ accessors, + * for example in an array repeat expression `[1; 10]`, `1` has positions for + * both `getRepeatOperand()` and `getExpr()`. + */ +query predicate multiplePositions(Element parent, int pos1, int pos2, string accessor, Element child) { + child = getChildAndAccessor(parent, pos1, accessor) and + child = getChildAndAccessor(parent, pos2, accessor) and + pos1 != pos2 +} + /** * Gets counts of abstract syntax tree inconsistencies of each type. */ @@ -71,4 +92,10 @@ int getAstInconsistencyCounts(string type) { or type = "Multiple parents" and result = count(Element e | multipleParents(e) | e) + or + type = "Multiple children" and + result = count(Element e | multipleChildren(_, _, e, _) | e) + or + type = "Multiple positions" and + result = count(Element e | multiplePositions(_, _, _, _, e) | e) } diff --git a/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected b/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected index 72147226e42b..7f8d388fdc50 100644 --- a/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected +++ b/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected @@ -1,5 +1,7 @@ +| Multiple children | 0 | | Multiple locations | 0 | | Multiple parents | 0 | +| Multiple positions | 0 | | Multiple primary QL classes | 0 | | Multiple toStrings | 0 | | No location | 0 | From 166f8916cc7dcb896ce4a871dfbbb047f7ff443d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 10 Jan 2025 12:51:00 +0100 Subject: [PATCH 3/3] Rust: Remove `Format.getArgument` --- rust/ql/.generated.list | 10 ++++--- rust/ql/.gitattributes | 4 ++- .../lib/codeql/rust/controlflow/CfgNodes.qll | 5 ++-- .../elements/internal/FormatArgumentImpl.qll | 10 ------- .../rust/elements/internal/FormatImpl.qll | 10 +++---- .../elements/internal/generated/Format.qll | 27 ++++++++++++++----- .../internal/generated/ParentChild.qll | 19 ++++++++++--- .../generated/FormatArgsExpr/Format.expected | 22 +++++++-------- .../generated/FormatArgsExpr/Format.ql | 12 ++++++--- .../Format_getArgumentRef.expected | 7 +++++ ...etArgument.ql => Format_getArgumentRef.ql} | 4 +-- .../Format_getPrecisionArgument.expected | 3 +++ .../Format_getPrecisionArgument.ql | 7 +++++ .../Format_getWidthArgument.expected | 3 +++ .../FormatArgsExpr/Format_getWidthArgument.ql | 7 +++++ rust/schema/annotations.py | 4 ++- 16 files changed, 102 insertions(+), 52 deletions(-) create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.expected rename rust/ql/test/extractor-tests/generated/FormatArgsExpr/{Format_getArgument.ql => Format_getArgumentRef.ql} (66%) create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.ql create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.expected create mode 100644 rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.ql diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 51a33e1fed32..761091ef6b46 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -521,7 +521,7 @@ lib/codeql/rust/elements/internal/generated/FieldList.qll 43c13c6e3c9ba75a7a4cb8 lib/codeql/rust/elements/internal/generated/FnPtrTypeRepr.qll d490ab9f2e3654d9abde18a06e534abd99ca62f518ca08670b696a97e9d5c592 01500319820f66cb4bbda6fe7c26270f76ea934efff4bb3cbf88e9b1e07e8be2 lib/codeql/rust/elements/internal/generated/ForExpr.qll 6c1838d952be65acaa9744736e73d9bfdcf58d7b392394223bf6fbfdcc172906 44237a248a5aa326a2544e84bc77f536f118f57a98c51562b71ddc81edfcccb8 lib/codeql/rust/elements/internal/generated/ForTypeRepr.qll 3027879795a6be5bfb370b8c2231b579f9df8afde54345416c6ce2c64bd3dfec f871d73b36f079f473915db298951020e5a05bb5e8e4d570822063afb4807559 -lib/codeql/rust/elements/internal/generated/Format.qll 26f1d63bddf120ef203353bb543a091c1d72dc076f22941cf6b8ba12145f975a 4ce7138b1e221de045ffd1cdcecaad39ee70231402012bded9fa784cd152e1e7 +lib/codeql/rust/elements/internal/generated/Format.qll 89a0bbeba8288ca52440dadcbb2f4c58e01cbbb000a9e94dfe2e0d272361d89b bf8099688eed34b2bf4e19b613187a64a5d82b2524e053149adb6891350d143c lib/codeql/rust/elements/internal/generated/FormatArgsArg.qll c762a4af8609472e285dd1b1aec8251421aec49f8d0e5ce9df2cc5e2722326f8 c8c226b94b32447634b445c62bd9af7e11b93a706f8fa35d2de4fda3ce951926 lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll 8aed8715a27d3af3de56ded4610c6792a25216b1544eb7e57c8b0b37c14bd9c1 590a2b0063d2ecd00bbbd1ce29603c8fd69972e34e6daddf309c915ce4ec1375 lib/codeql/rust/elements/internal/generated/FormatArgument.qll cd05153276e63e689c95d5537fbc7d892615f62e110323759ef02e23a7587407 be2a4531b498f01625effa4c631d51ee8857698b00cfb829074120a0f2696d57 @@ -579,7 +579,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll 4f168ef5d5bb87a903251cc31b2e44a759b099ec69c90af31783fbb15778c940 0e34f94a45a13396fd57d94c245dc64d1adde2ab0e22b56946f7e94c04e297fc lib/codeql/rust/elements/internal/generated/ParenTypeRepr.qll 40ab5c592e7699c621787793743e33988de71ff42ca27599f5ab3ddb70e3f7d8 12c0a6eed2202ee3e892f61da3b3ce77ac3190854cdf3097e8d2be98aa3cb91d -lib/codeql/rust/elements/internal/generated/ParentChild.qll d54053ecf258b0d531482bea7924995677d2a7e02bbc8caa5ba5b89a61be49ec 2ea71ef5e2e8dd8c3a9f95ef7a0e083fd213f7c2630afa17943ee856663e1a5e +lib/codeql/rust/elements/internal/generated/ParentChild.qll 738612c1ec404fe8c090e0d234bdac4ce207bd0d4cad699a2981e6b6cb8947a9 df002e5540bfe5de4e6849879f334b09c2ffb4893ff8364146c6c505f4b2d090 lib/codeql/rust/elements/internal/generated/ParenthesizedArgList.qll c5fa328ea60d3a3333d7c7bb3480969c1873166c7ac8ebb9d0afad7a8099d1a8 2dbbb6200d96f7db7dea4a55bdeab8d67b14d39a43e0bd54ada019f7e466f163 lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll bf6a86e7fcb7164624cc070dcce86d2bda50a2516b95115b87d0ebb5596e50a1 fd7a9ad4034cdebe8dfe495619c46f464630d38195313072e0bd904061b0fb00 @@ -801,7 +801,7 @@ test/extractor-tests/generated/ForExpr/ForExpr_getPat.ql 1e0205a9b3a58fd2ddba49e test/extractor-tests/generated/ForTypeRepr/ForTypeRepr.ql 38fa18958dc8c1564abf0c38ebc7e76bc64904f9774a99e46504f903e9c19379 8384e007868981dcd8120f4ef52475ca99641a530a487cd9dc7eba98b9391060 test/extractor-tests/generated/ForTypeRepr/ForTypeRepr_getGenericParamList.ql 33535c02c7000e89e4d4e4560499b9512455fae407e72e05615b38f9e950c6bf 35a6aa7de0f627fb96ca7f4f2134b060a820327a3de4970fa2790c8fbea28a2c test/extractor-tests/generated/ForTypeRepr/ForTypeRepr_getTypeRepr.ql f24d02c57af9f4fb4f5c3058e236a8d9b4c4f6f2aff84e65497f693309bdf93e 1c93d6214ee0a89e2bd5d0e02800e29e8a14ebd7efdb6a62380edb97dc902def -test/extractor-tests/generated/FormatArgsExpr/Format.ql 975867ea65a95ca49ebaa55b634fd3f885b64ffdd07bda48a3a07367e56f7d4d 04d90ee86312501c1560b4679c45408a42c55f490f700864696c06a980f008de +test/extractor-tests/generated/FormatArgsExpr/Format.ql 6fa117eebe7ec99b71ffd10cf2cb2a21e67ab157f7c08feedabcc9bcc5390dce 9e7681c3bff55ed78d43ba6567f85bb98da6b166358951b1e972de1114750009 test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg.ql a521903c73f79e2616f7b8ef76790e11cbf432f8437825d52d117da232022b9e 4cb195d09ecb51e5bbd5c1c069ec1720f74fc074efc88b0f5c07cfc140167775 test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getExpr.ql 7e1a7f902fb661660760d2a2f3f4cb6818a0c9f5b5061ede6ae80223774e4e09 8a50f64cba6f56320631206c801160201e3c98e74367bb035d689baaa9b4e411 test/extractor-tests/generated/FormatArgsExpr/FormatArgsArg_getName.ql 0e2f24388d516e14d195957163a2d5d97029c9e11a83ca71cf69e00ecc0bb2a8 dab2969f5ae6a15ec331c0152e7c116d1ee2c3d073b2d4da59ffbcb83404c65f @@ -813,7 +813,9 @@ test/extractor-tests/generated/FormatArgsExpr/FormatArgsExpr_getTemplate.ql c912 test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql 7a7ee3a3322b4af8cb3b525cfed8cc9719d136ea80aa6b3fb30c7e16394dd93f 5aa8a77d7741b02f8ceb9e5991efa4c2c43c6f1624989218990e985108dae535 test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql 7bd4ec3dde2ef0463585794101e6cc426c368b0e4ab95fbb1f24f8f0a76cf471 e7b01e8b21df5b22c51643e2c909c6fc4ca96fda41b3290c907ba228abe8669b test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql 2793ba1ff52182dab992d82d3767a000928f6b2fbfdb621349cafc183f0d2480 c3777d03214f7feb9020de3ce45af6556129e39e9b30d083de605b70ab9a0a12 -test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql 90eb75e0186eff7105477b68c60e8d33a1a2e27e0f880a52e9dfa65d9cce6e3f c6dbc117c3ef2e04162125f4da6b8f25931eaf36825534902cee0fa704c99b56 +test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.ql 634efdffaae4199aa9d95652cf081a8dc26e88224e24678845f8a67dc24ce090 d0302fee5c50403214771d5c6b896ba7c6e52be10c9bea59720ef2bb954e6f40 +test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.ql 0d2140f84d0220b0c72c48c6bd272f4cfe1863d1797eddd16a6e238552a61e4d f4fe9b29697041e30764fa3dea44f125546bfb648f32c3474a1e922a4255c534 +test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.ql 01ef27dd0bfab273e1ddc57ada0e079ece8a2bfd195ce413261006964b444093 acd0161f86010759417015c5b58044467a7f760f288ec4e8525458c54ae9a715 test/extractor-tests/generated/Function/Function.ql c1c2a9b68c35f839ccd2b5e62e87d1acd94dcc2a3dc4c307c269b84b2a0806e6 1c446f19d2f81dd139aa5a1578d1b165e13bddbaeab8cfee8f0430bced3a99ab test/extractor-tests/generated/Function/Function_getAbi.ql e5c9c97de036ddd51cae5d99d41847c35c6b2eabbbd145f4467cb501edc606d8 0b81511528bd0ef9e63b19edfc3cb638d8af43eb87d018fad69d6ef8f8221454 test/extractor-tests/generated/Function/Function_getAttr.ql 44067ee11bdec8e91774ff10de0704a8c5c1b60816d587378e86bf3d82e1f660 b4bebf9441bda1f2d1e34e9261e07a7468cbabf53cf8047384f3c8b11869f04e diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index abc044d11208..9c11869fb8dd 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -815,7 +815,9 @@ /test/extractor-tests/generated/FormatArgsExpr/FormatArgument.ql linguist-generated /test/extractor-tests/generated/FormatArgsExpr/FormatArgument_getVariable.ql linguist-generated /test/extractor-tests/generated/FormatArgsExpr/FormatTemplateVariableAccess.ql linguist-generated -/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.ql linguist-generated +/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.ql linguist-generated /test/extractor-tests/generated/Function/Function.ql linguist-generated /test/extractor-tests/generated/Function/Function_getAbi.ql linguist-generated /test/extractor-tests/generated/Function/Function_getAttr.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index 6ee6f490061e..2aad9473624d 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -195,8 +195,9 @@ final class FormatArgsExprCfgNode extends Nodes::FormatArgsExprCfgNode { /** Gets a format argument of the `i`th format of this format arguments expression (0-based). */ FormatTemplateVariableAccessCfgNode getFormatTemplateVariableAccess(int i) { - exists(FormatTemplateVariableAccess v | - v.getArgument() = node.getFormat(i).getArgument(_) and + exists(FormatTemplateVariableAccess v, Format f | + f = node.getFormat(i) and + v.getArgument() = [f.getArgumentRef(), f.getWidthArgument(), f.getPrecisionArgument()] and result.getFormatTemplateVariableAccess() = v and any(ChildMapping mapping).hasCfgChild(node, v, this, result) ) diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll index 90b15addb21c..6719d9d8cb3c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatArgumentImpl.qll @@ -40,16 +40,6 @@ module Impl { override Format getParent() { result = Synth::TFormat(parent, index, _, _) } - /** Gets the position of this argument. */ - int getPosition() { - this = - rank[result + 1](FormatArgument f, int offs | - f = Synth::TFormatArgument(parent, index, _, _, _, offs) - | - f order by offs - ) - } - override FormatTemplateVariableAccess getVariable() { result.getArgument() = this } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll index b5f1bed8d652..f59dfb8296a7 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll @@ -42,10 +42,6 @@ module Impl { override int getIndex() { result = index } - override FormatArgument getArgument(int i) { - result.getParent() = this and i = result.getPosition() - } - /** * Gets the name or position reference of this format, if any. For example `name` and `0` in: * ```rust @@ -54,7 +50,7 @@ module Impl { * println!("{0} in wonderland", name); * ``` */ - FormatArgument getArgumentRef() { + override FormatArgument getArgumentRef() { result.getParent() = this and result = Synth::TFormatArgument(_, _, 0, _, _, _) } @@ -66,7 +62,7 @@ module Impl { * println!("{:1$}", PI, width); * ``` */ - FormatArgument getWidthArgument() { + override FormatArgument getWidthArgument() { result.getParent() = this and result = Synth::TFormatArgument(_, _, 1, _, _, _) } @@ -78,7 +74,7 @@ module Impl { * println!("{:.1$}", PI, prec); * ``` */ - FormatArgument getPrecisionArgument() { + override FormatArgument getPrecisionArgument() { result.getParent() = this and result = Synth::TFormatArgument(_, _, 2, _, _, _) } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll index e552e657f720..942e0455cf49 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll @@ -41,18 +41,33 @@ module Generated { int getIndex() { none() } /** - * Gets the `index`th argument of this format (0-based). + * Gets the argument reference of this format, if it exists. */ - FormatArgument getArgument(int index) { none() } + FormatArgument getArgumentRef() { none() } /** - * Gets any of the arguments of this format. + * Holds if `getArgumentRef()` exists. */ - final FormatArgument getAnArgument() { result = this.getArgument(_) } + final predicate hasArgumentRef() { exists(this.getArgumentRef()) } /** - * Gets the number of arguments of this format. + * Gets the width argument of this format, if it exists. */ - final int getNumberOfArguments() { result = count(int i | exists(this.getArgument(i))) } + FormatArgument getWidthArgument() { none() } + + /** + * Holds if `getWidthArgument()` exists. + */ + final predicate hasWidthArgument() { exists(this.getWidthArgument()) } + + /** + * Gets the precision argument of this format, if it exists. + */ + FormatArgument getPrecisionArgument() { none() } + + /** + * Holds if `getPrecisionArgument()` exists. + */ + final predicate hasPrecisionArgument() { exists(this.getPrecisionArgument()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 5a230898a7a8..10a2efa30801 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -69,18 +69,29 @@ private module Impl { } private Element getImmediateChildOfFormat(Format e, int index, string partialPredicateCall) { - exists(int b, int bLocatable, int n, int nArgument | + exists( + int b, int bLocatable, int n, int nArgumentRef, int nWidthArgument, int nPrecisionArgument + | b = 0 and bLocatable = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocatable(e, i, _)) | i) and n = bLocatable and - nArgument = n + 1 + max(int i | i = -1 or exists(e.getArgument(i)) | i) and + nArgumentRef = n + 1 and + nWidthArgument = nArgumentRef + 1 and + nPrecisionArgument = nWidthArgument + 1 and ( none() or result = getImmediateChildOfLocatable(e, index - b, partialPredicateCall) or - result = e.getArgument(index - n) and - partialPredicateCall = "Argument(" + (index - n).toString() + ")" + index = n and result = e.getArgumentRef() and partialPredicateCall = "ArgumentRef()" + or + index = nArgumentRef and + result = e.getWidthArgument() and + partialPredicateCall = "WidthArgument()" + or + index = nWidthArgument and + result = e.getPrecisionArgument() and + partialPredicateCall = "PrecisionArgument()" ) ) } diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected index a4fe0acc9061..ce6f603ccd38 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.expected @@ -1,11 +1,11 @@ -| gen_format.rs:5:21:5:22 | {} | getParent: | gen_format.rs:5:14:5:32 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 0 | -| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | getParent: | gen_format.rs:7:14:7:47 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 3 | -| gen_format_args_arg.rs:5:26:5:27 | {} | getParent: | gen_format_args_arg.rs:5:17:5:39 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 0 | -| gen_format_args_expr.rs:6:19:6:20 | {} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 0 | -| gen_format_args_expr.rs:6:26:6:29 | {:?} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 3 | getNumberOfArguments: | 0 | -| gen_format_args_expr.rs:7:19:7:21 | {b} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 1 | -| gen_format_args_expr.rs:7:27:7:31 | {a:?} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 3 | getNumberOfArguments: | 1 | -| gen_format_args_expr.rs:9:19:9:21 | {x} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 1 | -| gen_format_args_expr.rs:9:24:9:26 | {y} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 3 | getNumberOfArguments: | 1 | -| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | getParent: | gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 3 | -| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | getParent: | gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | getIndex: | 1 | getNumberOfArguments: | 3 | +| gen_format.rs:5:21:5:22 | {} | getParent: | gen_format.rs:5:14:5:32 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | no | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | getParent: | gen_format.rs:7:14:7:47 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | yes | hasWidthArgument: | yes | hasPrecisionArgument: | yes | +| gen_format_args_arg.rs:5:26:5:27 | {} | getParent: | gen_format_args_arg.rs:5:17:5:39 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | no | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format_args_expr.rs:6:19:6:20 | {} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | no | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format_args_expr.rs:6:26:6:29 | {:?} | getParent: | gen_format_args_expr.rs:6:17:6:37 | FormatArgsExpr | getIndex: | 3 | hasArgumentRef: | no | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format_args_expr.rs:7:19:7:21 | {b} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | yes | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format_args_expr.rs:7:27:7:31 | {a:?} | getParent: | gen_format_args_expr.rs:7:17:7:43 | FormatArgsExpr | getIndex: | 3 | hasArgumentRef: | yes | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format_args_expr.rs:9:19:9:21 | {x} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | yes | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format_args_expr.rs:9:24:9:26 | {y} | getParent: | gen_format_args_expr.rs:9:17:9:28 | FormatArgsExpr | getIndex: | 3 | hasArgumentRef: | yes | hasWidthArgument: | no | hasPrecisionArgument: | no | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | getParent: | gen_format_argument.rs:5:14:5:47 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | yes | hasWidthArgument: | yes | hasPrecisionArgument: | yes | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | getParent: | gen_format_argument.rs:7:14:7:56 | FormatArgsExpr | getIndex: | 1 | hasArgumentRef: | yes | hasWidthArgument: | yes | hasPrecisionArgument: | yes | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql index 85b7d992af9f..5c7893ea65c5 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format.ql @@ -2,12 +2,16 @@ import codeql.rust.elements import TestUtils -from Format x, FormatArgsExpr getParent, int getIndex, int getNumberOfArguments +from + Format x, FormatArgsExpr getParent, int getIndex, string hasArgumentRef, string hasWidthArgument, + string hasPrecisionArgument where toBeTested(x) and not x.isUnknown() and getParent = x.getParent() and getIndex = x.getIndex() and - getNumberOfArguments = x.getNumberOfArguments() -select x, "getParent:", getParent, "getIndex:", getIndex, "getNumberOfArguments:", - getNumberOfArguments + (if x.hasArgumentRef() then hasArgumentRef = "yes" else hasArgumentRef = "no") and + (if x.hasWidthArgument() then hasWidthArgument = "yes" else hasWidthArgument = "no") and + if x.hasPrecisionArgument() then hasPrecisionArgument = "yes" else hasPrecisionArgument = "no" +select x, "getParent:", getParent, "getIndex:", getIndex, "hasArgumentRef:", hasArgumentRef, + "hasWidthArgument:", hasWidthArgument, "hasPrecisionArgument:", hasPrecisionArgument diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.expected new file mode 100644 index 000000000000..67572cd4d1a0 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.expected @@ -0,0 +1,7 @@ +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | gen_format.rs:7:22:7:26 | value | +| gen_format_args_expr.rs:7:19:7:21 | {b} | gen_format_args_expr.rs:7:20:7:20 | b | +| gen_format_args_expr.rs:7:27:7:31 | {a:?} | gen_format_args_expr.rs:7:28:7:28 | a | +| gen_format_args_expr.rs:9:19:9:21 | {x} | gen_format_args_expr.rs:9:20:9:20 | x | +| gen_format_args_expr.rs:9:24:9:26 | {y} | gen_format_args_expr.rs:9:25:9:25 | y | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:22:5:26 | value | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:22:7:22 | 0 | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.ql similarity index 66% rename from rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql rename to rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.ql index 33738ee81ef6..e9958bcf0fa2 100644 --- a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgument.ql +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getArgumentRef.ql @@ -2,6 +2,6 @@ import codeql.rust.elements import TestUtils -from Format x, int index +from Format x where toBeTested(x) and not x.isUnknown() -select x, index, x.getArgument(index) +select x, x.getArgumentRef() diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.expected new file mode 100644 index 000000000000..a7e495346553 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.expected @@ -0,0 +1,3 @@ +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | gen_format.rs:7:36:7:44 | precision | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:36:5:44 | precision | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:28:7:28 | 2 | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.ql new file mode 100644 index 000000000000..4b690bb0cc1e --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getPrecisionArgument.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from Format x +where toBeTested(x) and not x.isUnknown() +select x, x.getPrecisionArgument() diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.expected b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.expected new file mode 100644 index 000000000000..e6dd18077f24 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.expected @@ -0,0 +1,3 @@ +| gen_format.rs:7:21:7:46 | {value:#width$.precision$} | gen_format.rs:7:29:7:33 | width | +| gen_format_argument.rs:5:21:5:46 | {value:#width$.precision$} | gen_format_argument.rs:5:29:5:33 | width | +| gen_format_argument.rs:7:21:7:30 | {0:#1$.2$} | gen_format_argument.rs:7:25:7:25 | 1 | diff --git a/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.ql b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.ql new file mode 100644 index 000000000000..62fe11f48ebf --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/FormatArgsExpr/Format_getWidthArgument.ql @@ -0,0 +1,7 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +from Format x +where toBeTested(x) and not x.isUnknown() +select x, x.getWidthArgument() diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index bd539335a4eb..ff41d1a15e25 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1878,7 +1878,9 @@ class Format(Locatable): """ parent: FormatArgsExpr index: int - argument: list["FormatArgument"] | child + argument_ref: optional["FormatArgument"] | child + width_argument: optional["FormatArgument"] | child + precision_argument: optional["FormatArgument"] | child @synth.on_arguments(parent=FormatArgsExpr, index=int, kind=int, name=string, positional=boolean, offset=int)