diff --git a/docs/query-help-style-guide.md b/docs/query-help-style-guide.md index 88b9844fc224..3ed9f439490b 100644 --- a/docs/query-help-style-guide.md +++ b/docs/query-help-style-guide.md @@ -16,11 +16,33 @@ When you contribute a new [supported query](supported-queries.md) to this reposi ### Location and file name -Query help files must have the same base name as the query they describe and must be located in the same directory. +Query help files must have the same base name as the query they describe and must be located in the same directory. ### File structure and layout -Query help files are written using a custom XML format, and stored in a file with a `.qhelp` extension. The basic structure is as follows: +Query help files can be written in either a custom XML format (with a `.qhelp` extension) or in Markdown (with a `.md` extension). Both formats are supported by the CodeQL documentation tooling. There are a few minor differences, noted in the section `Differences between XML and markdown formats` below. + +#### Markdown query help files + +A Markdown query help file should use the following structure and section order (note that the `Implementation notes` section is optional): + +``` +## Overview + +## Recommendation + +## Example + +## Implementation notes + +## References +``` + +Each section should be clearly marked with the appropriate heading. See the other Markdown files in this repository for examples. + +#### XML query help files + +Query help files can also be written using a custom XML format, and stored in a file with a `.qhelp` extension. The basic structure is as follows: ```xml @@ -33,7 +55,7 @@ The header and single top-level `` element are both mandatory. ### Section-level elements -Section-level elements are used to group the information within the query help file. All query help files should include at least the following section elements, in the order specified: +Section-level elements are used to group the information within the query help file. For both Markdown and XML formats, the following sections should be included, in the order specified: 1. `overview`—a short summary of the issue that the query identifies, including an explanation of how it could affect the behavior of the program. 2. `recommendation`—information on how to fix the issue highlighted by the query. @@ -42,10 +64,9 @@ Section-level elements are used to group the information within the query help f For further information about the other section-level, block, list and table elements supported by query help files, see [Query help files](https://codeql.github.com/docs/writing-codeql-queries/query-help-files/) on codeql.github.com. - ## English style -You should write the overview and recommendation elements in simple English that is easy to follow. You should: +You should write the overview and recommendation sections in simple English that is easy to follow. You should: * Use simple sentence structures and avoid complex or academic language. * Avoid colloquialisms and contractions. @@ -57,10 +78,11 @@ You should write the overview and recommendation elements in simple English that Whenever possible, you should include a code example that helps to explain the issue you are highlighting. Any code examples that you include should adhere to the following guidelines: * The example should be less than 20 lines, but it should still clearly illustrate the issue that the query identifies. If appropriate, then the example may also be runnable. -* Put the code example after the recommendation element where possible. Only include an example in the description element if absolutely necessary. +* Put the code example after the recommendation section where possible. Only include an example in the description section if absolutely necessary. * If you are using an example to illustrate the solution to a problem, and the change required is minor, avoid repeating the whole example. It is preferable to either describe the change required or to include a smaller snippet of the corrected code. * Clearly indicate which of the samples is an example of bad coding practice and which is recommended practice. -* Define the code examples in `src` files. The language is inferred from the file extension: +* For Markdown files, use fenced code blocks with the appropriate language identifier (for example, ```java ). +* For XML files, define the code examples in `src` files. The language is inferred from the file extension: ```xml @@ -74,11 +96,11 @@ Whenever possible, you should include a code example that helps to explain the i ``` -Note, if any code words are included in the `overview` and `recommendation` sections, they should be formatted with ` ... ` for emphasis. +Note, if any code words are included in the `overview` and `recommendation` sections, in Markdown they should be formatted with backticks (`...`) and in XML they should be formatted with` ... ` for emphasis. ## Including references -You should include one or more references, list formatted with `
  • ...
  • ` for each item, to provide further information about the problem that your query is designed to find. References can be of the following types: +You should include one or more references, formatted as an unordered list (`- ...` or `* ...`) in Markdown or with `
  • ...
  • ` for each item in XML, to provide further information about the problem that your query is designed to find. References can be of the following types: ### Books @@ -90,7 +112,7 @@ For example: >W. C. Wake, _Refactoring Workbook_, pp. 93 – 94, Addison-Wesley Professional, 2004. -Note, & symbols need to be replaced by \&. The symbol will be displayed correctly in the HTML files generated from the query help files. +Note, & symbols need to be replaced by \& in XML. The symbol will be displayed correctly in the HTML files generated from the query help files. ### Academic papers @@ -98,7 +120,6 @@ If you are citing an academic paper, we recommend adopting the reference style o >S. R. Chidamber and C. F. Kemerer, _A metrics suite for object-oriented design_. IEEE Transactions on Software Engineering, 20(6):476-493, 1994. - ### Websites If you are citing a website, please use the following format, without breadcrumb trails: @@ -111,28 +132,123 @@ For example: ### Referencing potential security weaknesses -If your query checks code for a CWE weakness, you should use the `@tags` element in the query file to reference the associated CWEs, as explained [here](query-metadata-style-guide.md). When you use these tags, a link to the appropriate entry from the [MITRE.org](https://cwe.mitre.org/scoring/index.html) site will automatically appear as a reference in the output HTML file. +If your query checks code for a CWE weakness, you should use the `@tags` element in the query file to reference the associated CWEs, as explained [here](query-metadata-style-guide.md). When you use these tags in a query help file in the custom XML format, a link to the appropriate entry from the [MITRE.org](https://cwe.mitre.org/scoring/index.html) site will automatically appear as a reference in the output HTML file. -## Validating qhelp files +## Validating query help files -Before making a pull request, please ensure the `.qhelp` files are well-formed and can be generated without errors. This can be done locally with the CodeQL CLI, as shown in the following example: +Before making a pull request, please ensure the `.qhelp` or `.md` files are well-formed and can be generated without errors. This can be done locally with the CodeQL CLI, as shown in the following example: ```bash # codeql generate query-help --format= # For example: codeql generate query-help ./myCustomQuery.qhelp --format=markdown +codeql generate query-help ./myCustomQuery.md --format=markdown ``` +Please include the query help files (and any associated code snippets) in your pull request, but do not commit the generated Markdown. -Please include the `.qhelp` files (and any associated code snippets) in your pull request, but do not commit the generated Markdown. +More information on how to test your query help files can be found [within the documentation](https://docs.github.com/en/code-security/codeql-cli/using-the-codeql-cli/testing-query-help-files) -More information on how to test your `.qhelp` files can be found [within the documentation](https://docs.github.com/en/code-security/codeql-cli/using-the-codeql-cli/testing-query-help-files) +## Differences between XML and markdown formats + +1. The XML format allows for the contents of other files to be included in the output generated by processing the file, as mentioned in the section `Code examples`. This is not possible with the Markdown format. +2. When using the XML format, references are added to the output HTML file based on CWE tags, as mentioned in the section `Referencing potential security weaknesses`. +3. For custom queries and custom query packs, only the Markdown format is supported. ## Query help example -The following example is a query help file for a query from the standard query suite for Java: +The following example is a query help file for a query from the standard query suite for Java, shown in both Markdown and XML formats. -```xml +### Markdown example + +````markdown +# Overview + +A control structure (an `if` statement or a loop) has a body that is either a block +of statements surrounded by curly braces or a single statement. + +If you omit braces, it is particularly important to ensure that the indentation of the code +matches the control flow of the code. + +## Recommendation + +It is usually considered good practice to include braces for all control +structures in Java. This is because it makes it easier to maintain the code +later. For example, it's easy to see at a glance which part of the code is in the +scope of an `if` statement, and adding more statements to the body of the `if` +statement is less error-prone. + +You should also ensure that the indentation of the code is consistent with the actual flow of +control, so that it does not confuse programmers. + +## Example + +In the example below, the original version of `Cart` is missing braces. This means +that the code triggers a `NullPointerException` at runtime if `i` +is `null`. + +```java +class Cart { + Map items = ... + public void addItem(Item i) { + // No braces and misleading indentation. + if (i != null) + log("Adding item: " + i); + // Indentation suggests that the following statements + // are in the body of the 'if'. + Integer curQuantity = items.get(i.getID()); + if (curQuantity == null) curQuantity = 0; + items.put(i.getID(), curQuantity+1); + } +} +``` + +The corrected version of `Cart` does include braces, so +that the code executes as the indentation suggests. + +```java +class Cart { + Map items = ... + public void addItem(Item i) { + // Braces included. + if (i != null) { + log("Adding item: " + i); + Integer curQuantity = items.get(i.getID()); + if (curQuantity == null) curQuantity = 0; + items.put(i.getID(), curQuantity+1); + } + } +} +``` + +In the following example the indentation may or may not be misleading depending on your tab width +settings. As such, mixing tabs and spaces in this way is not recommended, since what looks fine in +one context can be very misleading in another. + +```java +// Tab width 8 + if (b) // Indentation: 1 tab + f(); // Indentation: 2 tabs + g(); // Indentation: 8 spaces + +// Tab width 4 + if (b) // Indentation: 1 tab + f(); // Indentation: 2 tabs + g(); // Indentation: 8 spaces +``` + +If you mix tabs and spaces in this way, then you might get seemingly false positives, since your +tab width settings cannot be taken into account. + +## References + +* Java SE Documentation: [Compound Statements](https://www.oracle.com/java/technologies/javase/codeconventions-statements.html#15395) +* Wikipedia: [Indentation style](https://en.wikipedia.org/wiki/Indentation_style) +```` + +### XML example + +````xml @@ -154,13 +270,13 @@ later. For example, it's easy to see at a glance which part of the code is in th scope of an if statement, and adding more statements to the body of the if statement is less error-prone.

    -

    You should also ensure that the indentation of the code is consistent with the actual flow of +

    You should also ensure that the indentation of the code is consistent with the actual flow of control, so that it does not confuse programmers.

    -

    In the example below, the original version of Cart is missing braces. This means +

    In the example below, the original version of Cart is missing braces. This means that the code triggers a NullPointerException at runtime if i is null.

    @@ -198,4 +314,4 @@ tab width settings cannot be taken into account.
    -``` +````