@@ -22,6 +22,10 @@ abstract class ExternalStringKind extends StringKind {
2222 urlsplit ( fromnode , tonode ) and result .( ExternalUrlSplitResult ) .getItem ( ) = this
2323 or
2424 urlparse ( fromnode , tonode ) and result .( ExternalUrlParseResult ) .getItem ( ) = this
25+ or
26+ parse_qs ( fromnode , tonode ) and result .( ExternalStringDictKind ) .getValue ( ) = this
27+ or
28+ parse_qsl ( fromnode , tonode ) and result .( SequenceKind ) .getItem ( ) .( SequenceKind ) .getItem ( ) = this
2529 }
2630}
2731
@@ -181,6 +185,58 @@ private predicate urlparse(ControlFlowNode fromnode, CallNode tonode) {
181185 )
182186}
183187
188+ private predicate parse_qs ( ControlFlowNode fromnode , CallNode tonode ) {
189+ // This could be implemented as `exists(FunctionValue` without the explicit six part,
190+ // but then our tests will need to import +100 modules, so for now this slightly
191+ // altered version gets to live on.
192+ exists ( Value parse_qs |
193+ (
194+ parse_qs = Value:: named ( "six.moves.urllib.parse.parse_qs" )
195+ or
196+ // Python 2
197+ parse_qs = Value:: named ( "urlparse.parse_qs" )
198+ or
199+ // Python 2 deprecated version of `urlparse.parse_qs`
200+ parse_qs = Value:: named ( "cgi.parse_qs" )
201+ or
202+ // Python 3
203+ parse_qs = Value:: named ( "urllib.parse.parse_qs" )
204+ ) and
205+ tonode = parse_qs .getACall ( ) and
206+ (
207+ tonode .getArg ( 0 ) = fromnode
208+ or
209+ tonode .getArgByName ( "qs" ) = fromnode
210+ )
211+ )
212+ }
213+
214+ private predicate parse_qsl ( ControlFlowNode fromnode , CallNode tonode ) {
215+ // This could be implemented as `exists(FunctionValue` without the explicit six part,
216+ // but then our tests will need to import +100 modules, so for now this slightly
217+ // altered version gets to live on.
218+ exists ( Value parse_qsl |
219+ (
220+ parse_qsl = Value:: named ( "six.moves.urllib.parse.parse_qsl" )
221+ or
222+ // Python 2
223+ parse_qsl = Value:: named ( "urlparse.parse_qsl" )
224+ or
225+ // Python 2 deprecated version of `urlparse.parse_qsl`
226+ parse_qsl = Value:: named ( "cgi.parse_qsl" )
227+ or
228+ // Python 3
229+ parse_qsl = Value:: named ( "urllib.parse.parse_qsl" )
230+ ) and
231+ tonode = parse_qsl .getACall ( ) and
232+ (
233+ tonode .getArg ( 0 ) = fromnode
234+ or
235+ tonode .getArgByName ( "qs" ) = fromnode
236+ )
237+ )
238+ }
239+
184240/** A kind of "taint", representing an open file-like object from an external source. */
185241class ExternalFileObject extends TaintKind {
186242 ExternalStringKind valueKind ;
0 commit comments