@@ -162,9 +162,6 @@ private predicate inputStreamWrapper(Constructor c, int argi) {
162162private predicate constructorStep ( Expr tracked , ConstructorCall sink ) {
163163 exists ( int argi | sink .getArgument ( argi ) = tracked |
164164 exists ( string s | sink .getConstructedType ( ) .getQualifiedName ( ) = s |
165- // String constructor does nothing to data
166- s = "java.lang.String" and argi = 0
167- or
168165 // some readers preserve the content of streams
169166 s = "java.io.InputStreamReader" and argi = 0
170167 or
@@ -254,18 +251,20 @@ private predicate constructorStep(Expr tracked, ConstructorCall sink) {
254251 argi = 0 and
255252 tracked .getType ( ) instanceof TypeString
256253 )
254+ or
255+ sink .getConstructor ( ) .( TaintPreservingCallable ) .returnsTaintFrom ( argToParam ( sink , argi ) )
257256 )
258257}
259258
260259/**
261260 * Converts an argument index to a formal parameter index.
262261 * This is relevant for varadic methods.
263262 */
264- private int argToParam ( MethodAccess ma , int arg ) {
265- exists ( ma .getArgument ( arg ) ) and
266- exists ( Method m | m = ma . getMethod ( ) |
267- if m .isVarargs ( ) and arg >= m .getNumberOfParameters ( )
268- then result = m .getNumberOfParameters ( ) - 1
263+ private int argToParam ( Call call , int arg ) {
264+ exists ( call .getArgument ( arg ) ) and
265+ exists ( Callable c | c = call . getCallee ( ) |
266+ if c .isVarargs ( ) and arg >= c .getNumberOfParameters ( )
267+ then result = c .getNumberOfParameters ( ) - 1
269268 else result = arg
270269 )
271270}
@@ -296,7 +295,7 @@ private predicate taintPreservingQualifierToArgument(Method m, int arg) {
296295 m .hasName ( "read" ) and
297296 arg = 0
298297 or
299- m .( TaintPreservingMethod ) .transfersTaint ( - 1 , arg )
298+ m .( TaintPreservingCallable ) .transfersTaint ( - 1 , arg )
300299}
301300
302301/** Access to a method that passes taint from the qualifier. */
@@ -378,10 +377,10 @@ private predicate taintPreservingQualifierToMethod(Method m) {
378377 )
379378 )
380379 or
381- m .( TaintPreservingMethod ) .returnsTaintFrom ( - 1 )
380+ m .( TaintPreservingCallable ) .returnsTaintFrom ( - 1 )
382381}
383382
384- private class StringReplaceMethod extends TaintPreservingMethod {
383+ private class StringReplaceMethod extends TaintPreservingCallable {
385384 StringReplaceMethod ( ) {
386385 getDeclaringType ( ) instanceof TypeString and
387386 (
@@ -523,7 +522,7 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
523522 method .hasName ( "append" ) and
524523 arg = 0
525524 or
526- method .( TaintPreservingMethod ) .returnsTaintFrom ( arg )
525+ method .( TaintPreservingCallable ) .returnsTaintFrom ( arg )
527526}
528527
529528/**
@@ -571,7 +570,7 @@ private predicate taintPreservingArgToArg(Method method, int input, int output)
571570 input = 0 and
572571 output = 2
573572 or
574- method .( TaintPreservingMethod ) .transfersTaint ( input , output )
573+ method .( TaintPreservingCallable ) .transfersTaint ( input , output )
575574}
576575
577576/**
@@ -607,10 +606,14 @@ private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
607606 method .overrides * ( append ) and
608607 append .hasName ( "append" ) and
609608 arg = 0 and
610- append .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "StringWriter" )
609+ (
610+ append .getDeclaringType ( ) .hasQualifiedName ( "java.lang" , "StringBuilder" ) or
611+ append .getDeclaringType ( ) .hasQualifiedName ( "java.lang" , "StringBuffer" ) or
612+ append .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "StringWriter" )
613+ )
611614 )
612615 or
613- method .( TaintPreservingMethod ) .transfersTaint ( arg , - 1 )
616+ method .( TaintPreservingCallable ) .transfersTaint ( arg , - 1 )
614617}
615618
616619/** A comparison or equality test with a constant. */
@@ -734,15 +737,27 @@ private class TypeFormatter extends Class {
734737 TypeFormatter ( ) { this .hasQualifiedName ( "java.util" , "Formatter" ) }
735738}
736739
737- private class FormatterMethod extends TaintPreservingMethod {
738- FormatterMethod ( ) {
739- getDeclaringType ( ) instanceof TypeFormatter and
740- hasName ( [ "format" , "out" , "toString" ] )
740+ private class FormatterCallable extends TaintPreservingCallable {
741+ FormatterCallable ( ) {
742+ this .getDeclaringType ( ) instanceof TypeFormatter and
743+ (
744+ this .hasName ( [ "format" , "out" , "toString" ] )
745+ or
746+ this
747+ .( Constructor )
748+ .getParameterType ( 0 )
749+ .( RefType )
750+ .getASourceSupertype * ( )
751+ .hasQualifiedName ( "java.lang" , "Appendable" )
752+ )
741753 }
742754
743- override predicate returnsTaintFrom ( int arg ) { arg = [ - 1 .. getNumberOfParameters ( ) ] }
755+ override predicate returnsTaintFrom ( int arg ) {
756+ if this instanceof Constructor then arg = 0 else arg = [ - 1 .. getNumberOfParameters ( ) ]
757+ }
744758
745759 override predicate transfersTaint ( int src , int sink ) {
760+ this .hasName ( "format" ) and
746761 sink = - 1 and
747762 src = [ 0 .. getNumberOfParameters ( ) ]
748763 }
0 commit comments