-
Notifications
You must be signed in to change notification settings - Fork 2k
Update qhelp style guide for markdown format #19730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,11 +16,27 @@ 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: | ||
|
|
||
| 1. **Overview** (level 2 heading, `## Overview`) | ||
| 2. **Recommendation** (level 2 heading, `## Recommendation`) | ||
| 3. **Example** (level 2 heading, `## Example`) | ||
| 4. **Implementation notes** (optional, level 2 heading, `## Implementation notes`) | ||
| 5. **References** (level 2 heading, `## 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 | ||
| <!DOCTYPE qhelp SYSTEM "qhelp.dtd"> | ||
|
|
@@ -33,7 +49,7 @@ The header and single top-level `<qhelp>` 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 +58,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 +72,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, <code> ```java </code>). | ||
| * For XML files, define the code examples in `src` files. The language is inferred from the file extension: | ||
|
|
||
| ```xml | ||
| <example> | ||
|
|
@@ -74,11 +90,11 @@ Whenever possible, you should include a code example that helps to explain the i | |
| </example> | ||
| ``` | ||
|
|
||
| Note, if any code words are included in the `overview` and `recommendation` sections, they should be formatted with `<code> ... </code>` for emphasis. | ||
| Note, if any code words are included in the `overview` and `recommendation` sections, in Markdown they should be formatted with backticks (<code>`...`</code>) and in XML they should be formatted with`<code> ... </code>` for emphasis. | ||
|
|
||
| ## Including references | ||
|
|
||
| You should include one or more references, list formatted with `<li> ... </li>` 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 `<li> ... </li>` 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,15 +106,14 @@ 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 | ||
|
|
||
| If you are citing an academic paper, we recommend adopting the reference style of the journal that you are citing. For example: | ||
|
|
||
| >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 +126,122 @@ 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 <path_to_your_qhelp_file> --format=<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. | ||
|
|
||
| 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) | ||
|
|
||
| Please include the `.qhelp` files (and any associated code snippets) in your pull request, but do not commit the generated Markdown. | ||
| ## Differences between XML and markdown formats | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One more difference: only Markdown is supported for custom queries / query packs.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting. Do you know why that is?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Deliberate choice to reduce the risk from processing untrusted XML. Our XML processing has protections against entity expansion, but the includes mechanism isn't completely robust to untrusted XML help. Markdown help does not have this problem. For this reason we only support XML help we've written ourselves, and require Markdown help for custom query packs. |
||
|
|
||
| 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) | ||
| 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`. | ||
|
|
||
| ## 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<Integer, Integer> 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<Integer, Integer> 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 | ||
| <!DOCTYPE qhelp PUBLIC | ||
| "-//Semmle//qhelp//EN" | ||
| "qhelp.dtd"> | ||
|
|
@@ -154,13 +263,13 @@ later. For example, it's easy to see at a glance which part of the code is in th | |
| scope of an <code>if</code> statement, and adding more statements to the body of the <code>if</code> | ||
| statement is less error-prone.</p> | ||
|
|
||
| <p>You should also ensure that the indentation of the code is consistent with the actual flow of | ||
| <p>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.</p> | ||
|
|
||
| </recommendation> | ||
| <example> | ||
|
|
||
| <p>In the example below, the original version of <code>Cart</code> is missing braces. This means | ||
| <p>In the example below, the original version of <code>Cart</code> is missing braces. This means | ||
| that the code triggers a <code>NullPointerException</code> at runtime if <code>i</code> | ||
| is <code>null</code>.</p> | ||
|
|
||
|
|
@@ -198,4 +307,4 @@ tab width settings cannot be taken into account. | |
|
|
||
| </references> | ||
| </qhelp> | ||
| ``` | ||
| ```` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion: consider just making this a fenced code block with the five headings filled in, and gaps in between. Then it can be copied and used directly.