@@ -2194,6 +2194,14 @@ module StdlibPrivate {
21942194 .calls ( any ( WsgiServerSubclass cls ) .getASelfRef ( ) , "set_app" )
21952195 ) and
21962196 appArg in [ setAppCall .getArg ( 0 ) , setAppCall .getArgByName ( "application" ) ]
2197+ or
2198+ // `make_server` calls `set_app`
2199+ setAppCall =
2200+ API:: moduleImport ( "wsgiref" )
2201+ .getMember ( "simple_server" )
2202+ .getMember ( "make_server" )
2203+ .getACall ( ) and
2204+ appArg in [ setAppCall .getArg ( 2 ) , setAppCall .getArgByName ( "app" ) ]
21972205 |
21982206 appArg = poorMansFunctionTracker ( this )
21992207 )
@@ -2305,6 +2313,109 @@ module StdlibPrivate {
23052313
23062314 override string getMimetypeDefault ( ) { none ( ) }
23072315 }
2316+
2317+ /**
2318+ * Provides models for the `wsgiref.headers.Headers` class
2319+ *
2320+ * See https://docs.python.org/3/library/wsgiref.html#module-wsgiref.headers.
2321+ */
2322+ module Headers {
2323+ /** Gets a reference to the `wsgiref.headers.Headers` class. */
2324+ API:: Node classRef ( ) {
2325+ result = API:: moduleImport ( "wsgiref" ) .getMember ( "headers" ) .getMember ( "Headers" )
2326+ or
2327+ result = ModelOutput:: getATypeNode ( "wsqiref.headers.Headers~Subclass" ) .getASubclass * ( )
2328+ }
2329+
2330+ /** Gets a reference to an instance of `wsgiref.headers.Headers`. */
2331+ private DataFlow:: TypeTrackingNode instance ( DataFlow:: TypeTracker t ) {
2332+ t .start ( ) and
2333+ result = classRef ( ) .getACall ( )
2334+ or
2335+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
2336+ }
2337+
2338+ /** Gets a reference to an instance of `wsgiref.headers.Headers`. */
2339+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
2340+
2341+ /** A class instantiation of `wsgiref.headers.Headers`, conidered as a write to a response header. */
2342+ private class WsgirefHeadersInstantiation extends Http:: Server:: ResponseHeaderBulkWrite:: Range ,
2343+ DataFlow:: CallCfgNode
2344+ {
2345+ WsgirefHeadersInstantiation ( ) { this = classRef ( ) .getACall ( ) }
2346+
2347+ override DataFlow:: Node getBulkArg ( ) {
2348+ result = [ this .getArg ( 0 ) , this .getArgByName ( "headers" ) ]
2349+ }
2350+
2351+ // TODO: implement validator
2352+ override predicate nameAllowsNewline ( ) { any ( ) }
2353+
2354+ override predicate valueAllowsNewline ( ) { any ( ) }
2355+ }
2356+
2357+ /**
2358+ * A call to a `start_response` function that sets the response headers.
2359+ */
2360+ private class WsgirefSimpleServerSetHeaders extends Http:: Server:: ResponseHeaderBulkWrite:: Range ,
2361+ DataFlow:: CallCfgNode
2362+ {
2363+ WsgirefSimpleServerSetHeaders ( ) { this .getFunction ( ) = startResponse ( ) }
2364+
2365+ override DataFlow:: Node getBulkArg ( ) {
2366+ result = [ this .getArg ( 1 ) , this .getArgByName ( "headers" ) ]
2367+ }
2368+
2369+ // TODO: implement validator
2370+ override predicate nameAllowsNewline ( ) { any ( ) }
2371+
2372+ override predicate valueAllowsNewline ( ) { any ( ) }
2373+ }
2374+
2375+ /** A call to a method that writes to a response header. */
2376+ private class HeaderWriteCall extends Http:: Server:: ResponseHeaderWrite:: Range ,
2377+ DataFlow:: MethodCallNode
2378+ {
2379+ HeaderWriteCall ( ) {
2380+ this .calls ( instance ( ) , [ "add_header" , "set" , "setdefault" , "__setitem__" ] )
2381+ }
2382+
2383+ override DataFlow:: Node getNameArg ( ) { result = this .getArg ( 0 ) }
2384+
2385+ override DataFlow:: Node getValueArg ( ) { result = this .getArg ( 1 ) }
2386+
2387+ // TODO: implement validator
2388+ override predicate nameAllowsNewline ( ) { any ( ) }
2389+
2390+ override predicate valueAllowsNewline ( ) { any ( ) }
2391+ }
2392+
2393+ /** A dict-like write to a response header. */
2394+ private class HeaderWriteSubscript extends Http:: Server:: ResponseHeaderWrite:: Range ,
2395+ DataFlow:: Node
2396+ {
2397+ DataFlow:: Node name ;
2398+ DataFlow:: Node value ;
2399+
2400+ HeaderWriteSubscript ( ) {
2401+ exists ( SubscriptNode subscript |
2402+ this .asCfgNode ( ) = subscript and
2403+ value .asCfgNode ( ) = subscript .( DefinitionNode ) .getValue ( ) and
2404+ name .asCfgNode ( ) = subscript .getIndex ( ) and
2405+ subscript .getObject ( ) = instance ( ) .asCfgNode ( )
2406+ )
2407+ }
2408+
2409+ override DataFlow:: Node getNameArg ( ) { result = name }
2410+
2411+ override DataFlow:: Node getValueArg ( ) { result = value }
2412+
2413+ // TODO: implement validator
2414+ override predicate nameAllowsNewline ( ) { any ( ) }
2415+
2416+ override predicate valueAllowsNewline ( ) { any ( ) }
2417+ }
2418+ }
23082419 }
23092420
23102421 // ---------------------------------------------------------------------------
0 commit comments