@@ -81,8 +81,34 @@ module Fasthttp {
8181 }
8282 }
8383
84+ private predicate responseBodyWriterResult ( DataFlow:: Node src ) {
85+ exists ( Method responseBodyWriter |
86+ responseBodyWriter .hasQualifiedName ( packagePath ( ) , "Response" , "BodyWriter" ) and
87+ src = responseBodyWriter .getACall ( ) .getResult ( 0 )
88+ )
89+ }
90+
91+ private predicate writerSinkAndBody ( DataFlow:: Node sink , DataFlow:: Node body ) {
92+ exists ( DataFlow:: CallNode writerCall |
93+ writerCall = any ( Method write | write .hasQualifiedName ( "io" , "Writer" , "Write" ) ) .getACall ( ) and
94+ sink = writerCall .getReceiver ( ) and
95+ body = writerCall .getArgument ( 0 )
96+ )
97+ or
98+ exists ( DataFlow:: CallNode writerCall |
99+ writerCall = any ( Function fprintf | fprintf .hasQualifiedName ( "fmt" , "Fprintf" ) ) .getACall ( ) and
100+ sink = writerCall .getArgument ( 0 ) and
101+ body = writerCall .getSyntacticArgument ( any ( int i | i > 1 ) )
102+ )
103+ }
104+
105+ private predicate writerSink ( DataFlow:: Node sink ) { writerSinkAndBody ( sink , _) }
106+
107+ private module ResponseBodyWriterFlow =
108+ DataFlow:: SimpleGlobal< responseBodyWriterResult / 1 > :: Graph< writerSink / 1 > ;
109+
84110 private class ResponseBody extends Http:: ResponseBody:: Range {
85- DataFlow:: MethodCallNode call ;
111+ DataFlow:: MethodCallNode responseWriterMethodCall ;
86112
87113 ResponseBody ( ) {
88114 exists ( Method m |
@@ -91,32 +117,24 @@ module Fasthttp {
91117 "AppendBody" , "AppendBodyString" , "SetBody" , "SetBodyRaw" , "SetBodyStream" ,
92118 "SetBodyString" , "Success" , "SuccessString"
93119 ] ) and
94- call = m .getACall ( ) and
95- this = call .getArgument ( 0 )
120+ responseWriterMethodCall = m .getACall ( ) and
121+ this = responseWriterMethodCall .getArgument ( 0 )
96122 or
97123 m .hasQualifiedName ( packagePath ( ) , "RequestCtx" , [ "Success" , "SuccessString" ] ) and
98- call = m .getACall ( ) and
99- this = call .getArgument ( 1 )
100- )
101- or
102- exists ( Method responseBodyWriter , DataFlow:: CallNode writerCall |
103- responseBodyWriter .hasQualifiedName ( packagePath ( ) , "Response" , "BodyWriter" ) and
104- call = responseBodyWriter .getACall ( ) and
105- writerCall = any ( Method write | write .hasQualifiedName ( "io" , "Writer" , "Write" ) ) .getACall ( ) and
106- this = writerCall .getArgument ( 0 ) and
107- DataFlow:: localFlow ( call .getResult ( 0 ) , writerCall .getReceiver ( ) )
124+ responseWriterMethodCall = m .getACall ( ) and
125+ this = responseWriterMethodCall .getArgument ( 1 )
108126 )
109127 or
110- exists ( Method responseBodyWriter , DataFlow:: CallNode writerCall |
111- responseBodyWriter .hasQualifiedName ( packagePath ( ) , "Response" , "BodyWriter" ) and
112- call = responseBodyWriter .getACall ( ) and
113- writerCall = any ( Function fprintf | fprintf .hasQualifiedName ( "fmt" , "Fprintf" ) ) .getACall ( ) and
114- this = writerCall .getSyntacticArgument ( any ( int i | i > 1 ) ) and
115- DataFlow:: localFlow ( call .getResult ( 0 ) , writerCall .getArgument ( 0 ) )
128+ exists ( ResponseBodyWriterFlow:: PathNode source , ResponseBodyWriterFlow:: PathNode sink |
129+ ResponseBodyWriterFlow:: flowPath ( source , sink ) and
130+ responseWriterMethodCall = source .getNode ( ) and
131+ writerSinkAndBody ( sink .getNode ( ) , this )
116132 )
117133 }
118134
119- override Http:: ResponseWriter getResponseWriter ( ) { result .getANode ( ) = call .getReceiver ( ) }
135+ override Http:: ResponseWriter getResponseWriter ( ) {
136+ result .getANode ( ) = responseWriterMethodCall .getReceiver ( )
137+ }
120138 }
121139
122140 /**
0 commit comments