Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f388aae

Browse files
committed
Fix getAnArgUsageOffset and improve its space complexity
Also add tests checking the output of the new function
1 parent 0db5484 commit f388aae

4 files changed

Lines changed: 61 additions & 6 deletions

File tree

java/ql/src/semmle/code/java/StringFormat.qll

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,17 @@ class FormattingCall extends Call {
175175
)
176176
}
177177

178-
/** Gets the `i`th argument to be formatted. */
178+
/** Gets the `i`th argument to be formatted. The index `i` is one-based. */
179179
Expr getArgumentToBeFormatted(int i) {
180-
i >= 0 and
180+
i >= 1 and
181181
if this.hasExplicitVarargsArray()
182182
then
183183
result =
184-
this.getArgument(1 + this.getFormatStringIndex()).(ArrayCreationExpr).getInit().getInit(i)
185-
else result = this.getArgument(this.getFormatStringIndex() + 1 + i)
184+
this.getArgument(1 + this.getFormatStringIndex())
185+
.(ArrayCreationExpr)
186+
.getInit()
187+
.getInit(i - 1)
188+
else result = this.getArgument(this.getFormatStringIndex() + i)
186189
}
187190

188191
/** Holds if the varargs argument is given as an explicit array. */
@@ -441,14 +444,21 @@ private class PrintfFormatString extends FormatString {
441444
not result = fmtSpecRefersToSpecificIndex(_)
442445
}
443446

447+
private int getFmtSpecRank(int specOffset) {
448+
rank[result](int i | this.fmtSpecIsRef(i)) = specOffset
449+
}
450+
444451
override int getAnArgUsageOffset(int argNo) {
445452
argNo = fmtSpecRefersToSpecificIndex(result)
446453
or
447454
fmtSpecRefersToSequentialIndex(result) and
448-
argNo = count(int i | i < result and fmtSpecRefersToSequentialIndex(i))
455+
result = rank[argNo](int i | fmtSpecRefersToSequentialIndex(i))
449456
or
450457
fmtSpecRefersToPrevious(result) and
451-
argNo = count(int i | i < result and fmtSpecRefersToSequentialIndex(i)) - 1
458+
exists(int previousOffset |
459+
getFmtSpecRank(previousOffset) = getFmtSpecRank(result) - 1 and
460+
previousOffset = getAnArgUsageOffset(argNo)
461+
)
452462
}
453463
}
454464

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
public class Test {
2+
3+
public static void test () {
4+
String.format("%s", "", "");
5+
String.format("s", "");
6+
String.format("%2$s %2$s", "", "");
7+
String.format("%2$s %1$s", "", "");
8+
String.format("%2$s %s", "");
9+
String.format("%s%<s", "", "");
10+
String.format("%s%%%%%%%%s%n", "", "");
11+
String.format("%s%%%%%%%%s%n", "");
12+
String.format("%s%%%%%%%s%n", "", "");
13+
String.format("%s%%%%%%%s%n", "");
14+
String.format("%2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s", "", "");
15+
}
16+
17+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
| %2$s %1$s | 1 | 5 |
2+
| %2$s %1$s | 2 | 0 |
3+
| %2$s %2$s | 2 | 0 |
4+
| %2$s %2$s | 2 | 5 |
5+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 11 |
6+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 16 |
7+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 20 |
8+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 23 |
9+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 27 |
10+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 38 |
11+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 43 |
12+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 0 |
13+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 31 |
14+
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 34 |
15+
| %2$s %s | 1 | 5 |
16+
| %2$s %s | 2 | 0 |
17+
| %s | 1 | 0 |
18+
| %s%%%%%%%%s%n | 1 | 0 |
19+
| %s%%%%%%%s%n | 1 | 0 |
20+
| %s%%%%%%%s%n | 2 | 8 |
21+
| %s%<s | 1 | 0 |
22+
| %s%<s | 1 | 2 |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import java
2+
import semmle.code.java.StringFormat
3+
4+
from FormatString f, int argNo, int offset
5+
where offset = f.getAnArgUsageOffset(argNo)
6+
select f, argNo, offset

0 commit comments

Comments
 (0)