Skip to content

Commit 370808a

Browse files
committed
BuildStringPassthruGraph: proper handling of long/double arguments
1 parent dcfb934 commit 370808a

3 files changed

Lines changed: 46 additions & 21 deletions

File tree

findbugs/src/java/edu/umd/cs/findbugs/detect/BuildStringPassthruGraph.java

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
import org.apache.bcel.classfile.Code;
3333
import org.apache.bcel.classfile.Method;
34+
import org.apache.bcel.generic.Type;
3435

3536
import edu.umd.cs.findbugs.BugReporter;
3637
import edu.umd.cs.findbugs.NonReportingDetector;
@@ -205,9 +206,7 @@ public Map<MethodDescriptor, int[]> getFileNameStringMethods() {
205206

206207
private int nArgs;
207208

208-
private int shift;
209-
210-
private boolean[] argEnabled;
209+
private int[] argNums;
211210

212211
private List<MethodParameter>[] passedParameters;
213212

@@ -218,30 +217,36 @@ public BuildStringPassthruGraph(BugReporter bugReporter) {
218217
@SuppressWarnings("unchecked")
219218
@Override
220219
public void visitMethod(Method obj) {
221-
argEnabled = null;
222-
org.apache.bcel.generic.Type[] argumentTypes = obj.getArgumentTypes();
220+
argNums = null;
221+
Type[] argumentTypes = obj.getArgumentTypes();
223222
if(argumentTypes.length == 0) {
224223
return;
225224
}
225+
int lvNum = obj.isStatic() ? 0 : 1;
226226
nArgs = argumentTypes.length;
227+
int argCount = lvNum;
228+
for(Type type : argumentTypes) {
229+
argCount+=type.getSize();
230+
}
227231
for(int i=0; i<nArgs; i++) {
228232
if(argumentTypes[i].getSignature().equals("Ljava/lang/String;")) {
229-
if(argEnabled == null) {
230-
argEnabled = new boolean[nArgs];
233+
if(argNums == null) {
234+
argNums = new int[argCount];
235+
Arrays.fill(argNums, -1);
231236
}
232-
argEnabled[i] = true;
237+
argNums[lvNum] = i;
233238
}
239+
lvNum+=argumentTypes[i].getSize();
234240
}
235-
if(argEnabled != null) {
236-
shift = obj.isStatic() ? 0 : -1;
241+
if(argNums != null) {
237242
passedParameters = new List[nArgs];
238243
}
239244
super.visitMethod(obj);
240245
}
241246

242247
@Override
243248
public boolean shouldVisitCode(Code obj) {
244-
return argEnabled != null;
249+
return argNums != null;
245250
}
246251

247252
@Override
@@ -261,10 +266,13 @@ public void visitAfter(Code obj) {
261266
@Override
262267
public void sawOpcode(int seen) {
263268
if (isRegisterStore()) {
264-
int param = getRegisterOperand() + shift;
265-
if (param >= 0 && param < nArgs) {
266-
argEnabled[param] = false;
267-
passedParameters[param] = null;
269+
int param = getRegisterOperand();
270+
if (param < argNums.length) {
271+
int argNum = argNums[param];
272+
argNums[param] = -1;
273+
if(argNum >= 0) {
274+
passedParameters[argNum] = null;
275+
}
268276
}
269277
}
270278
switch (seen) {
@@ -276,11 +284,11 @@ public void sawOpcode(int seen) {
276284
int callArgs = getNumberArguments(md.getSignature());
277285
for (int i = 0; i < callArgs; i++) {
278286
Item item = getStack().getStackItem(callArgs - 1 - i);
279-
int param = item.getRegisterNumber() + shift;
280-
if (param >= 0 && param < nArgs && argEnabled[param]) {
281-
List<MethodParameter> list = passedParameters[param];
287+
int param = item.getRegisterNumber();
288+
if (param >= 0 && param < argNums.length && argNums[param] != -1) {
289+
List<MethodParameter> list = passedParameters[argNums[param]];
282290
if (list == null) {
283-
passedParameters[param] = list = new ArrayList<>();
291+
passedParameters[argNums[param]] = list = new ArrayList<>();
284292
}
285293
list.add(new MethodParameter(md, i));
286294
}

findbugs/src/java/edu/umd/cs/findbugs/detect/DumbMethodInvocations.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
2323
import edu.umd.cs.findbugs.ba.Location;
2424
import edu.umd.cs.findbugs.ba.MethodUnprofitableException;
25+
import edu.umd.cs.findbugs.ba.SignatureParser;
2526
import edu.umd.cs.findbugs.ba.constant.Constant;
2627
import edu.umd.cs.findbugs.ba.constant.ConstantDataflow;
2728
import edu.umd.cs.findbugs.ba.constant.ConstantFrame;
@@ -95,6 +96,8 @@ private void analyzeMethod(ClassContext classContext, Method method) throws CFGB
9596
}
9697
InvokeInstruction iins = (InvokeInstruction) ins;
9798

99+
SignatureParser parser = new SignatureParser(iins.getSignature(cpg));
100+
98101
ConstantFrame frame = constantDataflow.getFactAtLocation(location);
99102
if (!frame.isValid()) {
100103
// This basic block is probably dead
@@ -104,7 +107,7 @@ private void analyzeMethod(ClassContext classContext, Method method) throws CFGB
104107
MethodDescriptor md = new MethodDescriptor(iins, cpg);
105108
if (allDatabasePasswordMethods.containsKey(md)) {
106109
for(int paramNumber : allDatabasePasswordMethods.get(md)) {
107-
Constant operandValue = frame.getStackValue(iins.getArgumentTypes(cpg).length-1-paramNumber);
110+
Constant operandValue = frame.getArgument(iins, cpg, paramNumber, parser);
108111
if (operandValue.isConstantString()) {
109112
String password = operandValue.getConstantString();
110113
if (password.length() == 0) {
@@ -134,7 +137,7 @@ private void analyzeMethod(ClassContext classContext, Method method) throws CFGB
134137
} else if (allFileNameStringMethods.containsKey(md)) {
135138

136139
for(int paramNumber : allFileNameStringMethods.get(md)) {
137-
Constant operandValue = frame.getStackValue(iins.getArgumentTypes(cpg).length-1-paramNumber);
140+
Constant operandValue = frame.getArgument(iins, cpg, paramNumber, parser);
138141
if (!operandValue.isConstantString()) {
139142
continue;
140143
}

findbugsTestCases/src/java/sfBugsNew/Feature314.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ public void testHardCodedPuzzlingOk() throws FileNotFoundException {
2727
openFilePuzzling4("c:\\file.txt", "ok", "c:\\file.txt", "c:\\file.txt");
2828
}
2929

30+
@ExpectWarning("DMI_HARDCODED_ABSOLUTE_FILENAME")
31+
public void testHardCodedLong() throws FileNotFoundException {
32+
openFilePuzzlingLong(1L, "c:\\file.txt", "ok", 0.0);
33+
}
34+
35+
@NoWarning("DMI_HARDCODED_ABSOLUTE_FILENAME")
36+
public void testHardCodedLongOk() throws FileNotFoundException {
37+
openFilePuzzlingLong(1L, "ok", "c:\\file.txt", 0.0);
38+
}
39+
3040
private FileOutputStream openFile(String name) throws FileNotFoundException {
3141
return new FileOutputStream(name);
3242
}
@@ -52,6 +62,10 @@ private FileOutputStream openFilePuzzling4(String arg1, String name, String arg2
5262
return openFilePuzzling3(name, arg1, arg2, arg3);
5363
}
5464

65+
private FileOutputStream openFilePuzzlingLong(long arg1, String name, String arg2, double arg3) throws FileNotFoundException {
66+
return openFilePuzzling3(name, String.valueOf(arg1), arg2, String.valueOf(arg3));
67+
}
68+
5569
@ExpectWarning("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE")
5670
public boolean test(Connection c, String code) throws SQLException {
5771
return Sql.hasResult(c, "SELECT 1 FROM myTable WHERE code='"+code+"'");

0 commit comments

Comments
 (0)