diff --git a/.codeqlmanifest.json b/.codeqlmanifest.json index 8941685..a23b21e 100644 --- a/.codeqlmanifest.json +++ b/.codeqlmanifest.json @@ -1,12 +1,13 @@ { - "provide": [ - "ql/*/qlpack.yml" - ], - "versionPolicies": { - "default": { - "requireChangeNotes": true, - "committedPrereleaseSuffix": "dev", - "committedVersion": "nextPatchRelease" - } + "provide": [ + "bicep/ql/*/qlpack.yml", + "ql/*/qlpack.yml" + ], + "versionPolicies": { + "default": { + "requireChangeNotes": true, + "committedPrereleaseSuffix": "dev", + "committedVersion": "nextPatchRelease" } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0630f60 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "extractor/tree-sitter-hcl"] + path = extractor/tree-sitter-hcl + url = https://github.com/GeekMasher/tree-sitter-hcl +[submodule "extractor/tree-sitter-dockerfile"] + path = extractor/tree-sitter-dockerfile + url = https://github.com/GeekMasher/tree-sitter-dockerfile +[submodule "bicep/extractor/tree-sitter"] + path = bicep/extractor/tree-sitter + url = https://github.com/tree-sitter-grammars/tree-sitter-bicep diff --git a/Cargo.lock b/Cargo.lock index 6df5fac..c659e34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler2" @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -49,49 +49,50 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bstr" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "serde", @@ -99,15 +100,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "cc" -version = "1.1.28" +version = "1.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "shlex", ] @@ -120,9 +121,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -130,7 +131,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-link", ] [[package]] @@ -176,7 +177,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "codeql-extractor" version = "0.2.0" -source = "git+https://github.com/github/codeql?rev=839ca60f90f918b567e192642b0cc3003803f482#839ca60f90f918b567e192642b0cc3003803f482" +source = "git+https://github.com/github/codeql?rev=626c752a0b8cfd98bcf1f4b622d73bbe6f078a4c#626c752a0b8cfd98bcf1f4b622d73bbe6f078a4c" dependencies = [ "chrono", "encoding", @@ -189,7 +190,43 @@ dependencies = [ "serde", "serde_json", "tracing", - "tree-sitter 0.20.10", + "tracing-subscriber", + "tree-sitter 0.24.7", +] + +[[package]] +name = "codeql-extractor" +version = "0.2.0" +source = "git+https://github.com/github/codeql?rev=c524a98eb91c769cb2994b8373181c2ebd27c20f#c524a98eb91c769cb2994b8373181c2ebd27c20f" +dependencies = [ + "chrono", + "encoding", + "flate2", + "globset", + "lazy_static", + "num_cpus", + "rayon", + "regex", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", + "tree-sitter 0.24.7", +] + +[[package]] +name = "codeql-extractor-bicep" +version = "0.1.0" +dependencies = [ + "clap", + "codeql-extractor 0.2.0 (git+https://github.com/github/codeql?rev=c524a98eb91c769cb2994b8373181c2ebd27c20f)", + "flate2", + "rayon", + "regex", + "tracing", + "tracing-subscriber", + "tree-sitter 0.24.7", + "tree-sitter-bicep", ] [[package]] @@ -197,23 +234,22 @@ name = "codeql-extractor-iac" version = "0.4.1" dependencies = [ "clap", - "codeql-extractor", + "codeql-extractor 0.2.0 (git+https://github.com/github/codeql?rev=626c752a0b8cfd98bcf1f4b622d73bbe6f078a4c)", "flate2", "rayon", "regex", "tracing", "tracing-subscriber", "tree-sitter 0.24.7", - "tree-sitter-bicep", "tree-sitter-dockerfile", "tree-sitter-hcl", ] [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "core-foundation-sys" @@ -232,9 +268,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -251,15 +287,15 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encoding" @@ -337,14 +373,14 @@ dependencies = [ [[package]] name = "globset" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -362,14 +398,15 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -391,16 +428,17 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -412,15 +450,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "matchers" @@ -439,9 +477,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -477,9 +515,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "overload" @@ -489,24 +527,24 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -539,7 +577,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -554,9 +592,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -575,26 +613,32 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -603,9 +647,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -630,9 +674,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "streaming-iterator" @@ -648,9 +692,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -753,17 +797,16 @@ dependencies = [ [[package]] name = "tree-sitter-bicep" -version = "1.0.1" -source = "git+https://github.com/GeekMasher/tree-sitter-bicep?rev=0092c7d1bd6bb22ce0a6f78497d50ea2b87f19c0#0092c7d1bd6bb22ce0a6f78497d50ea2b87f19c0" +version = "1.1.0" dependencies = [ "cc", - "tree-sitter 0.20.10", + "tree-sitter 0.24.7", + "tree-sitter-language", ] [[package]] name = "tree-sitter-dockerfile" version = "0.1.0" -source = "git+https://github.com/GeekMasher/tree-sitter-dockerfile?rev=439c3e7b8a9bfdbf1f7d7c2beaae4173dc484cbf#439c3e7b8a9bfdbf1f7d7c2beaae4173dc484cbf" dependencies = [ "cc", "tree-sitter 0.20.10", @@ -772,7 +815,6 @@ dependencies = [ [[package]] name = "tree-sitter-hcl" version = "0.0.1" -source = "git+https://github.com/GeekMasher/tree-sitter-hcl?rev=5e045dd1ff7852511c249c4c5d919d9556751d98#5e045dd1ff7852511c249c4c5d919d9556751d98" dependencies = [ "cc", "tree-sitter 0.20.10", @@ -780,15 +822,15 @@ dependencies = [ [[package]] name = "tree-sitter-language" -version = "0.1.0" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2545046bd1473dac6c626659cc2567c6c0ff302fc8b84a56c4243378276f7f57" +checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "utf8parse" @@ -798,30 +840,30 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -830,9 +872,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -840,9 +882,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -853,9 +895,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "winapi" @@ -881,18 +926,68 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-targets", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", ] [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] diff --git a/Cargo.toml b/Cargo.toml index 107618e..efc79b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,3 @@ [workspace] -members = ["extractor"] +resolver = "2" +members = ["bicep/extractor", "extractor"] diff --git a/bicep/.codeqlmanifest.json b/bicep/.codeqlmanifest.json new file mode 100644 index 0000000..4f9897c --- /dev/null +++ b/bicep/.codeqlmanifest.json @@ -0,0 +1,12 @@ +{ + "provide": [ + "ql/*/qlpack.yml" + ], + "versionPolicies": { + "default": { + "requireChangeNotes": true, + "committedPrereleaseSuffix": "dev", + "committedVersion": "nextPatchRelease" + } + } +} \ No newline at end of file diff --git a/bicep/.gitignore b/bicep/.gitignore new file mode 100644 index 0000000..defad31 --- /dev/null +++ b/bicep/.gitignore @@ -0,0 +1,6 @@ +target/ +extractor-pack/ +.codeql/ +# CodeQL Testing Files / Folders +*.testproj/ +*.actual \ No newline at end of file diff --git a/bicep/Cargo.lock b/bicep/Cargo.lock new file mode 100644 index 0000000..e6d6b67 --- /dev/null +++ b/bicep/Cargo.lock @@ -0,0 +1,995 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "cc" +version = "1.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "clap" +version = "4.5.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "codeql-extractor" +version = "0.2.0" +source = "git+https://github.com/github/codeql?rev=c524a98eb91c769cb2994b8373181c2ebd27c20f#c524a98eb91c769cb2994b8373181c2ebd27c20f" +dependencies = [ + "chrono", + "encoding", + "flate2", + "globset", + "lazy_static", + "num_cpus", + "rayon", + "regex", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", + "tree-sitter", +] + +[[package]] +name = "codeql-extractor-bicep" +version = "0.1.0" +dependencies = [ + "clap", + "codeql-extractor", + "flate2", + "rayon", + "regex", + "tracing", + "tracing-subscriber", + "tree-sitter", + "tree-sitter-bicep", +] + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + +[[package]] +name = "flate2" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "globset" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tree-sitter" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5387dffa7ffc7d2dae12b50c6f7aab8ff79d6210147c6613561fc3d474c6f75" +dependencies = [ + "cc", + "regex", + "regex-syntax 0.8.5", + "streaming-iterator", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-bicep" +version = "1.1.0" +dependencies = [ + "cc", + "tree-sitter", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-language" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/bicep/Cargo.toml b/bicep/Cargo.toml new file mode 100644 index 0000000..9adb710 --- /dev/null +++ b/bicep/Cargo.toml @@ -0,0 +1,3 @@ +[workspace] +resolver = "2" +members = ["extractor"] diff --git a/bicep/codeql-extractor.code-workspace b/bicep/codeql-extractor.code-workspace new file mode 100644 index 0000000..3419bc3 --- /dev/null +++ b/bicep/codeql-extractor.code-workspace @@ -0,0 +1,25 @@ +{ + "folders": [ + { + "name": "Library", + "path": "ql/lib" + }, + { + "name": "Queries", + "path": "ql/src" + }, + { + "name": "Tests", + "path": "ql/test" + }, + { + "name": "Extractor", + "path": "extractor" + } + ], + "settings": { + "codeQL.runningTests.additionalTestArguments": [ + "./extractor-pack" + ] + } +} \ No newline at end of file diff --git a/bicep/codeql-extractor.yml b/bicep/codeql-extractor.yml new file mode 100644 index 0000000..1d8572c --- /dev/null +++ b/bicep/codeql-extractor.yml @@ -0,0 +1,16 @@ +name: bicep +display_name: Bicep +version: 0.1.0 +column_kind: utf8 +legacy_qltest_extraction: true +build_modes: +- none +github_api_languages: +- Bicep +scc_languages: +- Bicep +file_types: +- name: bicep + display_name: Bicep + extensions: + - .bicep diff --git a/bicep/downgrades/qlpack.yml b/bicep/downgrades/qlpack.yml new file mode 100644 index 0000000..8f835ca --- /dev/null +++ b/bicep/downgrades/qlpack.yml @@ -0,0 +1,5 @@ +name: codeql/bicep-downgrades +groups: bicep +downgrades: . +library: true +warnOnImplicitThis: true \ No newline at end of file diff --git a/bicep/extractor/Cargo.toml b/bicep/extractor/Cargo.toml new file mode 100644 index 0000000..883007f --- /dev/null +++ b/bicep/extractor/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "codeql-extractor-bicep" +version = "0.1.0" +authors = ["GitHub"] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +flate2 = "1.0" +clap = { version = "4.4", features = ["derive"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } +rayon = "1.8" +regex = "1.11.1" +# Tree Sitter +tree-sitter-bicep = { path = "./tree-sitter" } +tree-sitter = "^0.24" +# CodeQL - v2.20.4 +codeql-extractor = { git = "https://github.com/github/codeql", rev = "c524a98eb91c769cb2994b8373181c2ebd27c20f" } diff --git a/bicep/extractor/src/autobuilder.rs b/bicep/extractor/src/autobuilder.rs new file mode 100644 index 0000000..43fc30a --- /dev/null +++ b/bicep/extractor/src/autobuilder.rs @@ -0,0 +1,21 @@ +use std::env; +use std::path::PathBuf; + +use clap::Args; + +use codeql_extractor::autobuilder; + +#[derive(Args)] +// The autobuilder takes no command-line options, but this may change in the future. +pub struct Options {} + +pub fn run(_: Options) -> std::io::Result<()> { + let database = env::var("CODEQL_EXTRACTOR_BICEP_WIP_DATABASE") + .expect("CODEQL_EXTRACTOR_BICEP_WIP_DATABASE not set"); + + autobuilder::Autobuilder::new("bicep", PathBuf::from(database)) + .include_extensions(&[".bicep"]) + .exclude_globs(&["**/.git"]) + .size_limit("10m") + .run() +} diff --git a/bicep/extractor/src/extractor.rs b/bicep/extractor/src/extractor.rs new file mode 100644 index 0000000..e6b076f --- /dev/null +++ b/bicep/extractor/src/extractor.rs @@ -0,0 +1,53 @@ +use clap::Args; +use std::path::PathBuf; + +use codeql_extractor::{ + extractor::simple::{Extractor, LanguageSpec}, + file_paths, trap, +}; + +#[derive(Args)] +pub struct Options { + /// Sets a custom source achive folder + #[arg(long)] + source_archive_dir: PathBuf, + + /// Sets a custom trap folder + #[arg(long)] + output_dir: PathBuf, + + /// A text file containing the paths of the files to extract + #[arg(long)] + file_list: String, +} + +pub fn run(options: Options) -> std::io::Result<()> { + tracing_subscriber::fmt() + .with_target(false) + .without_time() + .with_level(true) + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .init(); + + let file_list = file_paths::path_from_string(&options.file_list); + let file_lists: Vec = vec![file_list]; + + let extractor = Extractor { + prefix: "bicep".to_string(), + languages: vec![ + // Bicep + LanguageSpec { + prefix: "bicep", + ts_language: tree_sitter_bicep::LANGUAGE.into(), + node_types: tree_sitter_bicep::NODE_TYPES, + file_globs: vec!["*.bicep".into()], + }, + ], + trap_dir: options.output_dir, + trap_compression: trap::Compression::from_env("CODEQL_BICEP_TRAP_COMPRESSION"), + source_archive_dir: options.source_archive_dir, + file_lists, + }; + + extractor.run() +} diff --git a/bicep/extractor/src/generator.rs b/bicep/extractor/src/generator.rs new file mode 100644 index 0000000..aaa547a --- /dev/null +++ b/bicep/extractor/src/generator.rs @@ -0,0 +1,26 @@ +use clap::Args; +use std::path::PathBuf; + +use codeql_extractor::generator::{generate, language::Language}; + +#[derive(Args)] +pub struct Options { + /// Path of the generated dbscheme file + #[arg(long)] + dbscheme: PathBuf, + + /// Path of the generated QLL file + #[arg(long)] + library: PathBuf, +} + +pub fn run(options: Options) -> std::io::Result<()> { + codeql_extractor::extractor::set_tracing_level("bicep"); + + let languages = vec![Language { + name: "BICEP".to_owned(), + node_types: tree_sitter_bicep::NODE_TYPES, + }]; + + generate(languages, options.dbscheme, options.library) +} diff --git a/bicep/extractor/src/main.rs b/bicep/extractor/src/main.rs new file mode 100644 index 0000000..e6721d4 --- /dev/null +++ b/bicep/extractor/src/main.rs @@ -0,0 +1,23 @@ +use clap::Parser; + +mod autobuilder; +mod extractor; +mod generator; + +#[derive(Parser)] +#[command(author, version, about)] +enum Cli { + Extract(extractor::Options), + Generate(generator::Options), + Autobuild(autobuilder::Options), +} + +fn main() -> std::io::Result<()> { + let cli = Cli::parse(); + + match cli { + Cli::Extract(options) => extractor::run(options), + Cli::Generate(options) => generator::run(options), + Cli::Autobuild(options) => autobuilder::run(options), + } +} diff --git a/bicep/extractor/tree-sitter b/bicep/extractor/tree-sitter new file mode 160000 index 0000000..bff5988 --- /dev/null +++ b/bicep/extractor/tree-sitter @@ -0,0 +1 @@ +Subproject commit bff59884307c0ab009bd5e81afd9324b46a6c0f9 diff --git a/bicep/ql/lib/bicep.dbscheme b/bicep/ql/lib/bicep.dbscheme new file mode 100644 index 0000000..6f45a1d --- /dev/null +++ b/bicep/ql/lib/bicep.dbscheme @@ -0,0 +1,676 @@ +// CodeQL database schema for BICEP +// Automatically generated from the tree-sitter grammar; do not edit + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- BICEP dbscheme -*/ +#keyset[bicep_arguments, index] +bicep_arguments_child( + int bicep_arguments: @bicep_arguments ref, + int index: int ref, + unique int child: @bicep_expression ref +); + +bicep_arguments_def( + unique int id: @bicep_arguments +); + +@bicep_array_child_type = @bicep_decorators | @bicep_expression + +#keyset[bicep_array, index] +bicep_array_child( + int bicep_array: @bicep_array ref, + int index: int ref, + unique int child: @bicep_array_child_type ref +); + +bicep_array_def( + unique int id: @bicep_array +); + +bicep_array_type_def( + unique int id: @bicep_array_type, + int child: @bicep_type__ ref +); + +bicep_assert_statement_def( + unique int id: @bicep_assert_statement, + int name: @bicep_token_identifier ref, + int child: @bicep_expression ref +); + +@bicep_assignment_expression_left_type = @bicep_member_expression | @bicep_parenthesized_expression | @bicep_resource_expression | @bicep_subscript_expression | @bicep_token_identifier + +bicep_assignment_expression_def( + unique int id: @bicep_assignment_expression, + int left: @bicep_assignment_expression_left_type ref, + int right: @bicep_expression ref +); + +case @bicep_binary_expression.operator of + 0 = @bicep_binary_expression_bangequal +| 1 = @bicep_binary_expression_bangtilde +| 2 = @bicep_binary_expression_percent +| 3 = @bicep_binary_expression_ampersandampersand +| 4 = @bicep_binary_expression_star +| 5 = @bicep_binary_expression_plus +| 6 = @bicep_binary_expression_minus +| 7 = @bicep_binary_expression_slash +| 8 = @bicep_binary_expression_langle +| 9 = @bicep_binary_expression_langleequal +| 10 = @bicep_binary_expression_equalequal +| 11 = @bicep_binary_expression_equaltilde +| 12 = @bicep_binary_expression_rangle +| 13 = @bicep_binary_expression_rangleequal +| 14 = @bicep_binary_expression_questionquestion +| 15 = @bicep_binary_expression_pipe +| 16 = @bicep_binary_expression_pipepipe +; + + +bicep_binary_expression_def( + unique int id: @bicep_binary_expression, + int left: @bicep_expression ref, + int operator: int ref, + int right: @bicep_expression ref +); + +bicep_call_expression_child( + unique int bicep_call_expression: @bicep_call_expression ref, + unique int child: @bicep_token_nullable_return_type ref +); + +bicep_call_expression_def( + unique int id: @bicep_call_expression, + int arguments: @bicep_arguments ref, + int function: @bicep_expression ref +); + +bicep_compatible_identifier_def( + unique int id: @bicep_compatible_identifier, + int child: @bicep_token_identifier ref +); + +@bicep_declaration = @bicep_assert_statement | @bicep_metadata_declaration | @bicep_module_declaration | @bicep_output_declaration | @bicep_parameter_declaration | @bicep_resource_declaration | @bicep_test_block | @bicep_type_declaration | @bicep_user_defined_function | @bicep_variable_declaration + +bicep_decorator_def( + unique int id: @bicep_decorator, + int child: @bicep_call_expression ref +); + +#keyset[bicep_decorators, index] +bicep_decorators_child( + int bicep_decorators: @bicep_decorators ref, + int index: int ref, + unique int child: @bicep_decorator ref +); + +bicep_decorators_def( + unique int id: @bicep_decorators +); + +@bicep_expression = @bicep_assignment_expression | @bicep_binary_expression | @bicep_lambda_expression | @bicep_primary_expression | @bicep_ternary_expression | @bicep_unary_expression + +@bicep_for_loop_parameters_child_type = @bicep_token_loop_enumerator | @bicep_token_loop_variable + +#keyset[bicep_for_loop_parameters, index] +bicep_for_loop_parameters_child( + int bicep_for_loop_parameters: @bicep_for_loop_parameters ref, + int index: int ref, + unique int child: @bicep_for_loop_parameters_child_type ref +); + +bicep_for_loop_parameters_def( + unique int id: @bicep_for_loop_parameters +); + +@bicep_for_statement_body_type = @bicep_expression | @bicep_if_statement + +bicep_for_statement_initializer( + unique int bicep_for_statement: @bicep_for_statement ref, + unique int initializer: @bicep_token_identifier ref +); + +@bicep_for_statement_child_type = @bicep_expression | @bicep_for_loop_parameters + +#keyset[bicep_for_statement, index] +bicep_for_statement_child( + int bicep_for_statement: @bicep_for_statement ref, + int index: int ref, + unique int child: @bicep_for_statement_child_type ref +); + +bicep_for_statement_def( + unique int id: @bicep_for_statement, + int body: @bicep_for_statement_body_type ref +); + +@bicep_if_statement_child_type = @bicep_object | @bicep_parenthesized_expression + +#keyset[bicep_if_statement, index] +bicep_if_statement_child( + int bicep_if_statement: @bicep_if_statement ref, + int index: int ref, + unique int child: @bicep_if_statement_child_type ref +); + +bicep_if_statement_def( + unique int id: @bicep_if_statement +); + +@bicep_import_functionality_child_type = @bicep_string__ | @bicep_token_identifier + +#keyset[bicep_import_functionality, index] +bicep_import_functionality_child( + int bicep_import_functionality: @bicep_import_functionality ref, + int index: int ref, + unique int child: @bicep_import_functionality_child_type ref +); + +bicep_import_functionality_def( + unique int id: @bicep_import_functionality +); + +@bicep_import_statement_child_type = @bicep_string__ | @bicep_token_identifier + +#keyset[bicep_import_statement, index] +bicep_import_statement_child( + int bicep_import_statement: @bicep_import_statement ref, + int index: int ref, + unique int child: @bicep_import_statement_child_type ref +); + +bicep_import_statement_def( + unique int id: @bicep_import_statement +); + +@bicep_import_with_statement_child_type = @bicep_expression | @bicep_string__ | @bicep_token_identifier + +#keyset[bicep_import_with_statement, index] +bicep_import_with_statement_child( + int bicep_import_with_statement: @bicep_import_with_statement ref, + int index: int ref, + unique int child: @bicep_import_with_statement_child_type ref +); + +bicep_import_with_statement_def( + unique int id: @bicep_import_with_statement +); + +#keyset[bicep_infrastructure, index] +bicep_infrastructure_child( + int bicep_infrastructure: @bicep_infrastructure ref, + int index: int ref, + unique int child: @bicep_statement ref +); + +bicep_infrastructure_def( + unique int id: @bicep_infrastructure +); + +bicep_interpolation_def( + unique int id: @bicep_interpolation, + int child: @bicep_expression ref +); + +#keyset[bicep_lambda_expression, index] +bicep_lambda_expression_child( + int bicep_lambda_expression: @bicep_lambda_expression ref, + int index: int ref, + unique int child: @bicep_expression ref +); + +bicep_lambda_expression_def( + unique int id: @bicep_lambda_expression +); + +@bicep_member_expression_object_type = @bicep_expression | @bicep_parameterized_type + +bicep_member_expression_def( + unique int id: @bicep_member_expression, + int object: @bicep_member_expression_object_type ref, + int property: @bicep_token_property_identifier ref +); + +@bicep_metadata_declaration_child_type = @bicep_expression | @bicep_token_identifier + +#keyset[bicep_metadata_declaration, index] +bicep_metadata_declaration_child( + int bicep_metadata_declaration: @bicep_metadata_declaration ref, + int index: int ref, + unique int child: @bicep_metadata_declaration_child_type ref +); + +bicep_metadata_declaration_def( + unique int id: @bicep_metadata_declaration +); + +@bicep_module_declaration_child_type = @bicep_for_statement | @bicep_if_statement | @bicep_object | @bicep_string__ | @bicep_token_identifier + +#keyset[bicep_module_declaration, index] +bicep_module_declaration_child( + int bicep_module_declaration: @bicep_module_declaration ref, + int index: int ref, + unique int child: @bicep_module_declaration_child_type ref +); + +bicep_module_declaration_def( + unique int id: @bicep_module_declaration +); + +bicep_negated_type_def( + unique int id: @bicep_negated_type, + int child: @bicep_type__ ref +); + +@bicep_nullable_type_child_type = @bicep_array_type | @bicep_expression | @bicep_parenthesized_type | @bicep_token_primitive_type + +bicep_nullable_type_def( + unique int id: @bicep_nullable_type, + int child: @bicep_nullable_type_child_type ref +); + +@bicep_object_child_type = @bicep_decorators | @bicep_object_property + +#keyset[bicep_object, index] +bicep_object_child( + int bicep_object: @bicep_object ref, + int index: int ref, + unique int child: @bicep_object_child_type ref +); + +bicep_object_def( + unique int id: @bicep_object +); + +@bicep_object_property_child_type = @bicep_array_type | @bicep_compatible_identifier | @bicep_expression | @bicep_nullable_type | @bicep_parameterized_type | @bicep_resource_declaration | @bicep_string__ | @bicep_token_identifier | @bicep_token_primitive_type | @bicep_union_type + +#keyset[bicep_object_property, index] +bicep_object_property_child( + int bicep_object_property: @bicep_object_property ref, + int index: int ref, + unique int child: @bicep_object_property_child_type ref +); + +bicep_object_property_def( + unique int id: @bicep_object_property +); + +@bicep_output_declaration_child_type = @bicep_expression | @bicep_token_identifier | @bicep_type__ + +#keyset[bicep_output_declaration, index] +bicep_output_declaration_child( + int bicep_output_declaration: @bicep_output_declaration ref, + int index: int ref, + unique int child: @bicep_output_declaration_child_type ref +); + +bicep_output_declaration_def( + unique int id: @bicep_output_declaration +); + +@bicep_parameter_child_type = @bicep_token_identifier | @bicep_type__ + +#keyset[bicep_parameter, index] +bicep_parameter_child( + int bicep_parameter: @bicep_parameter ref, + int index: int ref, + unique int child: @bicep_parameter_child_type ref +); + +bicep_parameter_def( + unique int id: @bicep_parameter +); + +@bicep_parameter_declaration_child_type = @bicep_expression | @bicep_token_identifier | @bicep_type__ + +#keyset[bicep_parameter_declaration, index] +bicep_parameter_declaration_child( + int bicep_parameter_declaration: @bicep_parameter_declaration ref, + int index: int ref, + unique int child: @bicep_parameter_declaration_child_type ref +); + +bicep_parameter_declaration_def( + unique int id: @bicep_parameter_declaration +); + +@bicep_parameterized_type_child_type = @bicep_token_identifier | @bicep_type_arguments + +#keyset[bicep_parameterized_type, index] +bicep_parameterized_type_child( + int bicep_parameterized_type: @bicep_parameterized_type ref, + int index: int ref, + unique int child: @bicep_parameterized_type_child_type ref +); + +bicep_parameterized_type_def( + unique int id: @bicep_parameterized_type +); + +#keyset[bicep_parameters, index] +bicep_parameters_child( + int bicep_parameters: @bicep_parameters ref, + int index: int ref, + unique int child: @bicep_parameter ref +); + +bicep_parameters_def( + unique int id: @bicep_parameters +); + +#keyset[bicep_parenthesized_expression, index] +bicep_parenthesized_expression_child( + int bicep_parenthesized_expression: @bicep_parenthesized_expression ref, + int index: int ref, + unique int child: @bicep_expression ref +); + +bicep_parenthesized_expression_def( + unique int id: @bicep_parenthesized_expression +); + +bicep_parenthesized_type_def( + unique int id: @bicep_parenthesized_type, + int child: @bicep_type__ ref +); + +@bicep_primary_expression = @bicep_array | @bicep_call_expression | @bicep_for_statement | @bicep_member_expression | @bicep_object | @bicep_parenthesized_expression | @bicep_resource_expression | @bicep_string__ | @bicep_subscript_expression | @bicep_token_boolean | @bicep_token_identifier | @bicep_token_null | @bicep_token_number + +@bicep_resource_declaration_child_type = @bicep_for_statement | @bicep_if_statement | @bicep_object | @bicep_string__ | @bicep_token_identifier + +#keyset[bicep_resource_declaration, index] +bicep_resource_declaration_child( + int bicep_resource_declaration: @bicep_resource_declaration ref, + int index: int ref, + unique int child: @bicep_resource_declaration_child_type ref +); + +bicep_resource_declaration_def( + unique int id: @bicep_resource_declaration +); + +bicep_resource_expression_def( + unique int id: @bicep_resource_expression, + int object: @bicep_expression ref, + int resource: @bicep_token_identifier ref +); + +@bicep_statement = @bicep_declaration | @bicep_decorators | @bicep_import_functionality | @bicep_import_statement | @bicep_import_with_statement | @bicep_target_scope_assignment | @bicep_using_statement + +@bicep_string_child_type = @bicep_interpolation | @bicep_token_escape_sequence | @bicep_token_string_content + +#keyset[bicep_string__, index] +bicep_string_child( + int bicep_string__: @bicep_string__ ref, + int index: int ref, + unique int child: @bicep_string_child_type ref +); + +bicep_string_def( + unique int id: @bicep_string__ +); + +bicep_subscript_expression_def( + unique int id: @bicep_subscript_expression, + int index: @bicep_expression ref, + int object: @bicep_expression ref +); + +bicep_target_scope_assignment_def( + unique int id: @bicep_target_scope_assignment, + int child: @bicep_string__ ref +); + +bicep_ternary_expression_def( + unique int id: @bicep_ternary_expression, + int alternative: @bicep_expression ref, + int condition: @bicep_expression ref, + int consequence: @bicep_expression ref +); + +@bicep_test_block_child_type = @bicep_object | @bicep_string__ | @bicep_token_identifier + +#keyset[bicep_test_block, index] +bicep_test_block_child( + int bicep_test_block: @bicep_test_block ref, + int index: int ref, + unique int child: @bicep_test_block_child_type ref +); + +bicep_test_block_def( + unique int id: @bicep_test_block +); + +@bicep_type_child_type = @bicep_array_type | @bicep_member_expression | @bicep_negated_type | @bicep_nullable_type | @bicep_object | @bicep_parameterized_type | @bicep_parenthesized_type | @bicep_string__ | @bicep_token_boolean | @bicep_token_identifier | @bicep_token_null | @bicep_token_number | @bicep_token_primitive_type | @bicep_union_type + +bicep_type_def( + unique int id: @bicep_type__, + int child: @bicep_type_child_type ref +); + +#keyset[bicep_type_arguments, index] +bicep_type_arguments_child( + int bicep_type_arguments: @bicep_type_arguments ref, + int index: int ref, + unique int child: @bicep_string__ ref +); + +bicep_type_arguments_def( + unique int id: @bicep_type_arguments +); + +@bicep_type_declaration_child_type = @bicep_array_type | @bicep_expression | @bicep_nullable_type | @bicep_parameterized_type | @bicep_token_identifier | @bicep_union_type + +#keyset[bicep_type_declaration, index] +bicep_type_declaration_child( + int bicep_type_declaration: @bicep_type_declaration ref, + int index: int ref, + unique int child: @bicep_type_declaration_child_type ref +); + +bicep_type_declaration_def( + unique int id: @bicep_type_declaration +); + +case @bicep_unary_expression.operator of + 0 = @bicep_unary_expression_bang +| 1 = @bicep_unary_expression_minus +; + + +bicep_unary_expression_def( + unique int id: @bicep_unary_expression, + int argument: @bicep_expression ref, + int operator: int ref +); + +@bicep_union_type_child_type = @bicep_array_type | @bicep_expression | @bicep_member_expression | @bicep_negated_type | @bicep_nullable_type | @bicep_object | @bicep_parameterized_type | @bicep_parenthesized_type | @bicep_string__ | @bicep_token_boolean | @bicep_token_identifier | @bicep_token_null | @bicep_token_number | @bicep_token_primitive_type + +#keyset[bicep_union_type, index] +bicep_union_type_child( + int bicep_union_type: @bicep_union_type ref, + int index: int ref, + unique int child: @bicep_union_type_child_type ref +); + +bicep_union_type_def( + unique int id: @bicep_union_type +); + +@bicep_user_defined_function_child_type = @bicep_expression | @bicep_parameters + +#keyset[bicep_user_defined_function, index] +bicep_user_defined_function_child( + int bicep_user_defined_function: @bicep_user_defined_function ref, + int index: int ref, + unique int child: @bicep_user_defined_function_child_type ref +); + +bicep_user_defined_function_def( + unique int id: @bicep_user_defined_function, + int name: @bicep_token_identifier ref, + int returns: @bicep_type__ ref +); + +bicep_using_statement_def( + unique int id: @bicep_using_statement, + int child: @bicep_string__ ref +); + +@bicep_variable_declaration_child_type = @bicep_expression | @bicep_token_identifier + +#keyset[bicep_variable_declaration, index] +bicep_variable_declaration_child( + int bicep_variable_declaration: @bicep_variable_declaration ref, + int index: int ref, + unique int child: @bicep_variable_declaration_child_type ref +); + +bicep_variable_declaration_def( + unique int id: @bicep_variable_declaration +); + +bicep_tokeninfo( + unique int id: @bicep_token, + int kind: int ref, + string value: string ref +); + +case @bicep_token.kind of + 0 = @bicep_reserved_word +| 1 = @bicep_token_boolean +| 2 = @bicep_token_comment +| 3 = @bicep_token_diagnostic_comment +| 4 = @bicep_token_escape_sequence +| 5 = @bicep_token_identifier +| 6 = @bicep_token_loop_enumerator +| 7 = @bicep_token_loop_variable +| 8 = @bicep_token_null +| 9 = @bicep_token_nullable_return_type +| 10 = @bicep_token_number +| 11 = @bicep_token_primitive_type +| 12 = @bicep_token_property_identifier +| 13 = @bicep_token_string_content +; + + +@bicep_ast_node = @bicep_arguments | @bicep_array | @bicep_array_type | @bicep_assert_statement | @bicep_assignment_expression | @bicep_binary_expression | @bicep_call_expression | @bicep_compatible_identifier | @bicep_decorator | @bicep_decorators | @bicep_for_loop_parameters | @bicep_for_statement | @bicep_if_statement | @bicep_import_functionality | @bicep_import_statement | @bicep_import_with_statement | @bicep_infrastructure | @bicep_interpolation | @bicep_lambda_expression | @bicep_member_expression | @bicep_metadata_declaration | @bicep_module_declaration | @bicep_negated_type | @bicep_nullable_type | @bicep_object | @bicep_object_property | @bicep_output_declaration | @bicep_parameter | @bicep_parameter_declaration | @bicep_parameterized_type | @bicep_parameters | @bicep_parenthesized_expression | @bicep_parenthesized_type | @bicep_resource_declaration | @bicep_resource_expression | @bicep_string__ | @bicep_subscript_expression | @bicep_target_scope_assignment | @bicep_ternary_expression | @bicep_test_block | @bicep_token | @bicep_type__ | @bicep_type_arguments | @bicep_type_declaration | @bicep_unary_expression | @bicep_union_type | @bicep_user_defined_function | @bicep_using_statement | @bicep_variable_declaration + +bicep_ast_node_location( + unique int node: @bicep_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +bicep_ast_node_parent( + unique int node: @bicep_ast_node ref, + int parent: @bicep_ast_node ref, + int parent_index: int ref +); + diff --git a/bicep/ql/lib/bicep.dbscheme.stats b/bicep/ql/lib/bicep.dbscheme.stats new file mode 100644 index 0000000..a9aacbc --- /dev/null +++ b/bicep/ql/lib/bicep.dbscheme.stats @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/bicep/ql/lib/bicep.qll b/bicep/ql/lib/bicep.qll new file mode 100644 index 0000000..b53bdce --- /dev/null +++ b/bicep/ql/lib/bicep.qll @@ -0,0 +1,4 @@ +import codeql.Locations +import codeql.files.FileSystem +// AST +import codeql.bicep.AST diff --git a/bicep/ql/lib/codeql-pack.lock.yml b/bicep/ql/lib/codeql-pack.lock.yml new file mode 100644 index 0000000..9e1c9be --- /dev/null +++ b/bicep/ql/lib/codeql-pack.lock.yml @@ -0,0 +1,18 @@ +--- +lockVersion: 1.0.0 +dependencies: + codeql/controlflow: + version: 1.0.12 + codeql/dataflow: + version: 1.1.6 + codeql/regex: + version: 1.0.12 + codeql/ssa: + version: 1.0.12 + codeql/typetracking: + version: 1.0.12 + codeql/util: + version: 1.0.12 + codeql/yaml: + version: 1.0.20 +compiled: false diff --git a/bicep/ql/lib/codeql/IDEContextual.qll b/bicep/ql/lib/codeql/IDEContextual.qll new file mode 100644 index 0000000..27612ea --- /dev/null +++ b/bicep/ql/lib/codeql/IDEContextual.qll @@ -0,0 +1,16 @@ +/** + * Provides shared predicates related to contextual queries in the code viewer. + */ + +private import codeql.files.FileSystem +private import codeql.util.FileSystem + +/** + * Returns an appropriately encoded version of a filename `name` + * passed by the VS Code extension in order to coincide with the + * output of `.getFile()` on locatable entities. + */ +cached +File getFileBySourceArchiveName(string name) { + result = IdeContextual::getFileBySourceArchiveName(name) +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/Locations.qll b/bicep/ql/lib/codeql/Locations.qll new file mode 100644 index 0000000..ae8058c --- /dev/null +++ b/bicep/ql/lib/codeql/Locations.qll @@ -0,0 +1,54 @@ +/** Provides classes for working with locations. */ + +import files.FileSystem + +/** + * A location as given by a file, a start line, a start column, + * an end line, and an end column. + * + * For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +class Location extends @location_default { + /** Gets the file for this location. */ + File getFile() { locations_default(this, result, _, _, _, _) } + + /** Gets the 1-based line number (inclusive) where this location starts. */ + int getStartLine() { locations_default(this, _, result, _, _, _) } + + /** Gets the 1-based column number (inclusive) where this location starts. */ + int getStartColumn() { locations_default(this, _, _, result, _, _) } + + /** Gets the 1-based line number (inclusive) where this location ends. */ + int getEndLine() { locations_default(this, _, _, _, result, _) } + + /** Gets the 1-based column number (inclusive) where this location ends. */ + int getEndColumn() { locations_default(this, _, _, _, _, result) } + + /** Gets the number of lines covered by this location. */ + int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 } + + /** Gets a textual representation of this element. */ + cached + string toString() { + exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | + this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and + result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn + ) + } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + exists(File f | + locations_default(this, f, startline, startcolumn, endline, endcolumn) and + filepath = f.getAbsolutePath() + ) + } +} diff --git a/bicep/ql/lib/codeql/bicep/AST.qll b/bicep/ql/lib/codeql/bicep/AST.qll new file mode 100644 index 0000000..bbafd78 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/AST.qll @@ -0,0 +1,6 @@ +import ast.AstNodes +import ast.Literals +import ast.Expr +import ast.Stmts +import ast.Loops +import ast.Misc diff --git a/bicep/ql/lib/codeql/bicep/CFG.qll b/bicep/ql/lib/codeql/bicep/CFG.qll new file mode 100644 index 0000000..6223bd2 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/CFG.qll @@ -0,0 +1,5 @@ +/** Provides classes representing the control flow graph. */ + +import codeql.Locations +import controlflow.BasicBlocks +import controlflow.ControlFlowGraph diff --git a/bicep/ql/lib/codeql/bicep/Concepts.qll b/bicep/ql/lib/codeql/bicep/Concepts.qll new file mode 100644 index 0000000..5ead729 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/Concepts.qll @@ -0,0 +1,2 @@ +private import codeql.bicep.AST +private import codeql.bicep.CFG diff --git a/bicep/ql/lib/codeql/bicep/Diagnostics.qll b/bicep/ql/lib/codeql/bicep/Diagnostics.qll new file mode 100644 index 0000000..faf7b84 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/Diagnostics.qll @@ -0,0 +1,52 @@ +private import codeql.Locations + +/** A diagnostic emitted during extraction, such as a parse error */ +class Diagnostic extends @diagnostic { + int severity; + string tag; + string message; + string fullMessage; + Location location; + + Diagnostic() { diagnostics(this, severity, tag, message, fullMessage, location) } + + /** + * Gets the numerical severity level associated with this diagnostic. + */ + int getSeverity() { result = severity } + + /** Gets a string representation of the severity of this diagnostic. */ + string getSeverityText() { + severity = 10 and result = "Debug" + or + severity = 20 and result = "Info" + or + severity = 30 and result = "Warning" + or + severity = 40 and result = "Error" + } + + /** Gets the error code associated with this diagnostic, e.g. parse_error. */ + string getTag() { result = tag } + + /** + * Gets the error message text associated with this diagnostic. + */ + string getMessage() { result = message } + + /** + * Gets the full error message text associated with this diagnostic. + */ + string getFullMessage() { result = fullMessage } + + /** Gets the source location of this diagnostic. */ + Location getLocation() { result = location } + + /** Gets a textual representation of this diagnostic. */ + string toString() { result = this.getMessage() } +} + +/** A diagnostic relating to a particular error in extracting a file. */ +class ExtractionError extends Diagnostic { + ExtractionError() { this.getTag() = "parse_error" } +} diff --git a/bicep/ql/lib/codeql/bicep/ast/AstNodes.qll b/bicep/ql/lib/codeql/bicep/ast/AstNodes.qll new file mode 100644 index 0000000..f11d25d --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/AstNodes.qll @@ -0,0 +1,99 @@ +private import codeql.Locations +private import codeql.files.FileSystem +private import codeql.bicep.ast.internal.AstNodes +private import codeql.bicep.ast.internal.TreeSitter + +/** + * An AST node of a Bicep program + */ +class AstNode extends TAstNode { + string toString() { result = this.getAPrimaryQlClass() } + + /** Gets the location of the AST node. */ + cached + Location getLocation() { result = this.getFullLocation() } // overridden in some subclasses + + /** Gets the file containing this AST node. */ + cached + File getFile() { result = this.getFullLocation().getFile() } + + /** Gets the location that spans the entire AST node. */ + cached + final Location getFullLocation() { result = toTreeSitter(this).getLocation() } + + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + if exists(this.getLocation()) + then this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + else ( + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 + ) + } + + /** + * Gets the parent in the AST for this node. + */ + cached + AstNode getParent() { result.getAChild(_) = this } + + /** + * Gets a child of this node, which can also be retrieved using a predicate + * named `pred`. + */ + cached + AstNode getAChild(string pred) { none() } + + /** Gets any child of this node. */ + AstNode getAChild() { result = this.getAChild(_) } + + /** + * Gets the primary QL class for the ast node. + */ + string getAPrimaryQlClass() { result = "???" } +} + +/** A Bicep file */ +class BicepFile extends File { + BicepFile() { exists(Location loc | bicep_ast_node_location(_, loc) and this = loc.getFile()) } + + /** Gets a token in this file. */ + private BICEP::Token getAToken() { result.getLocation().getFile() = this } + + /** Holds if `line` contains a token. */ + private predicate line(int line) { + exists(BICEP::Token token, Location l | + token = this.getAToken() and + l = token.getLocation() and + line in [l.getStartLine() .. l.getEndLine()] + ) + } + + /** Gets the number of lines in this file. */ + int getNumberOfLines() { result = max([0, this.getAToken().getLocation().getEndLine()]) } + + /** Gets the number of lines of code in this file. */ + int getNumberOfLinesOfCode() { result = count(int line | this.line(line)) } +} + +/** + * A comment in a Bicep program + */ +class Comment extends AstNode, TComment { + private BICEP::Comment comment; + + override string getAPrimaryQlClass() { result = "Comment" } + + Comment() { this = TComment(comment) } + + /** + * Gets the text of the comment. + * + * TODO: Implement this method + */ + string getContents() { result = "" } +} diff --git a/bicep/ql/lib/codeql/bicep/ast/Expr.qll b/bicep/ql/lib/codeql/bicep/ast/Expr.qll new file mode 100644 index 0000000..2143e5f --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/Expr.qll @@ -0,0 +1,93 @@ +private import AstNodes +private import internal.AstNodes +private import internal.TreeSitter +private import internal.Expr +private import internal.AssignmentExpression +private import internal.BinaryExpression +private import internal.CallExpression +private import internal.Expression +private import internal.Interpolation +private import internal.LambdaExpression +private import internal.MemberExpression +private import internal.NullableType +private import internal.ParenthesizedExpression +private import internal.PrimaryExpression +private import internal.ResourceExpression +private import internal.SubscriptExpression +private import internal.TernaryExpression +private import internal.UnaryExpression + +/** + * An expression in the AST. + */ +final class Expr extends AstNode instanceof ExprImpl { } + +/** + * A AssignmentExpression expression in the AST. + */ +final class AssignmentExpressionExpr extends Expr instanceof AssignmentExpressionImpl { } + +/** + * A BinaryExpression expression in the AST. + */ +final class BinaryExpressionExpr extends Expr instanceof BinaryExpressionImpl { } + +/** + * A CallExpression expression in the AST. + */ +final class CallExpressionExpr extends Expr instanceof CallExpressionImpl { } + +/** + * A Expression expression in the AST. + */ +final class ExpressionExpr extends Expr instanceof ExpressionImpl { } + +/** + * A Interpolation literal in the AST. + */ +final class InterpolationLiteral extends Expr instanceof InterpolationImpl { } + +/** + * A LambdaExpression expression in the AST. + */ +final class LambdaExpressionExpr extends Expr instanceof LambdaExpressionImpl { } + +/** + * A MemberExpression expression in the AST. + */ +final class MemberExpressionExpr extends Expr instanceof MemberExpressionImpl { } + +/** + * A NullableType literal in the AST. + */ +final class NullableTypeLiteral extends Expr instanceof NullableTypeImpl { } + +/** + * A ParenthesizedExpression expression in the AST. + */ +final class ParenthesizedExpressionExpr extends Expr instanceof ParenthesizedExpressionImpl { } + +/** + * A PrimaryExpression expression in the AST. + */ +final class PrimaryExpressionExpr extends Expr instanceof PrimaryExpressionImpl { } + +/** + * A ResourceExpression expression in the AST. + */ +final class ResourceExpressionExpr extends Expr instanceof ResourceExpressionImpl { } + +/** + * A SubscriptExpression expression in the AST. + */ +final class SubscriptExpressionExpr extends Expr instanceof SubscriptExpressionImpl { } + +/** + * A TernaryExpression expression in the AST. + */ +final class TernaryExpressionExpr extends Expr instanceof TernaryExpressionImpl { } + +/** + * A UnaryExpression expression in the AST. + */ +final class UnaryExpressionExpr extends Expr instanceof UnaryExpressionImpl { } diff --git a/bicep/ql/lib/codeql/bicep/ast/Literals.qll b/bicep/ql/lib/codeql/bicep/ast/Literals.qll new file mode 100644 index 0000000..10e770a --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/Literals.qll @@ -0,0 +1,40 @@ +/** + * Literals in the AST. + */ + +private import AstNodes +private import internal.AstNodes +private import internal.TreeSitter +private import internal.Literals +private import internal.Null +private import internal.NullableReturnType +private import internal.String +private import internal.StringContent + +/** + * A literal in the AST. + */ +final class Literals extends AstNode instanceof LiteralsImpl { } + +/** + * A Null literal in the AST. + */ +final class NullLiteral extends Literals instanceof NullImpl { +} +/** + * A NullableReturnType literal in the AST. + */ +final class NullableReturnTypeLiteral extends Literals instanceof NullableReturnTypeImpl { +} + +/** + * A String literal in the AST. + */ +final class StringLiteral extends Literals instanceof StringImpl { + string getString() { result = super.getValue() } +} +/** + * A StringContent literal in the AST. + */ +final class StringContentLiteral extends Literals instanceof StringContentImpl { +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/Loops.qll b/bicep/ql/lib/codeql/bicep/ast/Loops.qll new file mode 100644 index 0000000..271afa8 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/Loops.qll @@ -0,0 +1,4 @@ + +/** + * Loop statements are not supported in `bicep` code. + */ diff --git a/bicep/ql/lib/codeql/bicep/ast/Misc.qll b/bicep/ql/lib/codeql/bicep/ast/Misc.qll new file mode 100644 index 0000000..78c8e71 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/Misc.qll @@ -0,0 +1,197 @@ + +private import AstNodes +private import internal.Arguments +private import internal.Array +private import internal.ArrayType +private import internal.Boolean +private import internal.CompatibleIdentifier +private import internal.Declaration +private import internal.Decorator +private import internal.Decorators +private import internal.DiagnosticComment +private import internal.EscapeSequence +private import internal.ForLoopParameters +private import internal.Identifier +private import internal.ImportFunctionality +private import internal.Infrastructure +private import internal.LoopEnumerator +private import internal.LoopVariable +private import internal.MetadataDeclaration +private import internal.ModuleDeclaration +private import internal.NegatedType +private import internal.Number +private import internal.Object +private import internal.ObjectProperty +private import internal.OutputDeclaration +private import internal.Parameter +private import internal.ParameterDeclaration +private import internal.ParameterizedType +private import internal.Parameters +private import internal.ParenthesizedType +private import internal.PrimitiveType +private import internal.PropertyIdentifier +private import internal.ResourceDeclaration +private import internal.TargetScopeAssignment +private import internal.TestBlock +private import internal.Type +private import internal.TypeArguments +private import internal.TypeDeclaration +private import internal.UnionType +private import internal.UserDefinedFunction +private import internal.VariableDeclaration +/** + * A Arguments unknown AST node. + */ +class Arguments extends AstNode instanceof ArgumentsImpl { } +/** + * A Array unknown AST node. + */ +class Array extends AstNode instanceof ArrayImpl { } +/** + * A ArrayType unknown AST node. + */ +class ArrayType extends AstNode instanceof ArrayTypeImpl { } +/** + * A Boolean unknown AST node. + */ +class Boolean extends AstNode instanceof BooleanImpl { } +/** + * A CompatibleIdentifier unknown AST node. + */ +class CompatibleIdentifier extends AstNode instanceof CompatibleIdentifierImpl { } +/** + * A Declaration unknown AST node. + */ +class Declaration extends AstNode instanceof DeclarationImpl { } +/** + * A Decorator unknown AST node. + */ +class Decorator extends AstNode instanceof DecoratorImpl { } +/** + * A Decorators unknown AST node. + */ +class Decorators extends AstNode instanceof DecoratorsImpl { } +/** + * A DiagnosticComment unknown AST node. + */ +class DiagnosticComment extends AstNode instanceof DiagnosticCommentImpl { } +/** + * A EscapeSequence unknown AST node. + */ +class EscapeSequence extends AstNode instanceof EscapeSequenceImpl { } +/** + * A ForLoopParameters unknown AST node. + */ +class ForLoopParameters extends AstNode instanceof ForLoopParametersImpl { } +/** + * A Identifier unknown AST node. + */ +class Identifier extends AstNode instanceof IdentifierImpl { } +/** + * A ImportFunctionality unknown AST node. + */ +class ImportFunctionality extends AstNode instanceof ImportFunctionalityImpl { } +/** + * A Infrastructure unknown AST node. + */ +class Infrastructure extends AstNode instanceof InfrastructureImpl { } +/** + * A LoopEnumerator unknown AST node. + */ +class LoopEnumerator extends AstNode instanceof LoopEnumeratorImpl { } +/** + * A LoopVariable unknown AST node. + */ +class LoopVariable extends AstNode instanceof LoopVariableImpl { } +/** + * A MetadataDeclaration unknown AST node. + */ +class MetadataDeclaration extends AstNode instanceof MetadataDeclarationImpl { } +/** + * A ModuleDeclaration unknown AST node. + */ +class ModuleDeclaration extends AstNode instanceof ModuleDeclarationImpl { } +/** + * A NegatedType unknown AST node. + */ +class NegatedType extends AstNode instanceof NegatedTypeImpl { } +/** + * A Number unknown AST node. + */ +class Number extends AstNode instanceof NumberImpl { } +/** + * A Object unknown AST node. + */ +class Object extends AstNode instanceof ObjectImpl { } +/** + * A ObjectProperty unknown AST node. + */ +class ObjectProperty extends AstNode instanceof ObjectPropertyImpl { } +/** + * A OutputDeclaration unknown AST node. + */ +class OutputDeclaration extends AstNode instanceof OutputDeclarationImpl { } +/** + * A Parameter unknown AST node. + */ +class Parameter extends AstNode instanceof ParameterImpl { } +/** + * A ParameterDeclaration unknown AST node. + */ +class ParameterDeclaration extends AstNode instanceof ParameterDeclarationImpl { } +/** + * A ParameterizedType unknown AST node. + */ +class ParameterizedType extends AstNode instanceof ParameterizedTypeImpl { } +/** + * A Parameters unknown AST node. + */ +class Parameters extends AstNode instanceof ParametersImpl { } +/** + * A ParenthesizedType unknown AST node. + */ +class ParenthesizedType extends AstNode instanceof ParenthesizedTypeImpl { } +/** + * A PrimitiveType unknown AST node. + */ +class PrimitiveType extends AstNode instanceof PrimitiveTypeImpl { } +/** + * A PropertyIdentifier unknown AST node. + */ +class PropertyIdentifier extends AstNode instanceof PropertyIdentifierImpl { } +/** + * A ResourceDeclaration unknown AST node. + */ +class ResourceDeclaration extends AstNode instanceof ResourceDeclarationImpl { } +/** + * A TargetScopeAssignment unknown AST node. + */ +class TargetScopeAssignment extends AstNode instanceof TargetScopeAssignmentImpl { } +/** + * A TestBlock unknown AST node. + */ +class TestBlock extends AstNode instanceof TestBlockImpl { } +/** + * A Type unknown AST node. + */ +class Type extends AstNode instanceof TypeImpl { } +/** + * A TypeArguments unknown AST node. + */ +class TypeArguments extends AstNode instanceof TypeArgumentsImpl { } +/** + * A TypeDeclaration unknown AST node. + */ +class TypeDeclaration extends AstNode instanceof TypeDeclarationImpl { } +/** + * A UnionType unknown AST node. + */ +class UnionType extends AstNode instanceof UnionTypeImpl { } +/** + * A UserDefinedFunction unknown AST node. + */ +class UserDefinedFunction extends AstNode instanceof UserDefinedFunctionImpl { } +/** + * A VariableDeclaration unknown AST node. + */ +class VariableDeclaration extends AstNode instanceof VariableDeclarationImpl { } diff --git a/bicep/ql/lib/codeql/bicep/ast/Stmts.qll b/bicep/ql/lib/codeql/bicep/ast/Stmts.qll new file mode 100644 index 0000000..20fe815 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/Stmts.qll @@ -0,0 +1,59 @@ +/** + * Statement nodes in the AST. + */ +private import AstNodes +private import internal.AstNodes +private import internal.TreeSitter +private import internal.Stmts +private import internal.AssertStatement +private import internal.ForStatement +private import internal.IfStatement +private import internal.ImportStatement +private import internal.ImportWithStatement +private import internal.Statement +private import internal.UsingStatement +// CFG +private import codeql.bicep.CFG +private import codeql.bicep.controlflow.internal.ControlFlowGraphImpl as CfgImpl + +/** + * A Stmt block + */ +class Stmts extends AstNode instanceof StmtsImpl { + /** Gets a control-flow node for this statement, if any. */ + CfgImpl::AstCfgNode getAControlFlowNode() { result.getAstNode() = this } + + /** Gets a control-flow entry node for this statement, if any */ + AstNode getAControlFlowEntryNode() { result = CfgImpl::getAControlFlowEntryNode(this) } +} + + + +/** + * A AssertStatement statement + */ +final class AssertStatementStmt extends Stmts instanceof AssertStatementImpl { } +/** + * A ForStatement statement + */ +final class ForStatementStmt extends Stmts instanceof ForStatementImpl { } +/** + * A IfStatement statement + */ +final class IfStatementStmt extends Stmts instanceof IfStatementImpl { } +/** + * A ImportStatement statement + */ +final class ImportStatementStmt extends Stmts instanceof ImportStatementImpl { } +/** + * A ImportWithStatement statement + */ +final class ImportWithStatementStmt extends Stmts instanceof ImportWithStatementImpl { } +/** + * A Statement statement + */ +final class StatementStmt extends Stmts instanceof StatementImpl { } +/** + * A UsingStatement statement + */ +final class UsingStatementStmt extends Stmts instanceof UsingStatementImpl { } diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Arguments.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Arguments.qll new file mode 100644 index 0000000..a1c39ff --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Arguments.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Arguments + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Arguments AST Node. + */ +class ArgumentsImpl extends TArguments, AstNode { + private BICEP::Arguments ast; + + override string getAPrimaryQlClass() { result = "Arguments" } + + ArgumentsImpl() { this = TArguments(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Array.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Array.qll new file mode 100644 index 0000000..dd7c64a --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Array.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Array + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Array AST Node. + */ +class ArrayImpl extends TArray, AstNode { + private BICEP::Array ast; + + override string getAPrimaryQlClass() { result = "Array" } + + ArrayImpl() { this = TArray(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ArrayType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ArrayType.qll new file mode 100644 index 0000000..e1c922f --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ArrayType.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ArrayType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ArrayType AST Node. + */ +class ArrayTypeImpl extends TArrayType, AstNode { + private BICEP::ArrayType ast; + + override string getAPrimaryQlClass() { result = "ArrayType" } + + ArrayTypeImpl() { this = TArrayType(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/AssertStatement.qll b/bicep/ql/lib/codeql/bicep/ast/internal/AssertStatement.qll new file mode 100644 index 0000000..c352b56 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/AssertStatement.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for AssertStatement + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Stmts + + +/** + * A AssertStatement AST Node. + */ +class AssertStatementImpl extends TAssertStatement, StmtsImpl { + private BICEP::AssertStatement ast; + + override string getAPrimaryQlClass() { result = "AssertStatement" } + + AssertStatementImpl() { this = TAssertStatement(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/AssignmentExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/AssignmentExpression.qll new file mode 100644 index 0000000..c9c285e --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/AssignmentExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for AssignmentExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A AssignmentExpression AST Node. + */ +class AssignmentExpressionImpl extends TAssignmentExpression, ExprImpl { + private BICEP::AssignmentExpression ast; + + override string getAPrimaryQlClass() { result = "AssignmentExpression" } + + AssignmentExpressionImpl() { this = TAssignmentExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/AstNodes.qll b/bicep/ql/lib/codeql/bicep/ast/internal/AstNodes.qll new file mode 100644 index 0000000..84bd6b9 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/AstNodes.qll @@ -0,0 +1,168 @@ +private import TreeSitter + +/** + * An AST node of a Bicep program + */ +cached +newtype TAstNode = + TArguments(BICEP::Arguments r) or + TArray(BICEP::Array r) or + TArrayType(BICEP::ArrayType r) or + TAssertStatement(BICEP::AssertStatement r) or + TAssignmentExpression(BICEP::AssignmentExpression r) or + TBinaryExpression(BICEP::BinaryExpression r) or + TBoolean(BICEP::Boolean r) or + TCallExpression(BICEP::CallExpression r) or + TComment(BICEP::Comment r) or + TCompatibleIdentifier(BICEP::CompatibleIdentifier r) or + TDeclaration(BICEP::Declaration r) or + TDecorator(BICEP::Decorator r) or + TDecorators(BICEP::Decorators r) or + TDiagnosticComment(BICEP::DiagnosticComment r) or + TEscapeSequence(BICEP::EscapeSequence r) or + TExpression(BICEP::Expression r) or + TForLoopParameters(BICEP::ForLoopParameters r) or + TForStatement(BICEP::ForStatement r) or + TIdentifier(BICEP::Identifier r) or + TIfStatement(BICEP::IfStatement r) or + TImportFunctionality(BICEP::ImportFunctionality r) or + TImportStatement(BICEP::ImportStatement r) or + TImportWithStatement(BICEP::ImportWithStatement r) or + TInfrastructure(BICEP::Infrastructure r) or + TInterpolation(BICEP::Interpolation r) or + TLambdaExpression(BICEP::LambdaExpression r) or + TLoopEnumerator(BICEP::LoopEnumerator r) or + TLoopVariable(BICEP::LoopVariable r) or + TMemberExpression(BICEP::MemberExpression r) or + TMetadataDeclaration(BICEP::MetadataDeclaration r) or + TModuleDeclaration(BICEP::ModuleDeclaration r) or + TNegatedType(BICEP::NegatedType r) or + TNull(BICEP::Null r) or + TNullableReturnType(BICEP::NullableReturnType r) or + TNullableType(BICEP::NullableType r) or + TNumber(BICEP::Number r) or + TObject(BICEP::Object r) or + TObjectProperty(BICEP::ObjectProperty r) or + TOutputDeclaration(BICEP::OutputDeclaration r) or + TParameter(BICEP::Parameter r) or + TParameterDeclaration(BICEP::ParameterDeclaration r) or + TParameterizedType(BICEP::ParameterizedType r) or + TParameters(BICEP::Parameters r) or + TParenthesizedExpression(BICEP::ParenthesizedExpression r) or + TParenthesizedType(BICEP::ParenthesizedType r) or + TPrimaryExpression(BICEP::PrimaryExpression r) or + TPrimitiveType(BICEP::PrimitiveType r) or + TPropertyIdentifier(BICEP::PropertyIdentifier r) or + TResourceDeclaration(BICEP::ResourceDeclaration r) or + TResourceExpression(BICEP::ResourceExpression r) or + TStatement(BICEP::Statement r) or + TString(BICEP::String r) or + TStringContent(BICEP::StringContent r) or + TSubscriptExpression(BICEP::SubscriptExpression r) or + TTargetScopeAssignment(BICEP::TargetScopeAssignment r) or + TTernaryExpression(BICEP::TernaryExpression r) or + TTestBlock(BICEP::TestBlock r) or + TType(BICEP::Type r) or + TTypeArguments(BICEP::TypeArguments r) or + TTypeDeclaration(BICEP::TypeDeclaration r) or + TUnaryExpression(BICEP::UnaryExpression r) or + TUnionType(BICEP::UnionType r) or + TUserDefinedFunction(BICEP::UserDefinedFunction r) or + TUsingStatement(BICEP::UsingStatement r) or + TVariableDeclaration(BICEP::VariableDeclaration r) + +/** + * A literal value in a Bicep program + */ +class TLiterals = + TInterpolation or TNull or TNullableReturnType or TNullableType or TString or TStringContent; + +/** + * A statement in a Bicep program + */ +class TStmts = + TAssertStatement or TForStatement or TIfStatement or TImportStatement or TImportWithStatement or + TStatement or TUsingStatement; + +/** + * A expersion value in a Bicep program + */ +class TExpr = + TLiterals or TConditionalExpr or TAssignmentExpression or TBinaryExpression or TCallExpression or + TExpression or TLambdaExpression or TMemberExpression or TParenthesizedExpression or + TPrimaryExpression or TResourceExpression or TSubscriptExpression or TTernaryExpression or + TUnaryExpression; + +/** + * A expersion value in a Bicep program + */ +class TConditionalExpr = TIfStatement; + +cached +BICEP::AstNode toTreeSitter(TAstNode n) { + n = TArguments(result) or + n = TArray(result) or + n = TArrayType(result) or + n = TAssertStatement(result) or + n = TAssignmentExpression(result) or + n = TBinaryExpression(result) or + n = TBoolean(result) or + n = TCallExpression(result) or + n = TComment(result) or + n = TCompatibleIdentifier(result) or + n = TDeclaration(result) or + n = TDecorator(result) or + n = TDecorators(result) or + n = TDiagnosticComment(result) or + n = TEscapeSequence(result) or + n = TExpression(result) or + n = TForLoopParameters(result) or + n = TForStatement(result) or + n = TIdentifier(result) or + n = TIfStatement(result) or + n = TImportFunctionality(result) or + n = TImportStatement(result) or + n = TImportWithStatement(result) or + n = TInfrastructure(result) or + n = TInterpolation(result) or + n = TLambdaExpression(result) or + n = TLoopEnumerator(result) or + n = TLoopVariable(result) or + n = TMemberExpression(result) or + n = TMetadataDeclaration(result) or + n = TModuleDeclaration(result) or + n = TNegatedType(result) or + n = TNull(result) or + n = TNullableReturnType(result) or + n = TNullableType(result) or + n = TNumber(result) or + n = TObject(result) or + n = TObjectProperty(result) or + n = TOutputDeclaration(result) or + n = TParameter(result) or + n = TParameterDeclaration(result) or + n = TParameterizedType(result) or + n = TParameters(result) or + n = TParenthesizedExpression(result) or + n = TParenthesizedType(result) or + n = TPrimaryExpression(result) or + n = TPrimitiveType(result) or + n = TPropertyIdentifier(result) or + n = TResourceDeclaration(result) or + n = TResourceExpression(result) or + n = TStatement(result) or + n = TString(result) or + n = TStringContent(result) or + n = TSubscriptExpression(result) or + n = TTargetScopeAssignment(result) or + n = TTernaryExpression(result) or + n = TTestBlock(result) or + n = TType(result) or + n = TTypeArguments(result) or + n = TTypeDeclaration(result) or + n = TUnaryExpression(result) or + n = TUnionType(result) or + n = TUserDefinedFunction(result) or + n = TUsingStatement(result) or + n = TVariableDeclaration(result) +} diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/BinaryExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/BinaryExpression.qll new file mode 100644 index 0000000..ee938a2 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/BinaryExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for BinaryExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A BinaryExpression AST Node. + */ +class BinaryExpressionImpl extends TBinaryExpression, ExprImpl { + private BICEP::BinaryExpression ast; + + override string getAPrimaryQlClass() { result = "BinaryExpression" } + + BinaryExpressionImpl() { this = TBinaryExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Boolean.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Boolean.qll new file mode 100644 index 0000000..27dea6a --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Boolean.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Boolean + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Boolean AST Node. + */ +class BooleanImpl extends TBoolean, AstNode { + private BICEP::Boolean ast; + + override string getAPrimaryQlClass() { result = "Boolean" } + + BooleanImpl() { this = TBoolean(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Call.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Call.qll new file mode 100644 index 0000000..6911557 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Call.qll @@ -0,0 +1,4 @@ + +/** + * Calls + */ diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/CallExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/CallExpression.qll new file mode 100644 index 0000000..f99096c --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/CallExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for CallExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A CallExpression AST Node. + */ +class CallExpressionImpl extends TCallExpression, ExprImpl { + private BICEP::CallExpression ast; + + override string getAPrimaryQlClass() { result = "CallExpression" } + + CallExpressionImpl() { this = TCallExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Comment.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Comment.qll new file mode 100644 index 0000000..a601d1a --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Comment.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for Comment + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Comment + + +/** + * A Comment AST Node. + */ +class CommentImpl extends TComment, CommentImpl { + private BICEP::Comment ast; + + override string getAPrimaryQlClass() { result = "Comment" } + + CommentImpl() { this = TComment(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/CompatibleIdentifier.qll b/bicep/ql/lib/codeql/bicep/ast/internal/CompatibleIdentifier.qll new file mode 100644 index 0000000..4560fff --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/CompatibleIdentifier.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for CompatibleIdentifier + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A CompatibleIdentifier AST Node. + */ +class CompatibleIdentifierImpl extends TCompatibleIdentifier, AstNode { + private BICEP::CompatibleIdentifier ast; + + override string getAPrimaryQlClass() { result = "CompatibleIdentifier" } + + CompatibleIdentifierImpl() { this = TCompatibleIdentifier(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Conditionals.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Conditionals.qll new file mode 100644 index 0000000..1cfbc13 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Conditionals.qll @@ -0,0 +1,17 @@ + +/** + * Conditional statements. + */ +private import codeql.bicep.ast.AstNodes +private import AstNodes +private import TreeSitter +private import Expr + +/** + * Conditional statements. + */ +class ConditionalExprImpl extends ExprImpl, TConditionalExpr { + override string getAPrimaryQlClass() { result = "Conditional" } + + abstract ExprImpl getCondition(); +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Declaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Declaration.qll new file mode 100644 index 0000000..8f99ecb --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Declaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Declaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Declaration AST Node. + */ +class DeclarationImpl extends TDeclaration, AstNode { + private BICEP::Declaration ast; + + override string getAPrimaryQlClass() { result = "Declaration" } + + DeclarationImpl() { this = TDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Decorator.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Decorator.qll new file mode 100644 index 0000000..bdc3a60 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Decorator.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Decorator + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Decorator AST Node. + */ +class DecoratorImpl extends TDecorator, AstNode { + private BICEP::Decorator ast; + + override string getAPrimaryQlClass() { result = "Decorator" } + + DecoratorImpl() { this = TDecorator(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Decorators.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Decorators.qll new file mode 100644 index 0000000..6bf413e --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Decorators.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Decorators + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Decorators AST Node. + */ +class DecoratorsImpl extends TDecorators, AstNode { + private BICEP::Decorators ast; + + override string getAPrimaryQlClass() { result = "Decorators" } + + DecoratorsImpl() { this = TDecorators(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/DiagnosticComment.qll b/bicep/ql/lib/codeql/bicep/ast/internal/DiagnosticComment.qll new file mode 100644 index 0000000..e26484b --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/DiagnosticComment.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for DiagnosticComment + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A DiagnosticComment AST Node. + */ +class DiagnosticCommentImpl extends TDiagnosticComment, AstNode { + private BICEP::DiagnosticComment ast; + + override string getAPrimaryQlClass() { result = "DiagnosticComment" } + + DiagnosticCommentImpl() { this = TDiagnosticComment(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/EscapeSequence.qll b/bicep/ql/lib/codeql/bicep/ast/internal/EscapeSequence.qll new file mode 100644 index 0000000..2f0a4f8 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/EscapeSequence.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for EscapeSequence + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A EscapeSequence AST Node. + */ +class EscapeSequenceImpl extends TEscapeSequence, AstNode { + private BICEP::EscapeSequence ast; + + override string getAPrimaryQlClass() { result = "EscapeSequence" } + + EscapeSequenceImpl() { this = TEscapeSequence(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Expr.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Expr.qll new file mode 100644 index 0000000..b39e463 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Expr.qll @@ -0,0 +1,10 @@ +private import codeql.bicep.ast.AstNodes +private import AstNodes +private import TreeSitter + +/** + * A Bicep expression. + */ +class ExprImpl extends AstNode, TExpr { + override string getAPrimaryQlClass() { result = "Expr" } +} diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Expression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Expression.qll new file mode 100644 index 0000000..01c8921 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Expression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for Expression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A Expression AST Node. + */ +class ExpressionImpl extends TExpression, ExprImpl { + private BICEP::Expression ast; + + override string getAPrimaryQlClass() { result = "Expression" } + + ExpressionImpl() { this = TExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ForLoopParameters.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ForLoopParameters.qll new file mode 100644 index 0000000..f54d50c --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ForLoopParameters.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ForLoopParameters + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ForLoopParameters AST Node. + */ +class ForLoopParametersImpl extends TForLoopParameters, AstNode { + private BICEP::ForLoopParameters ast; + + override string getAPrimaryQlClass() { result = "ForLoopParameters" } + + ForLoopParametersImpl() { this = TForLoopParameters(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ForStatement.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ForStatement.qll new file mode 100644 index 0000000..c512396 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ForStatement.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for ForStatement + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Stmts + + +/** + * A ForStatement AST Node. + */ +class ForStatementImpl extends TForStatement, StmtsImpl { + private BICEP::ForStatement ast; + + override string getAPrimaryQlClass() { result = "ForStatement" } + + ForStatementImpl() { this = TForStatement(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Identifier.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Identifier.qll new file mode 100644 index 0000000..8c15379 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Identifier.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Identifier + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Identifier AST Node. + */ +class IdentifierImpl extends TIdentifier, AstNode { + private BICEP::Identifier ast; + + override string getAPrimaryQlClass() { result = "Identifier" } + + IdentifierImpl() { this = TIdentifier(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/IfStatement.qll b/bicep/ql/lib/codeql/bicep/ast/internal/IfStatement.qll new file mode 100644 index 0000000..ff91130 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/IfStatement.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for IfStatement + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Stmts + + +/** + * A IfStatement AST Node. + */ +class IfStatementImpl extends TIfStatement, StmtsImpl { + private BICEP::IfStatement ast; + + override string getAPrimaryQlClass() { result = "IfStatement" } + + IfStatementImpl() { this = TIfStatement(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ImportFunctionality.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ImportFunctionality.qll new file mode 100644 index 0000000..3e17f86 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ImportFunctionality.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ImportFunctionality + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ImportFunctionality AST Node. + */ +class ImportFunctionalityImpl extends TImportFunctionality, AstNode { + private BICEP::ImportFunctionality ast; + + override string getAPrimaryQlClass() { result = "ImportFunctionality" } + + ImportFunctionalityImpl() { this = TImportFunctionality(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ImportStatement.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ImportStatement.qll new file mode 100644 index 0000000..811d92c --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ImportStatement.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for ImportStatement + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Stmts + + +/** + * A ImportStatement AST Node. + */ +class ImportStatementImpl extends TImportStatement, StmtsImpl { + private BICEP::ImportStatement ast; + + override string getAPrimaryQlClass() { result = "ImportStatement" } + + ImportStatementImpl() { this = TImportStatement(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ImportWithStatement.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ImportWithStatement.qll new file mode 100644 index 0000000..ba6cff7 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ImportWithStatement.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for ImportWithStatement + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Stmts + + +/** + * A ImportWithStatement AST Node. + */ +class ImportWithStatementImpl extends TImportWithStatement, StmtsImpl { + private BICEP::ImportWithStatement ast; + + override string getAPrimaryQlClass() { result = "ImportWithStatement" } + + ImportWithStatementImpl() { this = TImportWithStatement(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Infrastructure.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Infrastructure.qll new file mode 100644 index 0000000..d9177aa --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Infrastructure.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Infrastructure + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Infrastructure AST Node. + */ +class InfrastructureImpl extends TInfrastructure, AstNode { + private BICEP::Infrastructure ast; + + override string getAPrimaryQlClass() { result = "Infrastructure" } + + InfrastructureImpl() { this = TInfrastructure(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Interpolation.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Interpolation.qll new file mode 100644 index 0000000..00d7ff0 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Interpolation.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Interpolation + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A Interpolation AST Node. + */ +class InterpolationImpl extends TInterpolation, ExprImpl { + private BICEP::Interpolation ast; + + override string getAPrimaryQlClass() { result = "Interpolation" } + + InterpolationImpl() { this = TInterpolation(ast) } + + override string toString() { result = ast.toString() } + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/LambdaExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/LambdaExpression.qll new file mode 100644 index 0000000..fe3c03a --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/LambdaExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for LambdaExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A LambdaExpression AST Node. + */ +class LambdaExpressionImpl extends TLambdaExpression, ExprImpl { + private BICEP::LambdaExpression ast; + + override string getAPrimaryQlClass() { result = "LambdaExpression" } + + LambdaExpressionImpl() { this = TLambdaExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Literals.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Literals.qll new file mode 100644 index 0000000..4f71bec --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Literals.qll @@ -0,0 +1,13 @@ +private import codeql.bicep.ast.AstNodes +private import AstNodes +private import TreeSitter + +/** + * Literal statements. + */ +class LiteralsImpl extends AstNode, TLiterals { + override string getAPrimaryQlClass() { result = "Literals" } + + /** Get the value of the literal */ + abstract string getValue(); +} diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/LoopEnumerator.qll b/bicep/ql/lib/codeql/bicep/ast/internal/LoopEnumerator.qll new file mode 100644 index 0000000..d15f6c6 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/LoopEnumerator.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for LoopEnumerator + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A LoopEnumerator AST Node. + */ +class LoopEnumeratorImpl extends TLoopEnumerator, AstNode { + private BICEP::LoopEnumerator ast; + + override string getAPrimaryQlClass() { result = "LoopEnumerator" } + + LoopEnumeratorImpl() { this = TLoopEnumerator(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/LoopVariable.qll b/bicep/ql/lib/codeql/bicep/ast/internal/LoopVariable.qll new file mode 100644 index 0000000..270f2ac --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/LoopVariable.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for LoopVariable + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A LoopVariable AST Node. + */ +class LoopVariableImpl extends TLoopVariable, AstNode { + private BICEP::LoopVariable ast; + + override string getAPrimaryQlClass() { result = "LoopVariable" } + + LoopVariableImpl() { this = TLoopVariable(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Loops.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Loops.qll new file mode 100644 index 0000000..a5ccfae --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Loops.qll @@ -0,0 +1,4 @@ + +/** + * Loop statements are not supported in `bicep` code. + */ \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/MemberExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/MemberExpression.qll new file mode 100644 index 0000000..fd5d0b0 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/MemberExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for MemberExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A MemberExpression AST Node. + */ +class MemberExpressionImpl extends TMemberExpression, ExprImpl { + private BICEP::MemberExpression ast; + + override string getAPrimaryQlClass() { result = "MemberExpression" } + + MemberExpressionImpl() { this = TMemberExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/MetadataDeclaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/MetadataDeclaration.qll new file mode 100644 index 0000000..91d7ba4 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/MetadataDeclaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for MetadataDeclaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A MetadataDeclaration AST Node. + */ +class MetadataDeclarationImpl extends TMetadataDeclaration, AstNode { + private BICEP::MetadataDeclaration ast; + + override string getAPrimaryQlClass() { result = "MetadataDeclaration" } + + MetadataDeclarationImpl() { this = TMetadataDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ModuleDeclaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ModuleDeclaration.qll new file mode 100644 index 0000000..4707da2 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ModuleDeclaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ModuleDeclaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ModuleDeclaration AST Node. + */ +class ModuleDeclarationImpl extends TModuleDeclaration, AstNode { + private BICEP::ModuleDeclaration ast; + + override string getAPrimaryQlClass() { result = "ModuleDeclaration" } + + ModuleDeclarationImpl() { this = TModuleDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/NegatedType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/NegatedType.qll new file mode 100644 index 0000000..c4971a3 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/NegatedType.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for NegatedType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A NegatedType AST Node. + */ +class NegatedTypeImpl extends TNegatedType, AstNode { + private BICEP::NegatedType ast; + + override string getAPrimaryQlClass() { result = "NegatedType" } + + NegatedTypeImpl() { this = TNegatedType(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Null.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Null.qll new file mode 100644 index 0000000..0abc401 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Null.qll @@ -0,0 +1,30 @@ +/** + * Internal implementation for Null + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Literals + + +/** + * A Null AST Node. + */ +class NullImpl extends TNull, LiteralsImpl { + private BICEP::Null ast; + + override string getAPrimaryQlClass() { result = "Null" } + + NullImpl() { this = TNull(ast) } + + override string toString() { result = ast.toString() } + /** + * Get the literal value + */ + override string getValue() { result = ast.getValue() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/NullableReturnType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/NullableReturnType.qll new file mode 100644 index 0000000..4f30100 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/NullableReturnType.qll @@ -0,0 +1,30 @@ +/** + * Internal implementation for NullableReturnType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Literals + + +/** + * A NullableReturnType AST Node. + */ +class NullableReturnTypeImpl extends TNullableReturnType, LiteralsImpl { + private BICEP::NullableReturnType ast; + + override string getAPrimaryQlClass() { result = "NullableReturnType" } + + NullableReturnTypeImpl() { this = TNullableReturnType(ast) } + + override string toString() { result = ast.toString() } + /** + * Get the literal value + */ + override string getValue() { result = ast.getValue() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/NullableType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/NullableType.qll new file mode 100644 index 0000000..ad2cc21 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/NullableType.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for NullableType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A NullableType AST Node. + */ +class NullableTypeImpl extends TNullableType, ExprImpl { + private BICEP::NullableType ast; + + override string getAPrimaryQlClass() { result = "NullableType" } + + NullableTypeImpl() { this = TNullableType(ast) } + + override string toString() { result = ast.toString() } + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Number.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Number.qll new file mode 100644 index 0000000..d25d9cd --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Number.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Number + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Number AST Node. + */ +class NumberImpl extends TNumber, AstNode { + private BICEP::Number ast; + + override string getAPrimaryQlClass() { result = "Number" } + + NumberImpl() { this = TNumber(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Object.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Object.qll new file mode 100644 index 0000000..0664f00 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Object.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Object + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Object AST Node. + */ +class ObjectImpl extends TObject, AstNode { + private BICEP::Object ast; + + override string getAPrimaryQlClass() { result = "Object" } + + ObjectImpl() { this = TObject(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ObjectProperty.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ObjectProperty.qll new file mode 100644 index 0000000..38d26eb --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ObjectProperty.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ObjectProperty + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ObjectProperty AST Node. + */ +class ObjectPropertyImpl extends TObjectProperty, AstNode { + private BICEP::ObjectProperty ast; + + override string getAPrimaryQlClass() { result = "ObjectProperty" } + + ObjectPropertyImpl() { this = TObjectProperty(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/OutputDeclaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/OutputDeclaration.qll new file mode 100644 index 0000000..f5e27b8 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/OutputDeclaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for OutputDeclaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A OutputDeclaration AST Node. + */ +class OutputDeclarationImpl extends TOutputDeclaration, AstNode { + private BICEP::OutputDeclaration ast; + + override string getAPrimaryQlClass() { result = "OutputDeclaration" } + + OutputDeclarationImpl() { this = TOutputDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Parameter.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Parameter.qll new file mode 100644 index 0000000..5754a8a --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Parameter.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Parameter + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Parameter AST Node. + */ +class ParameterImpl extends TParameter, AstNode { + private BICEP::Parameter ast; + + override string getAPrimaryQlClass() { result = "Parameter" } + + ParameterImpl() { this = TParameter(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ParameterDeclaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ParameterDeclaration.qll new file mode 100644 index 0000000..d6d0525 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ParameterDeclaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ParameterDeclaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ParameterDeclaration AST Node. + */ +class ParameterDeclarationImpl extends TParameterDeclaration, AstNode { + private BICEP::ParameterDeclaration ast; + + override string getAPrimaryQlClass() { result = "ParameterDeclaration" } + + ParameterDeclarationImpl() { this = TParameterDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ParameterizedType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ParameterizedType.qll new file mode 100644 index 0000000..f6e04f0 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ParameterizedType.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ParameterizedType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ParameterizedType AST Node. + */ +class ParameterizedTypeImpl extends TParameterizedType, AstNode { + private BICEP::ParameterizedType ast; + + override string getAPrimaryQlClass() { result = "ParameterizedType" } + + ParameterizedTypeImpl() { this = TParameterizedType(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Parameters.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Parameters.qll new file mode 100644 index 0000000..a870612 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Parameters.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Parameters + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Parameters AST Node. + */ +class ParametersImpl extends TParameters, AstNode { + private BICEP::Parameters ast; + + override string getAPrimaryQlClass() { result = "Parameters" } + + ParametersImpl() { this = TParameters(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ParenthesizedExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ParenthesizedExpression.qll new file mode 100644 index 0000000..8264194 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ParenthesizedExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for ParenthesizedExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A ParenthesizedExpression AST Node. + */ +class ParenthesizedExpressionImpl extends TParenthesizedExpression, ExprImpl { + private BICEP::ParenthesizedExpression ast; + + override string getAPrimaryQlClass() { result = "ParenthesizedExpression" } + + ParenthesizedExpressionImpl() { this = TParenthesizedExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ParenthesizedType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ParenthesizedType.qll new file mode 100644 index 0000000..7a49160 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ParenthesizedType.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ParenthesizedType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ParenthesizedType AST Node. + */ +class ParenthesizedTypeImpl extends TParenthesizedType, AstNode { + private BICEP::ParenthesizedType ast; + + override string getAPrimaryQlClass() { result = "ParenthesizedType" } + + ParenthesizedTypeImpl() { this = TParenthesizedType(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/PrimaryExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/PrimaryExpression.qll new file mode 100644 index 0000000..42fbbd9 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/PrimaryExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for PrimaryExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A PrimaryExpression AST Node. + */ +class PrimaryExpressionImpl extends TPrimaryExpression, ExprImpl { + private BICEP::PrimaryExpression ast; + + override string getAPrimaryQlClass() { result = "PrimaryExpression" } + + PrimaryExpressionImpl() { this = TPrimaryExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/PrimitiveType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/PrimitiveType.qll new file mode 100644 index 0000000..b630753 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/PrimitiveType.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for PrimitiveType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A PrimitiveType AST Node. + */ +class PrimitiveTypeImpl extends TPrimitiveType, AstNode { + private BICEP::PrimitiveType ast; + + override string getAPrimaryQlClass() { result = "PrimitiveType" } + + PrimitiveTypeImpl() { this = TPrimitiveType(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/PropertyIdentifier.qll b/bicep/ql/lib/codeql/bicep/ast/internal/PropertyIdentifier.qll new file mode 100644 index 0000000..a62f067 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/PropertyIdentifier.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for PropertyIdentifier + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A PropertyIdentifier AST Node. + */ +class PropertyIdentifierImpl extends TPropertyIdentifier, AstNode { + private BICEP::PropertyIdentifier ast; + + override string getAPrimaryQlClass() { result = "PropertyIdentifier" } + + PropertyIdentifierImpl() { this = TPropertyIdentifier(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ReservedWord.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ReservedWord.qll new file mode 100644 index 0000000..af4c8eb --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ReservedWord.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ReservedWord + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ReservedWord AST Node. + */ +class ReservedWordImpl extends TReservedWord, AstNode { + private BICEP::ReservedWord ast; + + override string getAPrimaryQlClass() { result = "ReservedWord" } + + ReservedWordImpl() { this = TReservedWord(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ResourceDeclaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ResourceDeclaration.qll new file mode 100644 index 0000000..83538cb --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ResourceDeclaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for ResourceDeclaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A ResourceDeclaration AST Node. + */ +class ResourceDeclarationImpl extends TResourceDeclaration, AstNode { + private BICEP::ResourceDeclaration ast; + + override string getAPrimaryQlClass() { result = "ResourceDeclaration" } + + ResourceDeclarationImpl() { this = TResourceDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/ResourceExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/ResourceExpression.qll new file mode 100644 index 0000000..d22a736 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/ResourceExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for ResourceExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A ResourceExpression AST Node. + */ +class ResourceExpressionImpl extends TResourceExpression, ExprImpl { + private BICEP::ResourceExpression ast; + + override string getAPrimaryQlClass() { result = "ResourceExpression" } + + ResourceExpressionImpl() { this = TResourceExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Statement.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Statement.qll new file mode 100644 index 0000000..3356e22 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Statement.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for Statement + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Stmts + + +/** + * A Statement AST Node. + */ +class StatementImpl extends TStatement, StmtsImpl { + private BICEP::Statement ast; + + override string getAPrimaryQlClass() { result = "Statement" } + + StatementImpl() { this = TStatement(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Stmts.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Stmts.qll new file mode 100644 index 0000000..ce8a96a --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Stmts.qll @@ -0,0 +1,11 @@ +private import codeql.bicep.ast.AstNodes +private import AstNodes +private import TreeSitter +private import Expr + +/** + * Generic statement implementation class. + */ +class StmtsImpl extends AstNode, TStmts { + override string getAPrimaryQlClass() { result = "Stmts" } +} diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/String.qll b/bicep/ql/lib/codeql/bicep/ast/internal/String.qll new file mode 100644 index 0000000..d0c05a4 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/String.qll @@ -0,0 +1,32 @@ +/** + * Internal implementation for String + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Literals + + +/** + * A String AST Node. + */ +class StringImpl extends TString, LiteralsImpl { + private BICEP::String ast; + + override string getAPrimaryQlClass() { result = "String" } + + StringImpl() { this = TString(ast) } + + override string toString() { result = ast.toString() } + /** + * Get the literal value + * + * TODO: This is broken. + */ + override string getValue() { result = ast.getChild(_).toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/StringContent.qll b/bicep/ql/lib/codeql/bicep/ast/internal/StringContent.qll new file mode 100644 index 0000000..4bf975b --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/StringContent.qll @@ -0,0 +1,30 @@ +/** + * Internal implementation for StringContent + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Literals + + +/** + * A StringContent AST Node. + */ +class StringContentImpl extends TStringContent, LiteralsImpl { + private BICEP::StringContent ast; + + override string getAPrimaryQlClass() { result = "StringContent" } + + StringContentImpl() { this = TStringContent(ast) } + + override string toString() { result = ast.toString() } + /** + * Get the literal value + */ + override string getValue() { result = ast.getValue() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/SubscriptExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/SubscriptExpression.qll new file mode 100644 index 0000000..aa5bbaf --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/SubscriptExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for SubscriptExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A SubscriptExpression AST Node. + */ +class SubscriptExpressionImpl extends TSubscriptExpression, ExprImpl { + private BICEP::SubscriptExpression ast; + + override string getAPrimaryQlClass() { result = "SubscriptExpression" } + + SubscriptExpressionImpl() { this = TSubscriptExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/TargetScopeAssignment.qll b/bicep/ql/lib/codeql/bicep/ast/internal/TargetScopeAssignment.qll new file mode 100644 index 0000000..3aff938 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/TargetScopeAssignment.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for TargetScopeAssignment + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A TargetScopeAssignment AST Node. + */ +class TargetScopeAssignmentImpl extends TTargetScopeAssignment, AstNode { + private BICEP::TargetScopeAssignment ast; + + override string getAPrimaryQlClass() { result = "TargetScopeAssignment" } + + TargetScopeAssignmentImpl() { this = TTargetScopeAssignment(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/TernaryExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/TernaryExpression.qll new file mode 100644 index 0000000..16e046e --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/TernaryExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for TernaryExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A TernaryExpression AST Node. + */ +class TernaryExpressionImpl extends TTernaryExpression, ExprImpl { + private BICEP::TernaryExpression ast; + + override string getAPrimaryQlClass() { result = "TernaryExpression" } + + TernaryExpressionImpl() { this = TTernaryExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/TestBlock.qll b/bicep/ql/lib/codeql/bicep/ast/internal/TestBlock.qll new file mode 100644 index 0000000..c0fd1e9 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/TestBlock.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for TestBlock + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A TestBlock AST Node. + */ +class TestBlockImpl extends TTestBlock, AstNode { + private BICEP::TestBlock ast; + + override string getAPrimaryQlClass() { result = "TestBlock" } + + TestBlockImpl() { this = TTestBlock(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/TreeSitter.qll b/bicep/ql/lib/codeql/bicep/ast/internal/TreeSitter.qll new file mode 100644 index 0000000..73ad3bd --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/TreeSitter.qll @@ -0,0 +1,836 @@ +/** + * CodeQL library for BICEP + * Automatically generated from the tree-sitter grammar; do not edit + */ + +import codeql.Locations as L + +module BICEP { + /** The base class for all AST nodes */ + class AstNode extends @bicep_ast_node { + /** Gets a string representation of this element. */ + string toString() { result = this.getAPrimaryQlClass() } + + /** Gets the location of this element. */ + final L::Location getLocation() { bicep_ast_node_location(this, result) } + + /** Gets the parent of this element. */ + final AstNode getParent() { bicep_ast_node_parent(this, result, _) } + + /** Gets the index of this node among the children of its parent. */ + final int getParentIndex() { bicep_ast_node_parent(this, _, result) } + + /** Gets a field or child node of this node. */ + AstNode getAFieldOrChild() { none() } + + /** Gets the name of the primary QL class for this element. */ + string getAPrimaryQlClass() { result = "???" } + + /** Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs. */ + string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } + } + + /** A token. */ + class Token extends @bicep_token, AstNode { + /** Gets the value of this token. */ + final string getValue() { bicep_tokeninfo(this, _, result) } + + /** Gets a string representation of this element. */ + final override string toString() { result = this.getValue() } + + /** Gets the name of the primary QL class for this element. */ + override string getAPrimaryQlClass() { result = "Token" } + } + + /** A reserved word. */ + class ReservedWord extends @bicep_reserved_word, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ReservedWord" } + } + + /** A class representing `arguments` nodes. */ + class Arguments extends @bicep_arguments, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Arguments" } + + /** Gets the `i`th child of this node. */ + final Expression getChild(int i) { bicep_arguments_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_arguments_child(this, _, result) } + } + + /** A class representing `array` nodes. */ + class Array extends @bicep_array, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Array" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_array_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_array_child(this, _, result) } + } + + /** A class representing `array_type` nodes. */ + class ArrayType extends @bicep_array_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ArrayType" } + + /** Gets the child of this node. */ + final Type getChild() { bicep_array_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_array_type_def(this, result) } + } + + /** A class representing `assert_statement` nodes. */ + class AssertStatement extends @bicep_assert_statement, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "AssertStatement" } + + /** Gets the node corresponding to the field `name`. */ + final Identifier getName() { bicep_assert_statement_def(this, result, _) } + + /** Gets the child of this node. */ + final Expression getChild() { bicep_assert_statement_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_assert_statement_def(this, result, _) or bicep_assert_statement_def(this, _, result) + } + } + + /** A class representing `assignment_expression` nodes. */ + class AssignmentExpression extends @bicep_assignment_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "AssignmentExpression" } + + /** Gets the node corresponding to the field `left`. */ + final AstNode getLeft() { bicep_assignment_expression_def(this, result, _) } + + /** Gets the node corresponding to the field `right`. */ + final Expression getRight() { bicep_assignment_expression_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_assignment_expression_def(this, result, _) or + bicep_assignment_expression_def(this, _, result) + } + } + + /** A class representing `binary_expression` nodes. */ + class BinaryExpression extends @bicep_binary_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "BinaryExpression" } + + /** Gets the node corresponding to the field `left`. */ + final Expression getLeft() { bicep_binary_expression_def(this, result, _, _) } + + /** Gets the node corresponding to the field `operator`. */ + final string getOperator() { + exists(int value | bicep_binary_expression_def(this, _, value, _) | + result = "!=" and value = 0 + or + result = "!~" and value = 1 + or + result = "%" and value = 2 + or + result = "&&" and value = 3 + or + result = "*" and value = 4 + or + result = "+" and value = 5 + or + result = "-" and value = 6 + or + result = "/" and value = 7 + or + result = "<" and value = 8 + or + result = "<=" and value = 9 + or + result = "==" and value = 10 + or + result = "=~" and value = 11 + or + result = ">" and value = 12 + or + result = ">=" and value = 13 + or + result = "??" and value = 14 + or + result = "|" and value = 15 + or + result = "||" and value = 16 + ) + } + + /** Gets the node corresponding to the field `right`. */ + final Expression getRight() { bicep_binary_expression_def(this, _, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_binary_expression_def(this, result, _, _) or + bicep_binary_expression_def(this, _, _, result) + } + } + + /** A class representing `boolean` tokens. */ + class Boolean extends @bicep_token_boolean, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Boolean" } + } + + /** A class representing `call_expression` nodes. */ + class CallExpression extends @bicep_call_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "CallExpression" } + + /** Gets the node corresponding to the field `arguments`. */ + final Arguments getArguments() { bicep_call_expression_def(this, result, _) } + + /** Gets the node corresponding to the field `function`. */ + final Expression getFunction() { bicep_call_expression_def(this, _, result) } + + /** Gets the child of this node. */ + final NullableReturnType getChild() { bicep_call_expression_child(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_call_expression_def(this, result, _) or + bicep_call_expression_def(this, _, result) or + bicep_call_expression_child(this, result) + } + } + + /** A class representing `comment` tokens. */ + class Comment extends @bicep_token_comment, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Comment" } + } + + /** A class representing `compatible_identifier` nodes. */ + class CompatibleIdentifier extends @bicep_compatible_identifier, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "CompatibleIdentifier" } + + /** Gets the child of this node. */ + final Identifier getChild() { bicep_compatible_identifier_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_compatible_identifier_def(this, result) } + } + + class Declaration extends @bicep_declaration, AstNode { } + + /** A class representing `decorator` nodes. */ + class Decorator extends @bicep_decorator, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Decorator" } + + /** Gets the child of this node. */ + final CallExpression getChild() { bicep_decorator_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_decorator_def(this, result) } + } + + /** A class representing `decorators` nodes. */ + class Decorators extends @bicep_decorators, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Decorators" } + + /** Gets the `i`th child of this node. */ + final Decorator getChild(int i) { bicep_decorators_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_decorators_child(this, _, result) } + } + + /** A class representing `diagnostic_comment` tokens. */ + class DiagnosticComment extends @bicep_token_diagnostic_comment, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "DiagnosticComment" } + } + + /** A class representing `escape_sequence` tokens. */ + class EscapeSequence extends @bicep_token_escape_sequence, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "EscapeSequence" } + } + + class Expression extends @bicep_expression, AstNode { } + + /** A class representing `for_loop_parameters` nodes. */ + class ForLoopParameters extends @bicep_for_loop_parameters, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ForLoopParameters" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_for_loop_parameters_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_for_loop_parameters_child(this, _, result) } + } + + /** A class representing `for_statement` nodes. */ + class ForStatement extends @bicep_for_statement, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ForStatement" } + + /** Gets the node corresponding to the field `body`. */ + final AstNode getBody() { bicep_for_statement_def(this, result) } + + /** Gets the node corresponding to the field `initializer`. */ + final Identifier getInitializer() { bicep_for_statement_initializer(this, result) } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_for_statement_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_for_statement_def(this, result) or + bicep_for_statement_initializer(this, result) or + bicep_for_statement_child(this, _, result) + } + } + + /** A class representing `identifier` tokens. */ + class Identifier extends @bicep_token_identifier, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Identifier" } + } + + /** A class representing `if_statement` nodes. */ + class IfStatement extends @bicep_if_statement, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "IfStatement" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_if_statement_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_if_statement_child(this, _, result) } + } + + /** A class representing `import_functionality` nodes. */ + class ImportFunctionality extends @bicep_import_functionality, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ImportFunctionality" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_import_functionality_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_import_functionality_child(this, _, result) } + } + + /** A class representing `import_statement` nodes. */ + class ImportStatement extends @bicep_import_statement, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ImportStatement" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_import_statement_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_import_statement_child(this, _, result) } + } + + /** A class representing `import_with_statement` nodes. */ + class ImportWithStatement extends @bicep_import_with_statement, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ImportWithStatement" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_import_with_statement_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_import_with_statement_child(this, _, result) } + } + + /** A class representing `infrastructure` nodes. */ + class Infrastructure extends @bicep_infrastructure, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Infrastructure" } + + /** Gets the `i`th child of this node. */ + final Statement getChild(int i) { bicep_infrastructure_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_infrastructure_child(this, _, result) } + } + + /** A class representing `interpolation` nodes. */ + class Interpolation extends @bicep_interpolation, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Interpolation" } + + /** Gets the child of this node. */ + final Expression getChild() { bicep_interpolation_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_interpolation_def(this, result) } + } + + /** A class representing `lambda_expression` nodes. */ + class LambdaExpression extends @bicep_lambda_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "LambdaExpression" } + + /** Gets the `i`th child of this node. */ + final Expression getChild(int i) { bicep_lambda_expression_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_lambda_expression_child(this, _, result) } + } + + /** A class representing `loop_enumerator` tokens. */ + class LoopEnumerator extends @bicep_token_loop_enumerator, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "LoopEnumerator" } + } + + /** A class representing `loop_variable` tokens. */ + class LoopVariable extends @bicep_token_loop_variable, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "LoopVariable" } + } + + /** A class representing `member_expression` nodes. */ + class MemberExpression extends @bicep_member_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "MemberExpression" } + + /** Gets the node corresponding to the field `object`. */ + final AstNode getObject() { bicep_member_expression_def(this, result, _) } + + /** Gets the node corresponding to the field `property`. */ + final PropertyIdentifier getProperty() { bicep_member_expression_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_member_expression_def(this, result, _) or bicep_member_expression_def(this, _, result) + } + } + + /** A class representing `metadata_declaration` nodes. */ + class MetadataDeclaration extends @bicep_metadata_declaration, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "MetadataDeclaration" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_metadata_declaration_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_metadata_declaration_child(this, _, result) } + } + + /** A class representing `module_declaration` nodes. */ + class ModuleDeclaration extends @bicep_module_declaration, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ModuleDeclaration" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_module_declaration_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_module_declaration_child(this, _, result) } + } + + /** A class representing `negated_type` nodes. */ + class NegatedType extends @bicep_negated_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "NegatedType" } + + /** Gets the child of this node. */ + final Type getChild() { bicep_negated_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_negated_type_def(this, result) } + } + + /** A class representing `null` tokens. */ + class Null extends @bicep_token_null, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Null" } + } + + /** A class representing `nullable_return_type` tokens. */ + class NullableReturnType extends @bicep_token_nullable_return_type, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "NullableReturnType" } + } + + /** A class representing `nullable_type` nodes. */ + class NullableType extends @bicep_nullable_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "NullableType" } + + /** Gets the child of this node. */ + final AstNode getChild() { bicep_nullable_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_nullable_type_def(this, result) } + } + + /** A class representing `number` tokens. */ + class Number extends @bicep_token_number, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Number" } + } + + /** A class representing `object` nodes. */ + class Object extends @bicep_object, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Object" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_object_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_object_child(this, _, result) } + } + + /** A class representing `object_property` nodes. */ + class ObjectProperty extends @bicep_object_property, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ObjectProperty" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_object_property_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_object_property_child(this, _, result) } + } + + /** A class representing `output_declaration` nodes. */ + class OutputDeclaration extends @bicep_output_declaration, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "OutputDeclaration" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_output_declaration_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_output_declaration_child(this, _, result) } + } + + /** A class representing `parameter` nodes. */ + class Parameter extends @bicep_parameter, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Parameter" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_parameter_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_parameter_child(this, _, result) } + } + + /** A class representing `parameter_declaration` nodes. */ + class ParameterDeclaration extends @bicep_parameter_declaration, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ParameterDeclaration" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_parameter_declaration_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_parameter_declaration_child(this, _, result) } + } + + /** A class representing `parameterized_type` nodes. */ + class ParameterizedType extends @bicep_parameterized_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ParameterizedType" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_parameterized_type_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_parameterized_type_child(this, _, result) } + } + + /** A class representing `parameters` nodes. */ + class Parameters extends @bicep_parameters, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Parameters" } + + /** Gets the `i`th child of this node. */ + final Parameter getChild(int i) { bicep_parameters_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_parameters_child(this, _, result) } + } + + /** A class representing `parenthesized_expression` nodes. */ + class ParenthesizedExpression extends @bicep_parenthesized_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ParenthesizedExpression" } + + /** Gets the `i`th child of this node. */ + final Expression getChild(int i) { bicep_parenthesized_expression_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_parenthesized_expression_child(this, _, result) + } + } + + /** A class representing `parenthesized_type` nodes. */ + class ParenthesizedType extends @bicep_parenthesized_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ParenthesizedType" } + + /** Gets the child of this node. */ + final Type getChild() { bicep_parenthesized_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_parenthesized_type_def(this, result) } + } + + class PrimaryExpression extends @bicep_primary_expression, AstNode { } + + /** A class representing `primitive_type` tokens. */ + class PrimitiveType extends @bicep_token_primitive_type, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "PrimitiveType" } + } + + /** A class representing `property_identifier` tokens. */ + class PropertyIdentifier extends @bicep_token_property_identifier, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "PropertyIdentifier" } + } + + /** A class representing `resource_declaration` nodes. */ + class ResourceDeclaration extends @bicep_resource_declaration, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ResourceDeclaration" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_resource_declaration_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_resource_declaration_child(this, _, result) } + } + + /** A class representing `resource_expression` nodes. */ + class ResourceExpression extends @bicep_resource_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ResourceExpression" } + + /** Gets the node corresponding to the field `object`. */ + final Expression getObject() { bicep_resource_expression_def(this, result, _) } + + /** Gets the node corresponding to the field `resource`. */ + final Identifier getResource() { bicep_resource_expression_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_resource_expression_def(this, result, _) or + bicep_resource_expression_def(this, _, result) + } + } + + class Statement extends @bicep_statement, AstNode { } + + /** A class representing `string` nodes. */ + class String extends @bicep_string__, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "String" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_string_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_string_child(this, _, result) } + } + + /** A class representing `string_content` tokens. */ + class StringContent extends @bicep_token_string_content, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "StringContent" } + } + + /** A class representing `subscript_expression` nodes. */ + class SubscriptExpression extends @bicep_subscript_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "SubscriptExpression" } + + /** Gets the node corresponding to the field `index`. */ + final Expression getIndex() { bicep_subscript_expression_def(this, result, _) } + + /** Gets the node corresponding to the field `object`. */ + final Expression getObject() { bicep_subscript_expression_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_subscript_expression_def(this, result, _) or + bicep_subscript_expression_def(this, _, result) + } + } + + /** A class representing `target_scope_assignment` nodes. */ + class TargetScopeAssignment extends @bicep_target_scope_assignment, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TargetScopeAssignment" } + + /** Gets the child of this node. */ + final String getChild() { bicep_target_scope_assignment_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_target_scope_assignment_def(this, result) } + } + + /** A class representing `ternary_expression` nodes. */ + class TernaryExpression extends @bicep_ternary_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TernaryExpression" } + + /** Gets the node corresponding to the field `alternative`. */ + final Expression getAlternative() { bicep_ternary_expression_def(this, result, _, _) } + + /** Gets the node corresponding to the field `condition`. */ + final Expression getCondition() { bicep_ternary_expression_def(this, _, result, _) } + + /** Gets the node corresponding to the field `consequence`. */ + final Expression getConsequence() { bicep_ternary_expression_def(this, _, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_ternary_expression_def(this, result, _, _) or + bicep_ternary_expression_def(this, _, result, _) or + bicep_ternary_expression_def(this, _, _, result) + } + } + + /** A class representing `test_block` nodes. */ + class TestBlock extends @bicep_test_block, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TestBlock" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_test_block_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_test_block_child(this, _, result) } + } + + /** A class representing `type` nodes. */ + class Type extends @bicep_type__, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Type" } + + /** Gets the child of this node. */ + final AstNode getChild() { bicep_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_type_def(this, result) } + } + + /** A class representing `type_arguments` nodes. */ + class TypeArguments extends @bicep_type_arguments, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TypeArguments" } + + /** Gets the `i`th child of this node. */ + final String getChild(int i) { bicep_type_arguments_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_type_arguments_child(this, _, result) } + } + + /** A class representing `type_declaration` nodes. */ + class TypeDeclaration extends @bicep_type_declaration, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TypeDeclaration" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_type_declaration_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_type_declaration_child(this, _, result) } + } + + /** A class representing `unary_expression` nodes. */ + class UnaryExpression extends @bicep_unary_expression, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "UnaryExpression" } + + /** Gets the node corresponding to the field `argument`. */ + final Expression getArgument() { bicep_unary_expression_def(this, result, _) } + + /** Gets the node corresponding to the field `operator`. */ + final string getOperator() { + exists(int value | bicep_unary_expression_def(this, _, value) | + result = "!" and value = 0 + or + result = "-" and value = 1 + ) + } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_unary_expression_def(this, result, _) } + } + + /** A class representing `union_type` nodes. */ + class UnionType extends @bicep_union_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "UnionType" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_union_type_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_union_type_child(this, _, result) } + } + + /** A class representing `user_defined_function` nodes. */ + class UserDefinedFunction extends @bicep_user_defined_function, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "UserDefinedFunction" } + + /** Gets the node corresponding to the field `name`. */ + final Identifier getName() { bicep_user_defined_function_def(this, result, _) } + + /** Gets the node corresponding to the field `returns`. */ + final Type getReturns() { bicep_user_defined_function_def(this, _, result) } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_user_defined_function_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + bicep_user_defined_function_def(this, result, _) or + bicep_user_defined_function_def(this, _, result) or + bicep_user_defined_function_child(this, _, result) + } + } + + /** A class representing `using_statement` nodes. */ + class UsingStatement extends @bicep_using_statement, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "UsingStatement" } + + /** Gets the child of this node. */ + final String getChild() { bicep_using_statement_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_using_statement_def(this, result) } + } + + /** A class representing `variable_declaration` nodes. */ + class VariableDeclaration extends @bicep_variable_declaration, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "VariableDeclaration" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { bicep_variable_declaration_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { bicep_variable_declaration_child(this, _, result) } + } +} diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/Type.qll b/bicep/ql/lib/codeql/bicep/ast/internal/Type.qll new file mode 100644 index 0000000..d1906f8 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/Type.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for Type + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A Type AST Node. + */ +class TypeImpl extends TType, AstNode { + private BICEP::Type ast; + + override string getAPrimaryQlClass() { result = "Type" } + + TypeImpl() { this = TType(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/TypeArguments.qll b/bicep/ql/lib/codeql/bicep/ast/internal/TypeArguments.qll new file mode 100644 index 0000000..b83f0a0 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/TypeArguments.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for TypeArguments + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A TypeArguments AST Node. + */ +class TypeArgumentsImpl extends TTypeArguments, AstNode { + private BICEP::TypeArguments ast; + + override string getAPrimaryQlClass() { result = "TypeArguments" } + + TypeArgumentsImpl() { this = TTypeArguments(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/TypeDeclaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/TypeDeclaration.qll new file mode 100644 index 0000000..fcaf7ef --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/TypeDeclaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for TypeDeclaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A TypeDeclaration AST Node. + */ +class TypeDeclarationImpl extends TTypeDeclaration, AstNode { + private BICEP::TypeDeclaration ast; + + override string getAPrimaryQlClass() { result = "TypeDeclaration" } + + TypeDeclarationImpl() { this = TTypeDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/UnaryExpression.qll b/bicep/ql/lib/codeql/bicep/ast/internal/UnaryExpression.qll new file mode 100644 index 0000000..cc6b416 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/UnaryExpression.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for UnaryExpression + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Expr + + +/** + * A UnaryExpression AST Node. + */ +class UnaryExpressionImpl extends TUnaryExpression, ExprImpl { + private BICEP::UnaryExpression ast; + + override string getAPrimaryQlClass() { result = "UnaryExpression" } + + UnaryExpressionImpl() { this = TUnaryExpression(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/UnionType.qll b/bicep/ql/lib/codeql/bicep/ast/internal/UnionType.qll new file mode 100644 index 0000000..e177daf --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/UnionType.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for UnionType + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A UnionType AST Node. + */ +class UnionTypeImpl extends TUnionType, AstNode { + private BICEP::UnionType ast; + + override string getAPrimaryQlClass() { result = "UnionType" } + + UnionTypeImpl() { this = TUnionType(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/UserDefinedFunction.qll b/bicep/ql/lib/codeql/bicep/ast/internal/UserDefinedFunction.qll new file mode 100644 index 0000000..0f3d029 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/UserDefinedFunction.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for UserDefinedFunction + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A UserDefinedFunction AST Node. + */ +class UserDefinedFunctionImpl extends TUserDefinedFunction, AstNode { + private BICEP::UserDefinedFunction ast; + + override string getAPrimaryQlClass() { result = "UserDefinedFunction" } + + UserDefinedFunctionImpl() { this = TUserDefinedFunction(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/UsingStatement.qll b/bicep/ql/lib/codeql/bicep/ast/internal/UsingStatement.qll new file mode 100644 index 0000000..c706fc1 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/UsingStatement.qll @@ -0,0 +1,26 @@ +/** + * Internal implementation for UsingStatement + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes +private import Stmts + + +/** + * A UsingStatement AST Node. + */ +class UsingStatementImpl extends TUsingStatement, StmtsImpl { + private BICEP::UsingStatement ast; + + override string getAPrimaryQlClass() { result = "UsingStatement" } + + UsingStatementImpl() { this = TUsingStatement(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/ast/internal/VariableDeclaration.qll b/bicep/ql/lib/codeql/bicep/ast/internal/VariableDeclaration.qll new file mode 100644 index 0000000..dbea854 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ast/internal/VariableDeclaration.qll @@ -0,0 +1,24 @@ +/** + * Internal implementation for VariableDeclaration + * + * WARNING: this file is generated, do not edit manually + */ +private import AstNodes +private import TreeSitter +private import codeql.bicep.ast.AstNodes + +/** + * A VariableDeclaration AST Node. + */ +class VariableDeclarationImpl extends TVariableDeclaration, AstNode { + private BICEP::VariableDeclaration ast; + + override string getAPrimaryQlClass() { result = "VariableDeclaration" } + + VariableDeclarationImpl() { this = TVariableDeclaration(ast) } + + override string toString() { result = ast.toString() } + + + +} \ No newline at end of file diff --git a/bicep/ql/lib/codeql/bicep/controlflow/BasicBlocks.qll b/bicep/ql/lib/codeql/bicep/controlflow/BasicBlocks.qll new file mode 100644 index 0000000..2b0d430 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/controlflow/BasicBlocks.qll @@ -0,0 +1,167 @@ +/** + * Provides classes representing basic blocks. + */ + +// AST +private import codeql.bicep.AST +private import codeql.Locations +private import codeql.bicep.ast.internal.AstNodes +private import codeql.bicep.ast.internal.TreeSitter +// CFG +private import ControlFlowGraph +private import internal.SuccessorType +private import internal.ControlFlowGraphImpl as CfgImpl + +/** + * A basic block. + */ +final class BasicBlock = BasicBlockImpl; + +/** + * A basic block, that is, a maximal straight-line sequence of control flow nodes + * without branches or joins. + */ +private class BasicBlockImpl extends TBasicBlockStart { + /** Gets the scope of this basic block. */ + final CfgScope getScope() { result = this.getFirstNode().getScope() } + + /** Gets an immediate successor of this basic block, if any. */ + BasicBlock getASuccessor() { result = this.getASuccessor(_) } + + /** Gets an immediate successor of this basic block of a given type, if any. */ + BasicBlock getASuccessor(SuccessorType t) { + result.getFirstNode() = this.getLastNode().getASuccessor(t) + } + + /** Gets an immediate predecessor of this basic block, if any. */ + BasicBlock getAPredecessor() { result.getASuccessor() = this } + + /** Gets an immediate predecessor of this basic block of a given type, if any. */ + BasicBlock getAPredecessor(SuccessorType t) { result.getASuccessor(t) = this } + + /** Gets the control flow node at a specific (zero-indexed) position in this basic block. */ + CfgNode getNode(int pos) { bbIndex(this.getFirstNode(), result, pos) } + + /** Gets a control flow node in this basic block. */ + CfgNode getANode() { result = this.getNode(_) } + + /** Gets the first control flow node in this basic block. */ + CfgNode getFirstNode() { this = TBasicBlockStart(result) } + + /** Gets the last control flow node in this basic block. */ + CfgNode getLastNode() { result = this.getNode(this.length() - 1) } + + /** Gets the length of this basic block. */ + int length() { result = strictcount(this.getANode()) } + + predicate immediatelyDominates(BasicBlock bb) { bbIDominates(this, bb) } + + predicate strictlyDominates(BasicBlock bb) { bbIDominates+(this, bb) } + + predicate dominates(BasicBlock bb) { + bb = this or + this.strictlyDominates(bb) + } + + predicate inDominanceFrontier(BasicBlock df) { + this.dominatesPredecessor(df) and + not this.strictlyDominates(df) + } + + private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) } + + BasicBlock getImmediateDominator() { bbIDominates(result, this) } + + predicate strictlyPostDominates(BasicBlock bb) { bbIPostDominates+(this, bb) } + + predicate postDominates(BasicBlock bb) { + this.strictlyPostDominates(bb) or + this = bb + } + + /** Holds if this basic block is in a loop in the control flow graph. */ + predicate inLoop() { this.getASuccessor+() = this } + + /** Gets a textual representation of this basic block. */ + string toString() { result = this.getFirstNode().toString() } + + /** Gets the location of this basic block. */ + Location getLocation() { result = this.getFirstNode().getLocation() } +} + + +cached +private module Cached { + /** Internal representation of basic blocks. */ + cached + newtype TBasicBlock = TBasicBlockStart(CfgNode cfn) { startsBB(cfn) } + + /** Holds if `cfn` starts a new basic block. */ + private predicate startsBB(CfgNode cfn) { + not exists(cfn.getAPredecessor()) and exists(cfn.getASuccessor()) + } + + /** + * Holds if `succ` is a control flow successor of `pred` within + * the same basic block. + */ + private predicate intraBBSucc(CfgNode pred, CfgNode succ) { + succ = pred.getASuccessor() and + not startsBB(succ) + } + + /** + * Holds if `cfn` is the `i`th node in basic block `bb`. + * + * In other words, `i` is the shortest distance from a node `bb` + * that starts a basic block to `cfn` along the `intraBBSucc` relation. + */ + cached + predicate bbIndex(CfgNode bbStart, CfgNode cfn, int i) = + shortestDistances(startsBB/1, intraBBSucc/2)(bbStart, cfn, i) + + /** + * Holds if the first node of basic block `succ` is a control flow + * successor of the last node of basic block `pred`. + */ + private predicate succBB(BasicBlock pred, BasicBlock succ) { succ = pred.getASuccessor() } + + /** Holds if `dom` is an immediate dominator of `bb`. */ + cached + predicate bbIDominates(BasicBlock dom, BasicBlock bb) = + idominance(entryBB/1, succBB/2)(_, dom, bb) + + /** Holds if `pred` is a basic block predecessor of `succ`. */ + private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) } + + /** Holds if `bb` is an exit basic block that represents normal exit. */ + private predicate normalExitBB(BasicBlock bb) { + bb.getANode().(CfgImpl::AnnotatedExitNode).isNormal() + } + + /** Holds if `dom` is an immediate post-dominator of `bb`. */ + cached + predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) = + idominance(normalExitBB/1, predBB/2)(_, dom, bb) +} + +private import Cached + +/** Holds if `bb` is an entry basic block. */ +private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof CfgImpl::EntryNode } + +/** + * An entry basic block, that is, a basic block whose first node is + * an entry node. + */ +class EntryBasicBlock extends BasicBlock { + EntryBasicBlock() { entryBB(this) } +} + +/** + * An exit basic block, that is, a basic block whose last node is + * an exit node. + */ +class ExitBasicBlock extends BasicBlock { + ExitBasicBlock() { this.getLastNode() instanceof CfgImpl::ExitNode } +} diff --git a/bicep/ql/lib/codeql/bicep/controlflow/ControlFlowGraph.qll b/bicep/ql/lib/codeql/bicep/controlflow/ControlFlowGraph.qll new file mode 100644 index 0000000..df7d5b4 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/controlflow/ControlFlowGraph.qll @@ -0,0 +1,68 @@ +/** + * Provides classes representing the control flow graph. + */ + +private import bicep +private import internal.ControlFlowGraphImpl +private import internal.Completion +private import internal.Scope as Scope +private import internal.SuccessorType +private import internal.Splitting as Splitting +private import BasicBlocks + +/** + * An AST node with an associated control-flow graph. + * + * Top-levels, methods, blocks, and lambdas are all CFG scopes. + * + * Note that module declarations are not themselves CFG scopes, as they are part of + * the CFG of the enclosing top-level or callable. + */ +final class CfgScope = Scope::CfgScope; + +final class SuccessorType = SuccessorTypeImpl; + +final class NormalSuccessor = NormalSuccessorImpl; + +final class ConditionalSuccessor = ConditionalSuccessorImpl; + +final class BooleanSuccessor = BooleanSuccessorImpl; + +final class BreakSuccessor = BreakSuccessorImpl; + +final class ContinueSuccessor = ContinueSuccessorImpl; + +final class ReturnSuccessor = ReturnSuccessorImpl; + +/** + * A control flow node. + * + * A control flow node is a node in the control flow graph (CFG). There is a + * many-to-one relationship between CFG nodes and AST nodes. + * + * Only nodes that can be reached from an entry point are included in the CFG. + */ +final class CfgNode extends Node { + /** Gets the file of this control flow node. */ + File getFile() { result = this.getLocation().getFile() } + + /** Gets a successor node of a given type, if any. */ + CfgNode getASuccessor(SuccessorType t) { result = super.getASuccessor(t) } + + /** Gets an immediate successor, if any. */ + CfgNode getASuccessor() { result = this.getASuccessor(_) } + + /** Gets an immediate predecessor node of a given flow type, if any. */ + CfgNode getAPredecessor(SuccessorType t) { result.getASuccessor(t) = this } + + /** Gets an immediate predecessor, if any. */ + CfgNode getAPredecessor() { result = this.getAPredecessor(_) } + + /** Gets the basic block that this control flow node belongs to. */ + BasicBlock getBasicBlock() { result.getANode() = this } +} + +/** + * A control flow split. + */ +class Split = Splitting::Split; diff --git a/bicep/ql/lib/codeql/bicep/controlflow/internal/Completion.qll b/bicep/ql/lib/codeql/bicep/controlflow/internal/Completion.qll new file mode 100644 index 0000000..e8c2d4e --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/controlflow/internal/Completion.qll @@ -0,0 +1,91 @@ +private import codeql.util.Boolean +private import codeql.bicep.controlflow.ControlFlowGraph +private import bicep +private import SuccessorType + +newtype TCompletion = + TSimpleCompletion() or + TBooleanCompletion(Boolean b) or + TReturnCompletion() + +abstract class Completion extends TCompletion { + abstract string toString(); + + predicate isValidForSpecific(AstNode e) { none() } + + predicate isValidFor(AstNode e) { this.isValidForSpecific(e) } + + abstract SuccessorType getAMatchingSuccessorType(); +} + +abstract class NormalCompletion extends Completion { } + +class SimpleCompletion extends NormalCompletion, TSimpleCompletion { + override string toString() { result = "SimpleCompletion" } + + override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) } + + override NormalSuccessor getAMatchingSuccessorType() { any() } +} + +/** + * A completion that represents evaluation of an expression, whose value + * determines the successor. + */ +abstract class ConditionalCompletion extends NormalCompletion { + boolean value; + + bindingset[value] + ConditionalCompletion() { any() } + + /** Gets the Boolean value of this conditional completion. */ + final boolean getValue() { result = value } + + final predicate succeeded() { value = true } + + final predicate failed() { value = false } + + /** Gets the dual completion. */ + abstract ConditionalCompletion getDual(); +} + +class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion { + BooleanCompletion() { this = TBooleanCompletion(value) } + + override string toString() { result = "boolean(" + value + ")" } + + /** + * Implements valid completions for expressions. + * + * TODO: This is a placeholder implementation. + */ + override predicate isValidForSpecific(AstNode e) { + // Example: + // e = any(ForLoop c).getCondition() + none() + } + + /** Gets the dual Boolean completion. */ + override BooleanCompletion getDual() { result = TBooleanCompletion(value.booleanNot()) } + + override BooleanSuccessor getAMatchingSuccessorType() { result.getValue() = value } + + final boolean getValue() { result = value } +} + +class ReturnCompletion extends Completion, TReturnCompletion { + override string toString() { result = "ReturnCompletion" } + + override predicate isValidForSpecific(AstNode e) { none() } + + override ReturnSuccessor getAMatchingSuccessorType() { any() } +} + +/** Hold if `c` represents normal evaluation of a statement or an expression. */ +predicate completionIsNormal(Completion c) { c instanceof NormalCompletion } + +/** Hold if `c` represents simple and normal evaluation of a statement or an expression. */ +predicate completionIsSimple(Completion c) { c instanceof SimpleCompletion } + +/** Holds if `c` is a valid completion for `n`. */ +predicate completionIsValidFor(Completion c, AstNode n) { c.isValidFor(n) } diff --git a/bicep/ql/lib/codeql/bicep/controlflow/internal/ControlFlowGraphImpl.qll b/bicep/ql/lib/codeql/bicep/controlflow/internal/ControlFlowGraphImpl.qll new file mode 100644 index 0000000..ceda049 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/controlflow/internal/ControlFlowGraphImpl.qll @@ -0,0 +1,93 @@ +/** + * Internal: Control flow graph construction for Bicep. + */ + +private import bicep +// CFG +import codeql.controlflow.Cfg +import Completion +private import Scope as Scope +private import codeql.bicep.controlflow.ControlFlowGraph as Cfg + +// private import codeql.Locations +private module Implementation implements InputSig { + private import bicep as Bicep + private import Completion as C + private import Splitting as S + + class AstNode = Bicep::AstNode; + + class Completion = C::Completion; + + predicate completionIsNormal = C::completionIsNormal/1; + + predicate completionIsSimple = C::completionIsSimple/1; + + predicate completionIsValidFor = C::completionIsValidFor/2; + + /** An AST node with an associated control-flow graph. */ + class CfgScope = Scope::CfgScope; + + class SplitKindBase = S::TSplitKind; + + class Split = S::Split; + + class SuccessorType = Cfg::SuccessorType; + + CfgScope getCfgScope(AstNode e) { + exists(AstNode p | p = e.getParent() | + result = p + or + not p instanceof CfgScope and result = getCfgScope(p) + ) + } + + int maxSplits() { result = 0 } + + /** Holds if `first` is first executed when entering `scope`. */ + predicate scopeFirst(CfgScope scope, AstNode first) { scope.scopeFirst(first) } + + /** Holds if `scope` is exited when `last` finishes with completion `c`. */ + predicate scopeLast(CfgScope scope, AstNode last, Completion c) { scope.scopeLast(last, c) } + + predicate successorTypeIsSimple(SuccessorType t) { t instanceof Cfg::NormalSuccessor } + + predicate successorTypeIsCondition(SuccessorType t) { t instanceof Cfg::BooleanSuccessor } + + SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() } + + predicate isAbnormalExitType(SuccessorType t) { none() } +} + +private module CfgImpl = Make; + +import CfgImpl + +/** + * A literal value in a Bicep program. + */ +class LiteralTree extends LeafTree instanceof Literals { } +/** + * A Interpolation literal value in a Bicep program. + */ +class InterpolationLiteralTree extends LeafTree instanceof InterpolationLiteral { } +/** + * A Null literal value in a Bicep program. + */ +class NullLiteralTree extends LeafTree instanceof NullLiteral { } +/** + * A NullableReturnType literal value in a Bicep program. + */ +class NullableReturnTypeLiteralTree extends LeafTree instanceof NullableReturnTypeLiteral { } +/** + * A NullableType literal value in a Bicep program. + */ +class NullableTypeLiteralTree extends LeafTree instanceof NullableTypeLiteral { } +/** + * A String literal value in a Bicep program. + */ +class StringLiteralTree extends LeafTree instanceof StringLiteral { } +/** + * A StringContent literal value in a Bicep program. + */ +class StringContentLiteralTree extends LeafTree instanceof StringContentLiteral { } diff --git a/bicep/ql/lib/codeql/bicep/controlflow/internal/Scope.qll b/bicep/ql/lib/codeql/bicep/controlflow/internal/Scope.qll new file mode 100644 index 0000000..9ebdd27 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/controlflow/internal/Scope.qll @@ -0,0 +1,12 @@ +private import bicep +private import codeql.bicep.AST +private import Completion +private import ControlFlowGraphImpl + +abstract class CfgScope extends AstNode { + /** Holds if `first` is executed first when entering scope. */ + abstract predicate scopeFirst(AstNode first); + + /** Holds if scope is exited when `last` finishes with completion `c`. */ + abstract predicate scopeLast(AstNode last, Completion c); +} diff --git a/bicep/ql/lib/codeql/bicep/controlflow/internal/Splitting.qll b/bicep/ql/lib/codeql/bicep/controlflow/internal/Splitting.qll new file mode 100644 index 0000000..b4f0a06 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/controlflow/internal/Splitting.qll @@ -0,0 +1,17 @@ +cached +private module Cached { + // Not using CFG splitting, so the following are just placeholder types. + cached + newtype TSplitKind = TSplitKindUnit() + + cached + newtype TSplit = TSplitUnit() +} + +import Cached + +/** A split for a control flow node. */ +class Split extends TSplit { + /** Gets a textual representation of this split. */ + string toString() { none() } +} diff --git a/bicep/ql/lib/codeql/bicep/controlflow/internal/SuccessorType.qll b/bicep/ql/lib/codeql/bicep/controlflow/internal/SuccessorType.qll new file mode 100644 index 0000000..2f04e01 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/controlflow/internal/SuccessorType.qll @@ -0,0 +1,64 @@ +private import codeql.util.Boolean +private import Completion + +newtype TLoopJumpType = + TContinueJump() or + TBreakJump() + +cached +newtype TSuccessorType = + TSuccessorSuccessor() or + TBooleanSuccessor(Boolean b) or + TBreakSuccessor() or + TContinueSuccessor() or + TReturnSuccessor() + +/** The type of a control flow successor. */ +abstract class SuccessorTypeImpl extends TSuccessorType { + /** Gets a textual representation of successor type. */ + abstract string toString(); +} + +/** A normal control flow successor. */ +class NormalSuccessorImpl extends SuccessorTypeImpl, TSuccessorSuccessor { + override string toString() { result = "successor" } +} + +/** A conditional control flow successor. */ +abstract class ConditionalSuccessorImpl extends SuccessorTypeImpl { + boolean value; + + bindingset[value] + ConditionalSuccessorImpl() { exists(value) } + + /** Gets the Boolean value of this successor. */ + boolean getValue() { result = value } +} + +/** A Boolean control flow successor for a boolean conditon. */ +class BooleanSuccessorImpl extends ConditionalSuccessorImpl, TBooleanSuccessor { + BooleanSuccessorImpl() { this = TBooleanSuccessor(value) } + + override string toString() { result = "BooleanSuccessor" } +} + +/** + * A control flow successor of a `break` expression. + */ +class BreakSuccessorImpl extends SuccessorTypeImpl, TBreakSuccessor { + override string toString() { result = "break" } +} + +/** + * A control flow successor of a `continue` expression. + */ +class ContinueSuccessorImpl extends SuccessorTypeImpl, TContinueSuccessor { + override string toString() { result = "continue" } +} + +/** + * A `return` control flow successor. + */ +class ReturnSuccessorImpl extends SuccessorTypeImpl, TReturnSuccessor { + override string toString() { result = "return" } +} diff --git a/bicep/ql/lib/codeql/bicep/ideContextual/IDEContextual.qll b/bicep/ql/lib/codeql/bicep/ideContextual/IDEContextual.qll new file mode 100644 index 0000000..0e58b1d --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ideContextual/IDEContextual.qll @@ -0,0 +1,19 @@ +private import codeql.files.FileSystem + +/** + * Returns an appropriately encoded version of a filename `name` + * passed by the VS Code extension in order to coincide with the + * output of `.getFile()` on locatable entities. + */ +cached +File getFileBySourceArchiveName(string name) { + // The name provided for a file in the source archive by the VS Code extension + // has some differences from the absolute path in the database: + // 1. colons are replaced by underscores + // 2. there's a leading slash, even for Windows paths: "C:/foo/bar" -> + // "/C_/foo/bar" + // 3. double slashes in UNC prefixes are replaced with a single slash + // We can handle 2 and 3 together by unconditionally adding a leading slash + // before replacing double slashes. + name = ("/" + result.getAbsolutePath().replaceAll(":", "_")).replaceAll("//", "/") +} diff --git a/bicep/ql/lib/codeql/bicep/ideContextual/printAstAst.qll b/bicep/ql/lib/codeql/bicep/ideContextual/printAstAst.qll new file mode 100644 index 0000000..0d9399c --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ideContextual/printAstAst.qll @@ -0,0 +1,102 @@ +/** + * Provides queries to pretty-print a QL abstract syntax tree as a graph. + * + * This representation is based on the user-facing AST implementation. + * + * By default, this will print the AST for all nodes in the database. To change + * this behavior, extend `PrintASTConfiguration` and override `shouldPrintNode` + * to hold for only the AST nodes you wish to view. + */ + +import codeql.bicep.ast.AstNodes +private import codeql.Locations +import codeql.bicep.ast.internal.AstNodes + +/** + * The query can extend this class to control which nodes are printed. + */ +class PrintAstConfiguration extends string { + PrintAstConfiguration() { this = "PrintAstConfiguration" } + + /** + * Holds if the given node should be printed. + */ + predicate shouldPrintNode(AstNode n) { any() } +} + +/** + * Gets the `i`th child of parent. + * The ordering is location based and pretty arbitrary. + */ +AstNode getAstChild(PrintAstNode parent, int i) { + result = + rank[i](AstNode child, Location l | + child.getParent() = parent and + child.getLocation() = l + | + child + order by + l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString() + ) +} + +/** + * A node in the output tree. + */ +class PrintAstNode extends AstNode { + PrintAstNode() { shouldPrintNode(this) } + + string getProperty(string key) { + key = "semmle.label" and + result = "[" + concat(this.getAPrimaryQlClass(), ", ") + "] " + this.toString() + or + key = "semmle.order" and + result = + any(int i | + this = + rank[i](PrintAstNode p, Location l, File f | + l = p.getLocation() and + f = l.getFile() + | + p order by f.getBaseName(), f.getAbsolutePath(), l.getStartLine(), l.getStartColumn() + ) + ).toString() + } + + /** + * Gets the child node that is accessed using the predicate `edgeName`. + */ + PrintAstNode getChild(string edgeName) { result = this.getAChild(edgeName) } +} + +private predicate shouldPrintNode(AstNode n) { + exists(PrintAstConfiguration config | config.shouldPrintNode(n)) +} + +/** + * Holds if `node` belongs to the output tree, and its property `key` has the + * given `value`. + */ +query predicate nodes(PrintAstNode node, string key, string value) { value = node.getProperty(key) } + +/** + * Holds if `target` is a child of `source` in the AST, and property `key` of + * the edge has the given `value`. + */ +query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) { + target = source.getChild(_) and + ( + key = "semmle.label" and + value = strictconcat(string name | source.getChild(name) = target | name, "/") + or + key = "semmle.order" and + value = target.getProperty("semmle.order") + ) +} + +/** + * Holds if property `key` of the graph has the given `value`. + */ +query predicate graphProperties(string key, string value) { + key = "semmle.graphKind" and value = "tree" +} diff --git a/bicep/ql/lib/codeql/bicep/ideContextual/printAstGenerated.qll b/bicep/ql/lib/codeql/bicep/ideContextual/printAstGenerated.qll new file mode 100644 index 0000000..8a4f831 --- /dev/null +++ b/bicep/ql/lib/codeql/bicep/ideContextual/printAstGenerated.qll @@ -0,0 +1,108 @@ +/** + * Provides queries to pretty-print an HCL abstract syntax tree as a graph. + * + * This representation is based on the TreeSitter auto-generated AST. + * + * By default, this will print the AST for all nodes in the database. To change + * this behavior, extend `PrintASTConfiguration` and override `shouldPrintNode` + * to hold for only the AST nodes you wish to view. + */ + +import codeql.bicep.ast.internal.TreeSitter::BICEP +private import codeql.Locations + +/** + * The query can extend this class to control which nodes are printed. + */ +class PrintAstConfiguration extends string { + PrintAstConfiguration() { this = "PrintAstConfiguration" } + + /** + * Holds if the given node should be printed. + */ + predicate shouldPrintNode(AstNode n) { + not n instanceof Comment + } +} + +/** + * Gets the `i`th child of parent. + * The ordering is location based and pretty arbitrary. + */ +AstNode getAstChild(PrintAstNode parent, int i) { + result = + rank[i](AstNode child, Location l | + child.getParent() = parent and + child.getLocation() = l + | + child + order by + l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString() + ) +} + +/** + * A node in the output tree. + */ +class PrintAstNode extends AstNode { + PrintAstNode() { shouldPrintNode(this) } + + string getProperty(string key) { + key = "semmle.label" and + result = "[" + concat(this.getAPrimaryQlClass(), ", ") + "] " + this.toString() + or + key = "semmle.order" and + result = + any(int i | + this = + rank[i](PrintAstNode p, Location l, File f | + l = p.getLocation() and + f = l.getFile() + | + p order by f.getBaseName(), f.getAbsolutePath(), l.getStartLine(), l.getStartColumn() + ) + ).toString() + } + + /** + * Gets the child node that is accessed using the predicate `edgeName`. + */ + PrintAstNode getChild(string edgeName) { + exists(int i | + result = getAstChild(this, i) and + edgeName = i.toString() + ) + } +} + +private predicate shouldPrintNode(AstNode n) { + exists(PrintAstConfiguration config | config.shouldPrintNode(n)) +} + +/** + * Holds if `node` belongs to the output tree, and its property `key` has the + * given `value`. + */ +query predicate nodes(PrintAstNode node, string key, string value) { value = node.getProperty(key) } + +/** + * Holds if `target` is a child of `source` in the AST, and property `key` of + * the edge has the given `value`. + */ +query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) { + target = source.getChild(_) and + ( + key = "semmle.label" and + value = strictconcat(string name | source.getChild(name) = target | name, "/") + or + key = "semmle.order" and + value = target.getProperty("semmle.order") + ) +} + +/** + * Holds if property `key` of the graph has the given `value`. + */ +query predicate graphProperties(string key, string value) { + key = "semmle.graphKind" and value = "tree" +} diff --git a/bicep/ql/lib/codeql/files/FileSystem.qll b/bicep/ql/lib/codeql/files/FileSystem.qll new file mode 100644 index 0000000..552b85a --- /dev/null +++ b/bicep/ql/lib/codeql/files/FileSystem.qll @@ -0,0 +1,177 @@ +/** Provides classes for working with files and folders. */ + +private import codeql.Locations + +/** A file or folder. */ +abstract class Container extends @container { + /** Gets a file or sub-folder in this container. */ + Container getAChildContainer() { this = result.getParentContainer() } + + /** Gets a file in this container. */ + File getAFile() { result = this.getAChildContainer() } + + /** Gets a sub-folder in this container. */ + Folder getAFolder() { result = this.getAChildContainer() } + + /** + * Gets the absolute, canonical path of this container, using forward slashes + * as path separator. + * + * The path starts with a _root prefix_ followed by zero or more _path + * segments_ separated by forward slashes. + * + * The root prefix is of one of the following forms: + * + * 1. A single forward slash `/` (Unix-style) + * 2. An upper-case drive letter followed by a colon and a forward slash, + * such as `C:/` (Windows-style) + * 3. Two forward slashes, a computer name, and then another forward slash, + * such as `//FileServer/` (UNC-style) + * + * Path segments are never empty (that is, absolute paths never contain two + * contiguous slashes, except as part of a UNC-style root prefix). Also, path + * segments never contain forward slashes, and no path segment is of the + * form `.` (one dot) or `..` (two dots). + * + * Note that an absolute path never ends with a forward slash, except if it is + * a bare root prefix, that is, the path has no path segments. A container + * whose absolute path has no segments is always a `Folder`, not a `File`. + */ + abstract string getAbsolutePath(); + + /** + * Gets the base name of this container including extension, that is, the last + * segment of its absolute path, or the empty string if it has no segments. + * + * Here are some examples of absolute paths and the corresponding base names + * (surrounded with quotes to avoid ambiguity): + * + * + * + * + * + * + * + * + * + *
Absolute pathBase name
"/tmp/tst.go""tst.go"
"C:/Program Files (x86)""Program Files (x86)"
"/"""
"C:/"""
"D:/"""
"//FileServer/"""
+ */ + string getBaseName() { + result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1) + } + + /** + * Gets the extension of this container, that is, the suffix of its base name + * after the last dot character, if any. + * + * In particular, + * + * - if the name does not include a dot, there is no extension, so this + * predicate has no result; + * - if the name ends in a dot, the extension is the empty string; + * - if the name contains multiple dots, the extension follows the last dot. + * + * Here are some examples of absolute paths and the corresponding extensions + * (surrounded with quotes to avoid ambiguity): + * + * + * + * + * + * + * + * + *
Absolute pathExtension
"/tmp/tst.go""go"
"/tmp/.classpath""classpath"
"/bin/bash"not defined
"/tmp/tst2."""
"/tmp/x.tar.gz""gz"
+ */ + string getExtension() { + result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3) + } + + /** Gets the file in this container that has the given `baseName`, if any. */ + File getFile(string baseName) { + result = this.getAFile() and + result.getBaseName() = baseName + } + + /** Gets the sub-folder in this container that has the given `baseName`, if any. */ + Folder getFolder(string baseName) { + result = this.getAFolder() and + result.getBaseName() = baseName + } + + /** Gets the parent container of this file or folder, if any. */ + Container getParentContainer() { containerparent(result, this) } + + /** + * Gets the relative path of this file or folder from the root folder of the + * analyzed source location. The relative path of the root folder itself is + * the empty string. + * + * This has no result if the container is outside the source root, that is, + * if the root folder is not a reflexive, transitive parent of this container. + */ + string getRelativePath() { + exists(string absPath, string pref | + absPath = this.getAbsolutePath() and sourceLocationPrefix(pref) + | + absPath = pref and result = "" + or + absPath = pref.regexpReplaceAll("/$", "") + "/" + result and + not result.matches("/%") + ) + } + + /** + * Gets the stem of this container, that is, the prefix of its base name up to + * (but not including) the last dot character if there is one, or the entire + * base name if there is not. + * + * Here are some examples of absolute paths and the corresponding stems + * (surrounded with quotes to avoid ambiguity): + * + * + * + * + * + * + * + * + *
Absolute pathStem
"/tmp/tst.go""tst"
"/tmp/.classpath"""
"/bin/bash""bash"
"/tmp/tst2.""tst2"
"/tmp/x.tar.gz""x.tar"
+ */ + string getStem() { + result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1) + } + + /** + * Gets a URL representing the location of this container. + * + * For more information see https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls. + */ + abstract string getURL(); + + /** + * Gets a textual representation of the path of this container. + * + * This is the absolute path of the container. + */ + string toString() { result = this.getAbsolutePath() } +} + +/** A folder. */ +class Folder extends Container, @folder { + override string getAbsolutePath() { folders(this, result) } + + /** Gets the URL of this folder. */ + override string getURL() { result = "folder://" + this.getAbsolutePath() } +} + +/** A file. */ +class File extends Container, @file { + override string getAbsolutePath() { files(this, result) } + + /** Gets the URL of this file. */ + override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } + + /** Holds if this file was extracted from ordinary source code. */ + predicate fromSource() { any() } +} diff --git a/bicep/ql/lib/ide-contextual-queries/printAst.ql b/bicep/ql/lib/ide-contextual-queries/printAst.ql new file mode 100644 index 0000000..57cc279 --- /dev/null +++ b/bicep/ql/lib/ide-contextual-queries/printAst.ql @@ -0,0 +1,27 @@ +/** + * @name Print AST + * @description Produces a representation of a file's Abstract Syntax Tree. + * This query is used by the VS Code extension. + * @id bicep/print-ast + * @kind graph + * @tags ide-contextual-queries/print-ast + */ + +private import codeql.IDEContextual +private import codeql.bicep.AST +private import codeql.bicep.ideContextual.printAstAst + +/** + * The source file to generate an AST from. + */ +external string selectedSourceFile(); + +/** + * A configuration that only prints nodes in the selected source file. + */ +class Cfg extends PrintAstConfiguration { + override predicate shouldPrintNode(AstNode n) { + super.shouldPrintNode(n) and + n.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile()) + } +} \ No newline at end of file diff --git a/bicep/ql/lib/ide-contextual-queries/printCfg.ql b/bicep/ql/lib/ide-contextual-queries/printCfg.ql new file mode 100644 index 0000000..c7afc5e --- /dev/null +++ b/bicep/ql/lib/ide-contextual-queries/printCfg.ql @@ -0,0 +1,41 @@ +/** + * @name Print CFG + * @description Produces a representation of a file's Control Flow Graph. + * This query is used by the VS Code extension. + * @id rb/print-cfg + * @kind graph + * @tags ide-contextual-queries/print-cfg + */ + +private import codeql.Locations +private import codeql.bicep.controlflow.internal.ControlFlowGraphImpl +private import codeql.bicep.controlflow.ControlFlowGraph + +external string selectedSourceFile(); + +private predicate selectedSourceFileAlias = selectedSourceFile/0; + +external int selectedSourceLine(); + +private predicate selectedSourceLineAlias = selectedSourceLine/0; + +external int selectedSourceColumn(); + +private predicate selectedSourceColumnAlias = selectedSourceColumn/0; + +module ViewCfgQueryInput implements ViewCfgQueryInputSig { + predicate selectedSourceFile = selectedSourceFileAlias/0; + + predicate selectedSourceLine = selectedSourceLineAlias/0; + + predicate selectedSourceColumn = selectedSourceColumnAlias/0; + + predicate cfgScopeSpan( + CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn + ) { + file = scope.getFile() and + scope.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn) + } +} + +import ViewCfgQuery \ No newline at end of file diff --git a/bicep/ql/lib/qlpack.yml b/bicep/ql/lib/qlpack.yml new file mode 100644 index 0000000..49d5d87 --- /dev/null +++ b/bicep/ql/lib/qlpack.yml @@ -0,0 +1,17 @@ +--- +library: true +warnOnImplicitThis: false +name: advanced-security/bicep-all +version: 0.1.0 +dependencies: + codeql/util: "^1.0.0" + codeql/yaml: "^1.0.0" + codeql/controlflow: "^1.0.0" + codeql/dataflow: "^1.0.0" + codeql/regex: "^1.0.0" + codeql/ssa: "^1.0.0" +dbscheme: bicep.dbscheme +extractor: bicep +upgrades: upgrades +groups: + - bicep \ No newline at end of file diff --git a/bicep/ql/src/codeql-suites/code-scanning.qls b/bicep/ql/src/codeql-suites/code-scanning.qls new file mode 100644 index 0000000..07fe088 --- /dev/null +++ b/bicep/ql/src/codeql-suites/code-scanning.qls @@ -0,0 +1,17 @@ +- description: Standard Code Scanning queries for Bicep +- queries: . + +- include: + kind: + - problem + - path-problem + tags contain: + - security +- include: + kind: + - diagnostic + +- exclude: + tags contain: + - experimental + - testing diff --git a/bicep/ql/src/diagnostics/ExtractionErrors.ql b/bicep/ql/src/diagnostics/ExtractionErrors.ql new file mode 100644 index 0000000..6d7f5f5 --- /dev/null +++ b/bicep/ql/src/diagnostics/ExtractionErrors.ql @@ -0,0 +1,18 @@ +/** + * @name Extraction errors + * @description List all extraction errors for files in the source code directory. + * @kind diagnostic + * @id bicep/diagnostics/extraction-errors + */ + +import bicep +import codeql.bicep.Diagnostics + +/** Gets the SARIF severity to associate an error. */ +int getSeverity() { result = 2 } + +from ExtractionError error, File f +where + f = error.getLocation().getFile() and + exists(f.getRelativePath()) +select error, "Extraction failed in " + f + " with error " + error.getMessage(), getSeverity() diff --git a/bicep/ql/src/diagnostics/SuccessfullyExtractedFiles.ql b/bicep/ql/src/diagnostics/SuccessfullyExtractedFiles.ql new file mode 100644 index 0000000..5db2c38 --- /dev/null +++ b/bicep/ql/src/diagnostics/SuccessfullyExtractedFiles.ql @@ -0,0 +1,18 @@ +/** + * @name Successfully extracted files + * @description Lists all files in the source code directory that were extracted + * without encountering an error in the file. + * @kind diagnostic + * @id bicep/diagnostics/successfully-extracted-files + * @tags successfully-extracted-files + */ + +import bicep +import codeql.bicep.Diagnostics + + +from File f +where + not exists(ExtractionError e | e.getLocation().getFile() = f) and + exists(f.getRelativePath()) +select f, "" diff --git a/bicep/ql/src/qlpack.yml b/bicep/ql/src/qlpack.yml new file mode 100644 index 0000000..654b74e --- /dev/null +++ b/bicep/ql/src/qlpack.yml @@ -0,0 +1,9 @@ +name: advanced-security/bicep-queries +version: 0.1.0 +groups: + - bicep + - queries +dependencies: + advanced-security/bicep-all: ${workspace} +extractor: bicep +defaultSuiteFile: codeql-suites/code-scanning.qls diff --git a/bicep/ql/test/TestUtils.qll b/bicep/ql/test/TestUtils.qll new file mode 100644 index 0000000..34a116f --- /dev/null +++ b/bicep/ql/test/TestUtils.qll @@ -0,0 +1,3 @@ +private import bicep + +predicate toBeTested(AstNode e) { any() } diff --git a/bicep/ql/test/library-tests/ast/AST.ql b/bicep/ql/test/library-tests/ast/AST.ql new file mode 100644 index 0000000..86fa45e --- /dev/null +++ b/bicep/ql/test/library-tests/ast/AST.ql @@ -0,0 +1,5 @@ +private import codeql.bicep.AST + +query predicate astNodes(AstNode n) { any() } + +query predicate literals(Literals l) { any() } diff --git a/bicep/ql/test/library-tests/cfg/CFG.ql b/bicep/ql/test/library-tests/cfg/CFG.ql new file mode 100644 index 0000000..3fb1a8b --- /dev/null +++ b/bicep/ql/test/library-tests/cfg/CFG.ql @@ -0,0 +1,9 @@ +import bicep +import codeql.bicep.controlflow.ControlFlowGraph +import TestUtils + +class MyRelevantNode extends CfgNode { + MyRelevantNode() { toBeTested(this.getScope()) } +} + +import codeql.bicep.controlflow.internal.ControlFlowGraphImpl::TestOutput diff --git a/bicep/ql/test/qlpack.yml b/bicep/ql/test/qlpack.yml new file mode 100644 index 0000000..70f636f --- /dev/null +++ b/bicep/ql/test/qlpack.yml @@ -0,0 +1,9 @@ +name: advanced-security/bicep-tests +groups: [bicep, test] +dependencies: +dependencies: + advanced-security/bicep-all: ${workspace} + advanced-security/bicep-queries: ${workspace} +extractor: bicep +tests: . +warnOnImplicitThis: true diff --git a/bicep/ql/test/utils/InlineExpectationsTest.qll b/bicep/ql/test/utils/InlineExpectationsTest.qll new file mode 100644 index 0000000..840e04c --- /dev/null +++ b/bicep/ql/test/utils/InlineExpectationsTest.qll @@ -0,0 +1,8 @@ +/** + * Inline expectation tests for Rust. + * See `shared/util/codeql/util/test/InlineExpectationsTest.qll` + */ + +private import codeql.util.test.InlineExpectationsTest +private import internal.InlineExpectationsTestImpl +import Make diff --git a/bicep/ql/test/utils/internal/InlineExpectationsTestImpl.qll b/bicep/ql/test/utils/internal/InlineExpectationsTestImpl.qll new file mode 100644 index 0000000..88c3314 --- /dev/null +++ b/bicep/ql/test/utils/internal/InlineExpectationsTestImpl.qll @@ -0,0 +1,12 @@ +private import bicep as L +private import L +private import codeql.util.test.InlineExpectationsTest + +module Impl implements InlineExpectationsTestSig { + class ExpectationComment extends L::Comment { + /** Gets the contents of the given comment, _without_ the preceding comment marker (`//`). */ + override string getContents() { result = super.getContents() } + } + + class Location = L::Location; +} diff --git a/bicep/scripts/create-extractor-pack.sh b/bicep/scripts/create-extractor-pack.sh new file mode 100755 index 0000000..c6daf9b --- /dev/null +++ b/bicep/scripts/create-extractor-pack.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -eux + +CARGO=cargo + +if [[ "$OSTYPE" == "linux-gnu"* ]]; then + platform="linux64" + if which cross; then + CARGO=cross + fi +elif [[ "$OSTYPE" == "darwin"* ]]; then + platform="osx64" +else + echo "Unknown OS" + exit 1 +fi + +if which codeql >/dev/null; then + CODEQL_BINARY="codeql" +elif gh codeql >/dev/null; then + CODEQL_BINARY="gh codeql" +else + gh extension install github/gh-codeql + CODEQL_BINARY="gh codeql" +fi + +cargo build --release + +mkdir -p ql/lib/codeql/bicep/ast/internal/ +cargo run --release --bin codeql-extractor-bicep -- \ + generate \ + --dbscheme ql/lib/bicep.dbscheme \ + --library ql/lib/codeql/bicep/ast/internal/TreeSitter.qll + +$CODEQL_BINARY query format -i ql/lib/codeql/bicep/ast/internal/TreeSitter.qll + +echo "Create extractor pack for $platform" +rm -rf extractor-pack +mkdir -p extractor-pack +cp -r codeql-extractor.yml downgrades tools ql/lib/bicep.dbscheme ql/lib/bicep.dbscheme.stats extractor-pack/ + +# Tools +mkdir -p extractor-pack/tools/${platform} +cp target/release/codeql-extractor-bicep extractor-pack/tools/${platform}/extractor +chmod +x extractor-pack/tools/*.sh diff --git a/bicep/scripts/run-tests.sh b/bicep/scripts/run-tests.sh new file mode 100755 index 0000000..e78ca97 --- /dev/null +++ b/bicep/scripts/run-tests.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# get the argument +TESTS_DIR=$1 +if [ -z "$TESTS_DIR" ]; then + TESTS_DIR="ql/test" +fi + +if which codeql >/dev/null; then + CODEQL_BINARY="codeql" +elif gh codeql >/dev/null; then + CODEQL_BINARY="gh codeql" +else + gh extension install github/gh-codeql + CODEQL_BINARY="gh codeql" +fi + +$CODEQL_BINARY pack install ql/test + +echo "Running tests in $TESTS_DIR" + +$CODEQL_BINARY test run \ + -j 0 \ + --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition \ + --search-path ./extractor-pack \ + "$TESTS_DIR" diff --git a/bicep/tools/autobuild.cmd b/bicep/tools/autobuild.cmd new file mode 100644 index 0000000..b6934a6 --- /dev/null +++ b/bicep/tools/autobuild.cmd @@ -0,0 +1,5 @@ +@echo off + +type NUL && "%CODEQL_EXTRACTOR_BICEP_ROOT%\tools\%CODEQL_PLATFORM%\extractor" autobuild + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/bicep/tools/autobuild.sh b/bicep/tools/autobuild.sh new file mode 100644 index 0000000..f652fe7 --- /dev/null +++ b/bicep/tools/autobuild.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +exec "${CODEQL_EXTRACTOR_BICEP_ROOT}/tools/${CODEQL_PLATFORM}/extractor" autobuild \ No newline at end of file diff --git a/bicep/tools/index-files.cmd b/bicep/tools/index-files.cmd new file mode 100644 index 0000000..1979982 --- /dev/null +++ b/bicep/tools/index-files.cmd @@ -0,0 +1,8 @@ +@echo off + +type NUL && "%CODEQL_EXTRACTOR_BICEP_ROOT%\tools\win64\extractor.exe" ^ + --file-list "%1" ^ + --source-archive-dir "%CODEQL_EXTRACTOR_BICEP_SOURCE_ARCHIVE_DIR%" ^ + --output-dir "%CODEQL_EXTRACTOR_BICEP_TRAP_DIR%" + +exit /b %ERRORLEVEL% diff --git a/bicep/tools/index-files.sh b/bicep/tools/index-files.sh new file mode 100644 index 0000000..e457250 --- /dev/null +++ b/bicep/tools/index-files.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -eu + +exec "${CODEQL_EXTRACTOR_BICEP_ROOT}/tools/${CODEQL_PLATFORM}/extractor" \ + extract \ + --file-list "$1" \ + --source-archive-dir "$CODEQL_EXTRACTOR_BICEP_SOURCE_ARCHIVE_DIR" \ + --output-dir "$CODEQL_EXTRACTOR_BICEP_TRAP_DIR" \ No newline at end of file diff --git a/bicep/tools/pre-finalize.cmd b/bicep/tools/pre-finalize.cmd new file mode 100644 index 0000000..20ca437 --- /dev/null +++ b/bicep/tools/pre-finalize.cmd @@ -0,0 +1,14 @@ +@echo off + +type NUL && "%CODEQL_DIST%\codeql" database index-files ^ + --include=*.yml ^ + --include=*.yaml ^ + --include=*.json ^ + --include=*.jsonc ^ + --include=*.jsonl ^ + --size-limit=5m ^ + --language yaml ^ + -- ^ + "%CODEQL_EXTRACTOR_QL_WIP_DATABASE%" + +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/bicep/tools/pre-finalize.sh b/bicep/tools/pre-finalize.sh new file mode 100644 index 0000000..4f26897 --- /dev/null +++ b/bicep/tools/pre-finalize.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -eu + +"$CODEQL_DIST/codeql" database index-files \ + "--include=**/*.yml" \ + "--include=**/*.yaml" \ + "--include=**/*.json" \ + "--include=**/*.jsonc" \ + "--include=**/*.jsonl" \ + --size-limit=5m \ + --language yaml \ + -- \ + "$CODEQL_EXTRACTOR_BICEP_WIP_DATABASE" \ No newline at end of file diff --git a/bicep/tools/qltest.cmd b/bicep/tools/qltest.cmd new file mode 100644 index 0000000..1611475 --- /dev/null +++ b/bicep/tools/qltest.cmd @@ -0,0 +1,12 @@ +@echo off + +type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ + --prune=**/*.testproj ^ + --include-extension=.hcl ^ + --include-extension=.tf ^ + --size-limit=5m ^ + --language=hcl ^ + --working-dir=. ^ + "%CODEQL_EXTRACTOR_BICEP_WIP_DATABASE%" + +exit /b %ERRORLEVEL% diff --git a/bicep/tools/qltest.sh b/bicep/tools/qltest.sh new file mode 100644 index 0000000..ba2642d --- /dev/null +++ b/bicep/tools/qltest.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +set -eu + +"${CODEQL_DIST}/codeql" database index-files \ + --prune="**/*.testproj" \ + --include-extension=.bicep \ + --size-limit=5m \ + --language=bicep \ + --working-dir=.\ + "$CODEQL_EXTRACTOR_BICEP_WIP_DATABASE" + +exec "${CODEQL_DIST}/codeql" database index-files \ + --prune="**/*.testproj" \ + --include-extension=.yml \ + --include-extension=.yaml \ + --include-extension=.json \ + --size-limit=5m \ + --language=yaml \ + --working-dir=.\ + "$CODEQL_EXTRACTOR_BICEP_WIP_DATABASE" \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 7c6fd31..00e88ca 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.75" +channel = "1.85" profile = "minimal" components = ["rustfmt"]