|
| 1 | +/** |
| 2 | + * Provides a unified representation of comments across the infrastructure-as-code |
| 3 | + * (IaC) languages supported by CodeQL, spanning HCL/Terraform comments and comments |
| 4 | + * in YAML files recognized by a public IaC framework API. |
| 5 | + */ |
| 6 | + |
| 7 | +import iac |
| 8 | + |
| 9 | +/** |
| 10 | + * Holds if `file` is a YAML file recognized by a public IaC framework API. |
| 11 | + */ |
| 12 | +private predicate isSupportedYamlFile(File file) { |
| 13 | + exists(CloudFormation::Document document | document.getFile() = file) |
| 14 | + or |
| 15 | + exists(ARM::Document document | document.getFile() = file) |
| 16 | + or |
| 17 | + exists(AzurePipelines::Document document | document.getFile() = file) |
| 18 | + or |
| 19 | + exists(Compose::Document document | document.getFile() = file) |
| 20 | + or |
| 21 | + exists(HelmChart::Document document | document.getFile() = file) |
| 22 | + or |
| 23 | + exists(OpenApi::Document document | document.getFile() = file) |
| 24 | + or |
| 25 | + exists(YamlMapping document | |
| 26 | + document.getFile() = file and |
| 27 | + document |
| 28 | + .lookup("$schema") |
| 29 | + .(YamlString) |
| 30 | + .getValue() |
| 31 | + .regexpMatch(".*schema\\.management\\.azure\\.com.*") |
| 32 | + ) |
| 33 | +} |
| 34 | + |
| 35 | +/** |
| 36 | + * Gets the delimiter-stripped `text` and `delimiterStyle` of an HCL comment. |
| 37 | + */ |
| 38 | +private predicate getHclCommentText(HCLComment comment, string text, string delimiterStyle) { |
| 39 | + exists(string raw | raw = comment.getContents() | |
| 40 | + raw.matches("#%") and |
| 41 | + text = raw.suffix(1).replaceAll("\r", "") and |
| 42 | + delimiterStyle = "hash" |
| 43 | + or |
| 44 | + raw.matches("//%") and |
| 45 | + text = raw.suffix(2).replaceAll("\r", "") and |
| 46 | + delimiterStyle = "slash" |
| 47 | + or |
| 48 | + raw.matches("/*%*/") and |
| 49 | + text = raw.substring(2, raw.length() - 2).replaceAll("\r", "") and |
| 50 | + delimiterStyle = "slash" |
| 51 | + ) |
| 52 | +} |
| 53 | + |
| 54 | +/** |
| 55 | + * Gets the delimiter-stripped `text` and `delimiterStyle` of a comment exposed by a |
| 56 | + * supported public IaC API located at `location`. |
| 57 | + */ |
| 58 | +private predicate getIacCommentText(Location location, string text, string delimiterStyle) { |
| 59 | + exists(HCLComment comment | |
| 60 | + location = comment.getLocation() and |
| 61 | + getHclCommentText(comment, text, delimiterStyle) |
| 62 | + ) |
| 63 | + or |
| 64 | + exists(YamlComment comment | |
| 65 | + location = comment.getLocation() and |
| 66 | + isSupportedYamlFile(comment.getLocation().getFile()) and |
| 67 | + text = comment.getText() and |
| 68 | + delimiterStyle = "hash" |
| 69 | + ) |
| 70 | +} |
| 71 | + |
| 72 | +/** |
| 73 | + * A comment exposed by a supported public IaC API. |
| 74 | + * |
| 75 | + * This spans HCL/Terraform comments and comments in YAML files recognized by a public |
| 76 | + * IaC framework API (for example CloudFormation, ARM, Azure Pipelines, Compose, Helm |
| 77 | + * charts and OpenAPI documents). |
| 78 | + */ |
| 79 | +class Comment extends Location { |
| 80 | + Comment() { |
| 81 | + getIacCommentText(this, _, _) |
| 82 | + } |
| 83 | + |
| 84 | + /** Gets the comment text without its delimiter. */ |
| 85 | + string getText() { |
| 86 | + getIacCommentText(this, result, _) |
| 87 | + } |
| 88 | + |
| 89 | + /** Holds if this comment uses `#` as its delimiter. */ |
| 90 | + predicate hasHashDelimiter() { getIacCommentText(this, _, "hash") } |
| 91 | +} |
0 commit comments