@@ -413,4 +413,73 @@ private module Stdlib {
413413 result .asCfgNode ( ) = this .asCfgNode ( ) .( CallNode ) .getArgByName ( "cmd" )
414414 }
415415 }
416+
417+ // ---------------------------------------------------------------------------
418+ // platform
419+ // ---------------------------------------------------------------------------
420+ /** Gets a reference to the `platform` module. */
421+ private DataFlow:: Node platform ( DataFlow:: TypeTracker t ) {
422+ t .start ( ) and
423+ result = DataFlow:: importModule ( "platform" )
424+ or
425+ exists ( DataFlow:: TypeTracker t2 | result = platform ( t2 ) .track ( t2 , t ) )
426+ }
427+
428+ /** Gets a reference to the `platform` module. */
429+ DataFlow:: Node platform ( ) { result = platform ( DataFlow:: TypeTracker:: end ( ) ) }
430+
431+ /**
432+ * Gets a reference to the attribute `attr_name` of the `platform` module.
433+ * WARNING: Only holds for a few predefined attributes.
434+ */
435+ private DataFlow:: Node platform_attr ( DataFlow:: TypeTracker t , string attr_name ) {
436+ attr_name in [ "popen" ] and
437+ (
438+ t .start ( ) and
439+ result = DataFlow:: importMember ( "platform" , attr_name )
440+ or
441+ t .startInAttr ( attr_name ) and
442+ result = DataFlow:: importModule ( "platform" )
443+ )
444+ or
445+ // Due to bad performance when using normal setup with `platform_attr(t2, attr_name).track(t2, t)`
446+ // we have inlined that code and forced a join
447+ exists ( DataFlow:: TypeTracker t2 |
448+ exists ( DataFlow:: StepSummary summary |
449+ platform_attr_first_join ( t2 , attr_name , result , summary ) and
450+ t = t2 .append ( summary )
451+ )
452+ )
453+ }
454+
455+ pragma [ nomagic]
456+ private predicate platform_attr_first_join (
457+ DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res , DataFlow:: StepSummary summary
458+ ) {
459+ DataFlow:: StepSummary:: step ( platform_attr ( t2 , attr_name ) , res , summary )
460+ }
461+
462+ /**
463+ * Gets a reference to the attribute `attr_name` of the `platform` module.
464+ * WARNING: Only holds for a few predefined attributes.
465+ */
466+ private DataFlow:: Node platform_attr ( string attr_name ) {
467+ result = platform_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
468+ }
469+
470+ /**
471+ * A call to the `platform.popen` function.
472+ * See https://docs.python.org/2.7/library/platform.html#platform.popen
473+ */
474+ private class PlatformPopenCall extends SystemCommandExecution:: Range {
475+ PlatformPopenCall ( ) {
476+ this .asCfgNode ( ) .( CallNode ) .getFunction ( ) = platform_attr ( "popen" ) .asCfgNode ( )
477+ }
478+
479+ override DataFlow:: Node getCommand ( ) {
480+ result .asCfgNode ( ) = this .asCfgNode ( ) .( CallNode ) .getArg ( 0 )
481+ or
482+ result .asCfgNode ( ) = this .asCfgNode ( ) .( CallNode ) .getArgByName ( "cmd" )
483+ }
484+ }
416485}
0 commit comments