mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
Fix getAnArgUsageOffset and improve its space complexity
Also add tests checking the output of the new function
This commit is contained in:
@@ -175,14 +175,17 @@ class FormattingCall extends Call {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the `i`th argument to be formatted. */
|
||||
/** Gets the `i`th argument to be formatted. The index `i` is one-based. */
|
||||
Expr getArgumentToBeFormatted(int i) {
|
||||
i >= 0 and
|
||||
i >= 1 and
|
||||
if this.hasExplicitVarargsArray()
|
||||
then
|
||||
result =
|
||||
this.getArgument(1 + this.getFormatStringIndex()).(ArrayCreationExpr).getInit().getInit(i)
|
||||
else result = this.getArgument(this.getFormatStringIndex() + 1 + i)
|
||||
this.getArgument(1 + this.getFormatStringIndex())
|
||||
.(ArrayCreationExpr)
|
||||
.getInit()
|
||||
.getInit(i - 1)
|
||||
else result = this.getArgument(this.getFormatStringIndex() + i)
|
||||
}
|
||||
|
||||
/** Holds if the varargs argument is given as an explicit array. */
|
||||
@@ -441,14 +444,21 @@ private class PrintfFormatString extends FormatString {
|
||||
not result = fmtSpecRefersToSpecificIndex(_)
|
||||
}
|
||||
|
||||
private int getFmtSpecRank(int specOffset) {
|
||||
rank[result](int i | this.fmtSpecIsRef(i)) = specOffset
|
||||
}
|
||||
|
||||
override int getAnArgUsageOffset(int argNo) {
|
||||
argNo = fmtSpecRefersToSpecificIndex(result)
|
||||
or
|
||||
fmtSpecRefersToSequentialIndex(result) and
|
||||
argNo = count(int i | i < result and fmtSpecRefersToSequentialIndex(i))
|
||||
result = rank[argNo](int i | fmtSpecRefersToSequentialIndex(i))
|
||||
or
|
||||
fmtSpecRefersToPrevious(result) and
|
||||
argNo = count(int i | i < result and fmtSpecRefersToSequentialIndex(i)) - 1
|
||||
exists(int previousOffset |
|
||||
getFmtSpecRank(previousOffset) = getFmtSpecRank(result) - 1 and
|
||||
previousOffset = getAnArgUsageOffset(argNo)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
17
java/ql/test/library-tests/format-strings/Test.java
Normal file
17
java/ql/test/library-tests/format-strings/Test.java
Normal file
@@ -0,0 +1,17 @@
|
||||
public class Test {
|
||||
|
||||
public static void test () {
|
||||
String.format("%s", "", "");
|
||||
String.format("s", "");
|
||||
String.format("%2$s %2$s", "", "");
|
||||
String.format("%2$s %1$s", "", "");
|
||||
String.format("%2$s %s", "");
|
||||
String.format("%s%<s", "", "");
|
||||
String.format("%s%%%%%%%%s%n", "", "");
|
||||
String.format("%s%%%%%%%%s%n", "");
|
||||
String.format("%s%%%%%%%s%n", "", "");
|
||||
String.format("%s%%%%%%%s%n", "");
|
||||
String.format("%2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s", "", "");
|
||||
}
|
||||
|
||||
}
|
||||
22
java/ql/test/library-tests/format-strings/test.expected
Normal file
22
java/ql/test/library-tests/format-strings/test.expected
Normal file
@@ -0,0 +1,22 @@
|
||||
| %2$s %1$s | 1 | 5 |
|
||||
| %2$s %1$s | 2 | 0 |
|
||||
| %2$s %2$s | 2 | 0 |
|
||||
| %2$s %2$s | 2 | 5 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 11 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 16 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 20 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 23 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 27 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 38 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 43 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 0 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 31 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 34 |
|
||||
| %2$s %s | 1 | 5 |
|
||||
| %2$s %s | 2 | 0 |
|
||||
| %s | 1 | 0 |
|
||||
| %s%%%%%%%%s%n | 1 | 0 |
|
||||
| %s%%%%%%%s%n | 1 | 0 |
|
||||
| %s%%%%%%%s%n | 2 | 8 |
|
||||
| %s%<s | 1 | 0 |
|
||||
| %s%<s | 1 | 2 |
|
||||
6
java/ql/test/library-tests/format-strings/test.ql
Normal file
6
java/ql/test/library-tests/format-strings/test.ql
Normal file
@@ -0,0 +1,6 @@
|
||||
import java
|
||||
import semmle.code.java.StringFormat
|
||||
|
||||
from FormatString f, int argNo, int offset
|
||||
where offset = f.getAnArgUsageOffset(argNo)
|
||||
select f, argNo, offset
|
||||
Reference in New Issue
Block a user