@@ -206,6 +206,68 @@ module StringOps {
206206
207207 override string getReplacedString ( ) { result = this .getArgument ( 1 ) .getStringValue ( ) }
208208 }
209+
210+ /**
211+ * A call to `strings.NewReplacer`.
212+ */
213+ private class StringsNewReplacerCall extends DataFlow:: CallNode {
214+ StringsNewReplacerCall ( ) { this .getTarget ( ) .hasQualifiedName ( "strings" , "NewReplacer" ) }
215+
216+ /**
217+ * Gets an argument to this call corresponding to a string that will be
218+ * replaced.
219+ */
220+ DataFlow:: Node getAReplacedArgument ( ) {
221+ exists ( int n | n % 2 = 0 and result = this .getArgument ( n ) )
222+ }
223+ }
224+
225+ /**
226+ * A configuration for tracking flow from a call to `strings.NewReplacer` to
227+ * the receiver of a call to `strings.Replacer.Replace` or
228+ * `strings.Replacer.WriteString`.
229+ */
230+ private class StringsNewReplacerConfiguration extends DataFlow2:: Configuration {
231+ StringsNewReplacerConfiguration ( ) { this = "StringsNewReplacerConfiguration" }
232+
233+ override predicate isSource ( DataFlow:: Node source ) {
234+ source instanceof StringsNewReplacerCall
235+ }
236+
237+ override predicate isSink ( DataFlow:: Node sink ) {
238+ exists ( DataFlow:: MethodCallNode call |
239+ sink = call .getReceiver ( ) and
240+ call .getTarget ( ) .hasQualifiedName ( "strings" , "Replacer" , [ "Replace" , "WriteString" ] )
241+ )
242+ }
243+ }
244+
245+ /**
246+ * A call to `strings.Replacer.Replace` or `strings.Replacer.WriteString`.
247+ */
248+ private class StringsReplacerReplaceOrWriteString extends Range {
249+ string replacedString ;
250+
251+ StringsReplacerReplaceOrWriteString ( ) {
252+ exists (
253+ StringsNewReplacerConfiguration config , StringsNewReplacerCall source ,
254+ DataFlow:: Node sink , DataFlow:: MethodCallNode call
255+ |
256+ config .hasFlow ( source , sink ) and
257+ sink = call .getReceiver ( ) and
258+ replacedString = source .getAReplacedArgument ( ) .getStringValue ( ) and
259+ (
260+ call .getTarget ( ) .hasQualifiedName ( "strings" , "Replacer" , "Replace" ) and
261+ this = call .getResult ( )
262+ or
263+ call .getTarget ( ) .hasQualifiedName ( "strings" , "Replacer" , "WriteString" ) and
264+ this = call .getArgument ( 1 )
265+ )
266+ )
267+ }
268+
269+ override string getReplacedString ( ) { result = replacedString }
270+ }
209271 }
210272
211273 /** Provides predicates and classes for working with Printf-style formatters. */
0 commit comments