Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,13 @@ class FormatLiteral extends Literal instanceof StringLiteral {
*/
int getConvSpecOffset(int n) { result = this.getFormat().indexOf("%", n, 0) }

/**
* Gets the nth conversion specifier string.
*/
private string getConvSpecString(int n) {
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, it's quite clean for what it accomplishes. 👍

}
Comment on lines +462 to +467

/*
* Each of these predicates gets a regular expressions to match each individual
* parts of a conversion specifier.
Expand Down Expand Up @@ -524,22 +531,20 @@ class FormatLiteral extends Literal instanceof StringLiteral {
int n, string spec, string params, string flags, string width, string prec, string len,
string conv
) {
exists(int offset, string fmt, string rst, string regexp |
offset = this.getConvSpecOffset(n) and
fmt = this.getFormat() and
rst = fmt.substring(offset, fmt.length()) and
exists(string convSpec, string regexp |
convSpec = this.getConvSpecString(n) and
regexp = this.getConvSpecRegexp() and
(
spec = rst.regexpCapture(regexp, 1) and
params = rst.regexpCapture(regexp, 2) and
flags = rst.regexpCapture(regexp, 3) and
width = rst.regexpCapture(regexp, 4) and
prec = rst.regexpCapture(regexp, 5) and
len = rst.regexpCapture(regexp, 6) and
conv = rst.regexpCapture(regexp, 7)
spec = convSpec.regexpCapture(regexp, 1) and
params = convSpec.regexpCapture(regexp, 2) and
flags = convSpec.regexpCapture(regexp, 3) and
width = convSpec.regexpCapture(regexp, 4) and
prec = convSpec.regexpCapture(regexp, 5) and
len = convSpec.regexpCapture(regexp, 6) and
conv = convSpec.regexpCapture(regexp, 7)
or
spec = rst.regexpCapture(regexp, 1) and
not exists(rst.regexpCapture(regexp, 2)) and
spec = convSpec.regexpCapture(regexp, 1) and
not exists(convSpec.regexpCapture(regexp, 2)) and
params = "" and
flags = "" and
width = "" and
Expand All @@ -554,12 +559,10 @@ class FormatLiteral extends Literal instanceof StringLiteral {
* Gets the nth conversion specifier (including the initial `%`).
*/
string getConvSpec(int n) {
exists(int offset, string fmt, string rst, string regexp |
offset = this.getConvSpecOffset(n) and
fmt = this.getFormat() and
rst = fmt.substring(offset, fmt.length()) and
exists(string convSpec, string regexp |
convSpec = this.getConvSpecString(n) and
regexp = this.getConvSpecRegexp() and
result = rst.regexpCapture(regexp, 1)
result = convSpec.regexpCapture(regexp, 1)
)
}

Expand Down
21 changes: 13 additions & 8 deletions cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ class ScanfFormatLiteral extends Expr {
)
}

/**
* Gets the nth conversion specifier string.
*/
private string getConvSpecString(int n) {
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
}
Comment on lines +197 to +202

/**
* Gets the regular expression to match each individual part of a conversion specifier.
*/
Expand Down Expand Up @@ -227,16 +234,14 @@ class ScanfFormatLiteral extends Expr {
* specifier.
*/
predicate parseConvSpec(int n, string spec, string width, string len, string conv) {
exists(int offset, string fmt, string rst, string regexp |
offset = this.getConvSpecOffset(n) and
fmt = this.getFormat() and
rst = fmt.substring(offset, fmt.length()) and
exists(string convSpec, string regexp |
convSpec = this.getConvSpecString(n) and
regexp = this.getConvSpecRegexp() and
(
spec = rst.regexpCapture(regexp, 1) and
width = rst.regexpCapture(regexp, 2) and
len = rst.regexpCapture(regexp, 3) and
conv = rst.regexpCapture(regexp, 4)
spec = convSpec.regexpCapture(regexp, 1) and
width = convSpec.regexpCapture(regexp, 2) and
len = convSpec.regexpCapture(regexp, 3) and
conv = convSpec.regexpCapture(regexp, 4)
)
)
}
Expand Down
Loading