mirror of
https://github.com/github/codeql.git
synced 2026-05-05 21:55:19 +02:00
Python: Autoformat everything using qlformat.
Will need subsequent PRs fixing up test failures (due to deprecated methods moving around), but other than that everything should be straight-forward.
This commit is contained in:
@@ -2,125 +2,125 @@ import python
|
||||
|
||||
/** A string constant that looks like it may be used in string formatting operations. */
|
||||
library class PossibleAdvancedFormatString extends StrConst {
|
||||
PossibleAdvancedFormatString() { this.getText().matches("%{%}%") }
|
||||
PossibleAdvancedFormatString() { this.getText().matches("%{%}%") }
|
||||
|
||||
private predicate field(int start, int end) {
|
||||
brace_pair(this, start, end) and
|
||||
this.getText().substring(start, end) != "{{}}"
|
||||
}
|
||||
private predicate field(int start, int end) {
|
||||
brace_pair(this, start, end) and
|
||||
this.getText().substring(start, end) != "{{}}"
|
||||
}
|
||||
|
||||
/** Gets the number of the formatting field at [start, end) */
|
||||
int getFieldNumber(int start, int end) {
|
||||
result = this.fieldId(start, end).toInt()
|
||||
or
|
||||
this.implicitlyNumberedField(start, end) and
|
||||
result = count(int s | this.implicitlyNumberedField(s, _) and s < start)
|
||||
}
|
||||
/** Gets the number of the formatting field at [start, end) */
|
||||
int getFieldNumber(int start, int end) {
|
||||
result = this.fieldId(start, end).toInt()
|
||||
or
|
||||
this.implicitlyNumberedField(start, end) and
|
||||
result = count(int s | this.implicitlyNumberedField(s, _) and s < start)
|
||||
}
|
||||
|
||||
/** Gets the text of the formatting field at [start, end) */
|
||||
string getField(int start, int end) {
|
||||
this.field(start, end) and
|
||||
result = this.getText().substring(start, end)
|
||||
}
|
||||
/** Gets the text of the formatting field at [start, end) */
|
||||
string getField(int start, int end) {
|
||||
this.field(start, end) and
|
||||
result = this.getText().substring(start, end)
|
||||
}
|
||||
|
||||
private string fieldId(int start, int end) {
|
||||
this.field(start, end) and
|
||||
(
|
||||
result = this.getText().substring(start, end).regexpCapture("\\{([^!:.\\[]+)[!:.\\[].*", 1)
|
||||
or
|
||||
result = this.getText().substring(start + 1, end - 1) and result.regexpMatch("[^!:.\\[]+")
|
||||
)
|
||||
}
|
||||
private string fieldId(int start, int end) {
|
||||
this.field(start, end) and
|
||||
(
|
||||
result = this.getText().substring(start, end).regexpCapture("\\{([^!:.\\[]+)[!:.\\[].*", 1)
|
||||
or
|
||||
result = this.getText().substring(start + 1, end - 1) and result.regexpMatch("[^!:.\\[]+")
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the name of the formatting field at [start, end) */
|
||||
string getFieldName(int start, int end) {
|
||||
result = this.fieldId(start, end) and
|
||||
not exists(this.getFieldNumber(start, end))
|
||||
}
|
||||
/** Gets the name of the formatting field at [start, end) */
|
||||
string getFieldName(int start, int end) {
|
||||
result = this.fieldId(start, end) and
|
||||
not exists(this.getFieldNumber(start, end))
|
||||
}
|
||||
|
||||
private predicate implicitlyNumberedField(int start, int end) {
|
||||
this.field(start, end) and
|
||||
exists(string c | start + 1 = this.getText().indexOf(c) |
|
||||
c = "}" or c = ":" or c = "!" or c = "."
|
||||
)
|
||||
}
|
||||
private predicate implicitlyNumberedField(int start, int end) {
|
||||
this.field(start, end) and
|
||||
exists(string c | start + 1 = this.getText().indexOf(c) |
|
||||
c = "}" or c = ":" or c = "!" or c = "."
|
||||
)
|
||||
}
|
||||
|
||||
/** Whether this format string has implicitly numbered fields */
|
||||
predicate isImplicitlyNumbered() { this.implicitlyNumberedField(_, _) }
|
||||
/** Whether this format string has implicitly numbered fields */
|
||||
predicate isImplicitlyNumbered() { this.implicitlyNumberedField(_, _) }
|
||||
|
||||
/** Whether this format string has explicitly numbered fields */
|
||||
predicate isExplicitlyNumbered() { exists(this.fieldId(_, _).toInt()) }
|
||||
/** Whether this format string has explicitly numbered fields */
|
||||
predicate isExplicitlyNumbered() { exists(this.fieldId(_, _).toInt()) }
|
||||
}
|
||||
|
||||
/** Holds if the formatting string `fmt` contains a sequence of braces `{` of length `len`, beginning at index `index`. */
|
||||
predicate brace_sequence(PossibleAdvancedFormatString fmt, int index, int len) {
|
||||
exists(string text | text = fmt.getText() |
|
||||
text.charAt(index) = "{" and not text.charAt(index - 1) = "{" and len = 1
|
||||
or
|
||||
text.charAt(index) = "{" and
|
||||
text.charAt(index - 1) = "{" and
|
||||
brace_sequence(fmt, index - 1, len - 1)
|
||||
)
|
||||
exists(string text | text = fmt.getText() |
|
||||
text.charAt(index) = "{" and not text.charAt(index - 1) = "{" and len = 1
|
||||
or
|
||||
text.charAt(index) = "{" and
|
||||
text.charAt(index - 1) = "{" and
|
||||
brace_sequence(fmt, index - 1, len - 1)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if index `index` in the format string `fmt` contains an escaped brace `{`. */
|
||||
predicate escaped_brace(PossibleAdvancedFormatString fmt, int index) {
|
||||
exists(int len | brace_sequence(fmt, index, len) | len % 2 = 0)
|
||||
exists(int len | brace_sequence(fmt, index, len) | len % 2 = 0)
|
||||
}
|
||||
|
||||
/** Holds if index `index` in the format string `fmt` contains a left brace `{` that acts as an escape character. */
|
||||
predicate escaping_brace(PossibleAdvancedFormatString fmt, int index) {
|
||||
escaped_brace(fmt, index + 1)
|
||||
escaped_brace(fmt, index + 1)
|
||||
}
|
||||
|
||||
private predicate inner_brace_pair(PossibleAdvancedFormatString fmt, int start, int end) {
|
||||
not escaping_brace(fmt, start) and
|
||||
not escaped_brace(fmt, start) and
|
||||
fmt.getText().charAt(start) = "{" and
|
||||
exists(string pair |
|
||||
pair = fmt.getText().suffix(start).regexpCapture("(?s)(\\{([^{}]|\\{\\{)*+\\}).*", 1)
|
||||
|
|
||||
end = start + pair.length()
|
||||
)
|
||||
not escaping_brace(fmt, start) and
|
||||
not escaped_brace(fmt, start) and
|
||||
fmt.getText().charAt(start) = "{" and
|
||||
exists(string pair |
|
||||
pair = fmt.getText().suffix(start).regexpCapture("(?s)(\\{([^{}]|\\{\\{)*+\\}).*", 1)
|
||||
|
|
||||
end = start + pair.length()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate brace_pair(PossibleAdvancedFormatString fmt, int start, int end) {
|
||||
inner_brace_pair(fmt, start, end)
|
||||
or
|
||||
not escaping_brace(fmt, start) and
|
||||
not escaped_brace(fmt, start) and
|
||||
exists(string prefix, string postfix, int innerstart, int innerend |
|
||||
brace_pair(fmt, innerstart, innerend) and
|
||||
prefix = fmt.getText().regexpFind("\\{([^{}]|\\{\\{)+\\{", _, start) and
|
||||
innerstart = start + prefix.length() - 1 and
|
||||
postfix = fmt.getText().regexpFind("\\}([^{}]|\\}\\})*\\}", _, innerend - 1) and
|
||||
end = innerend + postfix.length() - 1
|
||||
)
|
||||
inner_brace_pair(fmt, start, end)
|
||||
or
|
||||
not escaping_brace(fmt, start) and
|
||||
not escaped_brace(fmt, start) and
|
||||
exists(string prefix, string postfix, int innerstart, int innerend |
|
||||
brace_pair(fmt, innerstart, innerend) and
|
||||
prefix = fmt.getText().regexpFind("\\{([^{}]|\\{\\{)+\\{", _, start) and
|
||||
innerstart = start + prefix.length() - 1 and
|
||||
postfix = fmt.getText().regexpFind("\\}([^{}]|\\}\\})*\\}", _, innerend - 1) and
|
||||
end = innerend + postfix.length() - 1
|
||||
)
|
||||
}
|
||||
|
||||
private predicate advanced_format_call(Call format_expr, PossibleAdvancedFormatString fmt, int args) {
|
||||
exists(CallNode call | call = format_expr.getAFlowNode() |
|
||||
call.getFunction().pointsTo(Value::named("format")) and
|
||||
call.getArg(0).pointsTo(_, fmt.getAFlowNode()) and
|
||||
args = count(format_expr.getAnArg()) - 1
|
||||
or
|
||||
call.getFunction().(AttrNode).getObject("format").pointsTo(_, fmt.getAFlowNode()) and
|
||||
args = count(format_expr.getAnArg())
|
||||
)
|
||||
exists(CallNode call | call = format_expr.getAFlowNode() |
|
||||
call.getFunction().pointsTo(Value::named("format")) and
|
||||
call.getArg(0).pointsTo(_, fmt.getAFlowNode()) and
|
||||
args = count(format_expr.getAnArg()) - 1
|
||||
or
|
||||
call.getFunction().(AttrNode).getObject("format").pointsTo(_, fmt.getAFlowNode()) and
|
||||
args = count(format_expr.getAnArg())
|
||||
)
|
||||
}
|
||||
|
||||
/** A string constant that has the `format` method applied to it. */
|
||||
class AdvancedFormatString extends PossibleAdvancedFormatString {
|
||||
AdvancedFormatString() { advanced_format_call(_, this, _) }
|
||||
AdvancedFormatString() { advanced_format_call(_, this, _) }
|
||||
}
|
||||
|
||||
/** A string formatting operation that uses the `format` method. */
|
||||
class AdvancedFormattingCall extends Call {
|
||||
AdvancedFormattingCall() { advanced_format_call(this, _, _) }
|
||||
AdvancedFormattingCall() { advanced_format_call(this, _, _) }
|
||||
|
||||
/** Count of the arguments actually provided */
|
||||
int providedArgCount() { advanced_format_call(this, _, result) }
|
||||
/** Count of the arguments actually provided */
|
||||
int providedArgCount() { advanced_format_call(this, _, result) }
|
||||
|
||||
/** Gets a formatting string for this call. */
|
||||
AdvancedFormatString getAFormat() { advanced_format_call(this, result, _) }
|
||||
/** Gets a formatting string for this call. */
|
||||
AdvancedFormatString getAFormat() { advanced_format_call(this, result, _) }
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ int field_count(AdvancedFormatString fmt) { result = max(fmt.getFieldNumber(_, _
|
||||
|
||||
from AdvancedFormattingCall call, AdvancedFormatString fmt, int arg_count, int max_field
|
||||
where
|
||||
arg_count = call.providedArgCount() and
|
||||
max_field = field_count(fmt) and
|
||||
call.getAFormat() = fmt and
|
||||
not exists(call.getStarargs()) and
|
||||
forall(AdvancedFormatString other | other = call.getAFormat() | field_count(other) < arg_count)
|
||||
arg_count = call.providedArgCount() and
|
||||
max_field = field_count(fmt) and
|
||||
call.getAFormat() = fmt and
|
||||
not exists(call.getStarargs()) and
|
||||
forall(AdvancedFormatString other | other = call.getAFormat() | field_count(other) < arg_count)
|
||||
select call,
|
||||
"Too many arguments for string format. Format $@ requires only " + max_field + ", but " +
|
||||
arg_count.toString() + " are provided.", fmt, "\"" + fmt.getText() + "\""
|
||||
"Too many arguments for string format. Format $@ requires only " + max_field + ", but " +
|
||||
arg_count.toString() + " are provided.", fmt, "\"" + fmt.getText() + "\""
|
||||
|
||||
@@ -15,17 +15,17 @@ import AdvancedFormatting
|
||||
|
||||
from AdvancedFormattingCall call, AdvancedFormatString fmt, string name, string fmt_repr
|
||||
where
|
||||
call.getAFormat() = fmt and
|
||||
name = call.getAKeyword().getArg() and
|
||||
forall(AdvancedFormatString format | format = call.getAFormat() |
|
||||
not format.getFieldName(_, _) = name
|
||||
) and
|
||||
not exists(call.getKwargs()) and
|
||||
(
|
||||
strictcount(call.getAFormat()) = 1 and fmt_repr = "format \"" + fmt.getText() + "\""
|
||||
or
|
||||
strictcount(call.getAFormat()) != 1 and fmt_repr = "any format used."
|
||||
)
|
||||
call.getAFormat() = fmt and
|
||||
name = call.getAKeyword().getArg() and
|
||||
forall(AdvancedFormatString format | format = call.getAFormat() |
|
||||
not format.getFieldName(_, _) = name
|
||||
) and
|
||||
not exists(call.getKwargs()) and
|
||||
(
|
||||
strictcount(call.getAFormat()) = 1 and fmt_repr = "format \"" + fmt.getText() + "\""
|
||||
or
|
||||
strictcount(call.getAFormat()) != 1 and fmt_repr = "any format used."
|
||||
)
|
||||
select call,
|
||||
"Surplus named argument for string format. An argument named '" + name +
|
||||
"' is provided, but it is not required by $@.", fmt, fmt_repr
|
||||
"Surplus named argument for string format. An argument named '" + name +
|
||||
"' is provided, but it is not required by $@.", fmt, fmt_repr
|
||||
|
||||
@@ -16,10 +16,10 @@ import AdvancedFormatting
|
||||
|
||||
from AdvancedFormattingCall call, AdvancedFormatString fmt, string name
|
||||
where
|
||||
call.getAFormat() = fmt and
|
||||
not name = call.getAKeyword().getArg() and
|
||||
fmt.getFieldName(_, _) = name and
|
||||
not exists(call.getKwargs())
|
||||
call.getAFormat() = fmt and
|
||||
not name = call.getAKeyword().getArg() and
|
||||
fmt.getFieldName(_, _) = name and
|
||||
not exists(call.getKwargs())
|
||||
select call,
|
||||
"Missing named argument for string format. Format $@ requires '" + name + "', but it is omitted.",
|
||||
fmt, "\"" + fmt.getText() + "\""
|
||||
"Missing named argument for string format. Format $@ requires '" + name + "', but it is omitted.",
|
||||
fmt, "\"" + fmt.getText() + "\""
|
||||
|
||||
@@ -15,15 +15,15 @@ import python
|
||||
import AdvancedFormatting
|
||||
|
||||
from
|
||||
AdvancedFormattingCall call, AdvancedFormatString fmt, int arg_count, int max_field,
|
||||
string provided
|
||||
AdvancedFormattingCall call, AdvancedFormatString fmt, int arg_count, int max_field,
|
||||
string provided
|
||||
where
|
||||
arg_count = call.providedArgCount() and
|
||||
max_field = max(fmt.getFieldNumber(_, _)) and
|
||||
call.getAFormat() = fmt and
|
||||
not exists(call.getStarargs()) and
|
||||
arg_count <= max_field and
|
||||
(if arg_count = 1 then provided = " is provided." else provided = " are provided.")
|
||||
arg_count = call.providedArgCount() and
|
||||
max_field = max(fmt.getFieldNumber(_, _)) and
|
||||
call.getAFormat() = fmt and
|
||||
not exists(call.getStarargs()) and
|
||||
arg_count <= max_field and
|
||||
(if arg_count = 1 then provided = " is provided." else provided = " are provided.")
|
||||
select call,
|
||||
"Too few arguments for string format. Format $@ requires at least " + (max_field + 1) + ", but " +
|
||||
arg_count.toString() + provided, fmt, "\"" + fmt.getText() + "\""
|
||||
"Too few arguments for string format. Format $@ requires at least " + (max_field + 1) + ", but " +
|
||||
arg_count.toString() + provided, fmt, "\"" + fmt.getText() + "\""
|
||||
|
||||
Reference in New Issue
Block a user