47
47
import edu .umd .cs .findbugs .BugReporter ;
48
48
import edu .umd .cs .findbugs .Detector ;
49
49
import edu .umd .cs .findbugs .SourceLineAnnotation ;
50
+ import edu .umd .cs .findbugs .ba .AnalysisContext ;
50
51
import edu .umd .cs .findbugs .ba .BasicBlock ;
51
52
import edu .umd .cs .findbugs .ba .CFG ;
52
53
import edu .umd .cs .findbugs .ba .CFGBuilderException ;
53
54
import edu .umd .cs .findbugs .ba .ClassContext ;
54
55
import edu .umd .cs .findbugs .ba .DataflowAnalysisException ;
55
56
import edu .umd .cs .findbugs .ba .EdgeTypes ;
56
57
import edu .umd .cs .findbugs .ba .Location ;
58
+ import edu .umd .cs .findbugs .ba .SignatureParser ;
57
59
import edu .umd .cs .findbugs .ba .constant .Constant ;
58
60
import edu .umd .cs .findbugs .ba .constant .ConstantDataflow ;
59
61
import edu .umd .cs .findbugs .ba .constant .ConstantFrame ;
60
62
import edu .umd .cs .findbugs .ba .type .TopType ;
61
63
import edu .umd .cs .findbugs .ba .type .TypeDataflow ;
62
64
import edu .umd .cs .findbugs .ba .type .TypeFrame ;
65
+ import edu .umd .cs .findbugs .ba .vna .ValueNumber ;
66
+ import edu .umd .cs .findbugs .ba .vna .ValueNumberDataflow ;
67
+ import edu .umd .cs .findbugs .ba .vna .ValueNumberFrame ;
63
68
import edu .umd .cs .findbugs .classfile .CheckedAnalysisException ;
64
69
import edu .umd .cs .findbugs .classfile .Global ;
65
70
import edu .umd .cs .findbugs .classfile .MethodDescriptor ;
@@ -496,6 +501,7 @@ private void analyzeMethod(ClassContext classContext, Method method) throws Data
496
501
StringAppendState stringAppendState = getStringAppendState (cfg , cpg );
497
502
498
503
ConstantDataflow dataflow = classContext .getConstantDataflow (method );
504
+ ValueNumberDataflow vnd = classContext .getValueNumberDataflow (method );
499
505
for (Iterator <Location > i = cfg .locationIterator (); i .hasNext ();) {
500
506
Location location = i .next ();
501
507
Instruction ins = location .getHandle ().getInstruction ();
@@ -522,15 +528,16 @@ private void analyzeMethod(ClassContext classContext, Method method) throws Data
522
528
}
523
529
}
524
530
ConstantFrame frame = dataflow .getFactAtLocation (location );
525
- int numArguments = frame .getNumArguments (invoke , cpg );
526
- Constant value = frame .getStackValue (numArguments - 1 - paramNumber );
531
+ SignatureParser parser = new SignatureParser (invoke .getSignature (cpg ));
532
+ Constant value = frame .getArgument (invoke , cpg , paramNumber , parser );
533
+ ValueNumber vn = vnd .getFactAtLocation (location ).getArgument (invoke , cpg , paramNumber , parser );
527
534
528
535
if (!value .isConstantString ()) {
529
536
// TODO: verify it's the same string represented by
530
537
// stringAppendState
531
538
// FIXME: will false positive on const/static strings
532
539
// returns by methods
533
- Location prev = getPreviousLocation ( cfg , location , true );
540
+ Location prev = getValueNumberCreationLocation ( vnd , vn );
534
541
if (prev == null || !isSafeValue (prev , cpg )) {
535
542
BugInstance bug = generateBugInstance (javaClass , methodGen , location .getHandle (), stringAppendState ,
536
543
executeMethod );
@@ -544,6 +551,25 @@ private void analyzeMethod(ClassContext classContext, Method method) throws Data
544
551
bugAccumulator .reportAccumulatedBugs ();
545
552
}
546
553
554
+ private Location getValueNumberCreationLocation (ValueNumberDataflow vnd , ValueNumber vn ) {
555
+ ConstantPoolGen cpg = vnd .getCFG ().getMethodGen ().getConstantPool ();
556
+ for (Iterator <Location > it = vnd .getCFG ().locationIterator (); it .hasNext (); ) {
557
+ Location loc = it .next ();
558
+ if (loc .getHandle ().getInstruction ().produceStack (cpg ) != 1 ) {
559
+ continue ;
560
+ }
561
+ try {
562
+ ValueNumberFrame vnf = vnd .getFactAfterLocation (loc );
563
+ if (vnf .getTopValue ().equals (vn )) {
564
+ return loc ;
565
+ }
566
+ } catch (DataflowAnalysisException e ) {
567
+ AnalysisContext .logError ("While analyzing " +vnd .getCFG ().getMethodGen ()+" at " +loc , e );
568
+ }
569
+ }
570
+ return null ;
571
+ }
572
+
547
573
@ Override
548
574
public void report () {
549
575
}
0 commit comments