@@ -39,6 +39,16 @@ private AstNode getSelectPart(Select sel, int index) {
3939 )
4040}
4141
42+ /**
43+ * Gets a string element that is the last part of the message, that doesn't end with a full stop.
44+ *
45+ * E.g.
46+ * ```CodeQL
47+ * select foo(), "This is a description" // <- bad
48+ *
49+ * select foo(), "This is a description." // <- good
50+ * ```
51+ */
4252String shouldHaveFullStop ( Select sel ) {
4353 result =
4454 max ( AstNode str , int i |
@@ -50,6 +60,16 @@ String shouldHaveFullStop(Select sel) {
5060 not result .getValue ( ) .matches ( "%?" )
5161}
5262
63+ /**
64+ * Gets a string element that is the first part of the message, that starts with a lower case letter.
65+ *
66+ * E.g.
67+ * ```CodeQL
68+ * select foo(), "this is a description." // <- bad
69+ *
70+ * select foo(), "This is a description." // <- good
71+ * ```
72+ */
5373String shouldStartCapital ( Select sel ) {
5474 result =
5575 min ( AstNode str , int i |
@@ -60,31 +80,64 @@ String shouldStartCapital(Select sel) {
6080 result .getValue ( ) .regexpMatch ( "^[a-z].*" )
6181}
6282
63- // see https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html
83+ /**
84+ * Gets a string element that is used in a message that contains "here" or "this location".
85+ *
86+ * E.g.
87+ * ```CodeQL
88+ * select foo(), "XSS happens here from using a unsafe value." // <- bad
89+ *
90+ * select foo(), "XSS from using a unsafe value." // <- good
91+ * ```
92+ */
6493String avoidHere ( string part ) {
65- part = [ "here" , "this location" ] and // TODO: prefer "this location" of the two.
94+ part = [ "here" , "this location" ] and
6695 (
6796 result .getValue ( ) .regexpMatch ( ".*\\b" + part + "\\b.*" ) and
6897 result = getSelectPart ( _, _)
6998 )
7099}
71100
72- // see https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html
101+ /**
102+ * Avoid using an indefinite article ("a" or "an") in a link text.
103+ *
104+ * E.g.
105+ * ```CodeQL
106+ * select foo(), "XSS from $@", val, "an unsafe value." // <- bad
107+ *
108+ * select foo(), "XSS from a $@", val, "unsafe value." // <- good
109+ * ```
110+ *
111+ * See https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html for the W3C guideline on link text. a
112+ */
73113String avoidArticleInLinkText ( Select sel ) {
74114 result = sel .getExpr ( ( any ( int i | i > 1 ) ) ) and
75115 result = getSelectPart ( sel , _) and
76116 result .getValue ( ) .regexpMatch ( "a|an .*" )
77117}
78118
119+ /**
120+ * Don't quote substitutions in a message.
121+ *
122+ * E.g.
123+ * ```CodeQL
124+ * select foo(), "XSS from '$@'", val, "an unsafe value." // <- bad
125+ *
126+ * select foo(), "XSS from $@", val, "an unsafe value." // <- good
127+ * ```
128+ */
79129String dontQuoteSubstitutions ( Select sel ) {
80130 result = getSelectPart ( sel , _) and
81131 result .getValue ( ) .matches ( [ "%'$@'%" , "%\"$@\"%" ] )
82132}
83133
84- // "data" or "taint"
85- string getQueryKind ( Select s ) {
134+ /**
135+ * Gets the kind of the path-query represented by `sel`.
136+ * Either "data" for a dataflow query or "taint" for a taint-tracking query.
137+ */
138+ private string getQueryKind ( Select sel ) {
86139 exists ( TypeExpr sup |
87- sup = s .getVarDecl ( _) .getType ( ) .( ClassType ) .getDeclaration ( ) .getASuperType ( ) and
140+ sup = sel .getVarDecl ( _) .getType ( ) .( ClassType ) .getDeclaration ( ) .getASuperType ( ) and
88141 sup .getResolvedType ( ) .( ClassType ) .getName ( ) = "Configuration"
89142 |
90143 result = "data" and
@@ -95,6 +148,10 @@ string getQueryKind(Select s) {
95148 )
96149}
97150
151+ /**
152+ * Gets a string element from a message that uses the wrong phrase for a path query.
153+ * A dataflow query should use "flows to" and a taint-tracking query should use "depends on".
154+ */
98155String wrongFlowsPhrase ( Select sel , string kind ) {
99156 result = getSelectPart ( sel , _) and
100157 kind = getQueryKind ( sel ) and
0 commit comments