@@ -736,7 +736,11 @@ private module Stdlib {
736736 private class OpenCall extends FileSystemAccess:: Range , DataFlow:: CfgNode {
737737 override CallNode node ;
738738
739- OpenCall ( ) { node .getFunction ( ) = builtins_attr ( "open" ) .asCfgNode ( ) }
739+ OpenCall ( ) {
740+ node .getFunction ( ) = builtins_attr ( "open" ) .asCfgNode ( )
741+ or
742+ node .getFunction ( ) = io_attr ( "open" ) .asCfgNode ( )
743+ }
740744
741745 override DataFlow:: Node getAPathArgument ( ) {
742746 result .asCfgNode ( ) in [ node .getArg ( 0 ) , node .getArgByName ( "file" ) ]
@@ -888,6 +892,59 @@ private module Stdlib {
888892 )
889893 }
890894 }
895+
896+ // ---------------------------------------------------------------------------
897+ // io
898+ // ---------------------------------------------------------------------------
899+ /** Gets a reference to the `io` module. */
900+ private DataFlow:: Node io ( DataFlow:: TypeTracker t ) {
901+ t .start ( ) and
902+ result = DataFlow:: importNode ( "io" )
903+ or
904+ exists ( DataFlow:: TypeTracker t2 | result = io ( t2 ) .track ( t2 , t ) )
905+ }
906+
907+ /** Gets a reference to the `io` module. */
908+ DataFlow:: Node io ( ) { result = io ( DataFlow:: TypeTracker:: end ( ) ) }
909+
910+ /**
911+ * Gets a reference to the attribute `attr_name` of the `io` module.
912+ * WARNING: Only holds for a few predefined attributes.
913+ */
914+ private DataFlow:: Node io_attr ( DataFlow:: TypeTracker t , string attr_name ) {
915+ attr_name in [ "open" ] and
916+ (
917+ t .start ( ) and
918+ result = DataFlow:: importNode ( "io" + "." + attr_name )
919+ or
920+ t .startInAttr ( attr_name ) and
921+ result = io ( )
922+ )
923+ or
924+ // Due to bad performance when using normal setup with `io_attr(t2, attr_name).track(t2, t)`
925+ // we have inlined that code and forced a join
926+ exists ( DataFlow:: TypeTracker t2 |
927+ exists ( DataFlow:: StepSummary summary |
928+ io_attr_first_join ( t2 , attr_name , result , summary ) and
929+ t = t2 .append ( summary )
930+ )
931+ )
932+ }
933+
934+ pragma [ nomagic]
935+ private predicate io_attr_first_join (
936+ DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res , DataFlow:: StepSummary summary
937+ ) {
938+ DataFlow:: StepSummary:: step ( io_attr ( t2 , attr_name ) , res , summary )
939+ }
940+
941+ /**
942+ * Gets a reference to the attribute `attr_name` of the `io` module.
943+ * WARNING: Only holds for a few predefined attributes.
944+ */
945+ private DataFlow:: Node io_attr ( string attr_name ) {
946+ result = io_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
947+ }
891948}
892949
893950// ---------------------------------------------------------------------------
0 commit comments