@@ -651,7 +651,7 @@ private module Stdlib {
651
651
* WARNING: Only holds for a few predefined attributes.
652
652
*/
653
653
private DataFlow:: Node builtins_attr ( DataFlow:: TypeTracker t , string attr_name ) {
654
- attr_name in [ "exec" , "eval" , "compile" ] and
654
+ attr_name in [ "exec" , "eval" , "compile" , "open" ] and
655
655
(
656
656
t .start ( ) and
657
657
result = DataFlow:: importNode ( [ "builtins" , "__builtin__" ] + "." + attr_name )
@@ -728,165 +728,222 @@ private module Stdlib {
728
728
)
729
729
}
730
730
}
731
- }
732
731
733
- /**
734
- * An exec statement (only Python 2).
735
- * Se ehttps://docs.python.org/2/reference/simple_stmts.html#the-exec-statement.
736
- */
737
- private class ExecStatement extends CodeExecution:: Range {
738
- ExecStatement ( ) {
739
- // since there are no DataFlow::Nodes for a Statement, we can't do anything like
740
- // `this = any(Exec exec)`
741
- this .asExpr ( ) = any ( Exec exec ) .getBody ( )
742
- }
732
+ /**
733
+ * A call to the builtin `open` function.
734
+ * See https://docs.python.org/3/library/functions.html#open
735
+ */
736
+ private class OpenCall extends FileSystemAccess:: Range , DataFlow:: CfgNode {
737
+ override CallNode node ;
743
738
744
- override DataFlow:: Node getCode ( ) { result = this }
745
- }
739
+ OpenCall ( ) {
740
+ node .getFunction ( ) = builtins_attr ( "open" ) .asCfgNode ( )
741
+ or
742
+ node .getFunction ( ) = io_attr ( "open" ) .asCfgNode ( )
743
+ }
746
744
747
- /**
748
- * A call to the builtin `open` function.
749
- * See https://docs.python.org/3/library/functions.html#open
750
- */
751
- private class OpenCall extends FileSystemAccess:: Range , DataFlow:: CfgNode {
752
- override CallNode node ;
745
+ override DataFlow:: Node getAPathArgument ( ) {
746
+ result .asCfgNode ( ) in [ node .getArg ( 0 ) , node .getArgByName ( "file" ) ]
747
+ }
748
+ }
753
749
754
- OpenCall ( ) { node .getFunction ( ) .( NameNode ) .getId ( ) = "open" }
750
+ /**
751
+ * An exec statement (only Python 2).
752
+ * Se ehttps://docs.python.org/2/reference/simple_stmts.html#the-exec-statement.
753
+ */
754
+ private class ExecStatement extends CodeExecution:: Range {
755
+ ExecStatement ( ) {
756
+ // since there are no DataFlow::Nodes for a Statement, we can't do anything like
757
+ // `this = any(Exec exec)`
758
+ this .asExpr ( ) = any ( Exec exec ) .getBody ( )
759
+ }
755
760
756
- override DataFlow:: Node getAPathArgument ( ) {
757
- result .asCfgNode ( ) in [ node .getArg ( 0 ) , node .getArgByName ( "file" ) ]
761
+ override DataFlow:: Node getCode ( ) { result = this }
758
762
}
759
- }
760
763
761
- // ---------------------------------------------------------------------------
762
- // base64
763
- // ---------------------------------------------------------------------------
764
- /** Gets a reference to the `base64` module. */
765
- private DataFlow:: Node base64 ( DataFlow:: TypeTracker t ) {
766
- t .start ( ) and
767
- result = DataFlow:: importNode ( "base64" )
768
- or
769
- exists ( DataFlow:: TypeTracker t2 | result = base64 ( t2 ) .track ( t2 , t ) )
770
- }
764
+ // ---------------------------------------------------------------------------
765
+ // base64
766
+ // ---------------------------------------------------------------------------
767
+ /** Gets a reference to the `base64` module. */
768
+ private DataFlow:: Node base64 ( DataFlow:: TypeTracker t ) {
769
+ t .start ( ) and
770
+ result = DataFlow:: importNode ( "base64" )
771
+ or
772
+ exists ( DataFlow:: TypeTracker t2 | result = base64 ( t2 ) .track ( t2 , t ) )
773
+ }
771
774
772
- /** Gets a reference to the `base64` module. */
773
- DataFlow:: Node base64 ( ) { result = base64 ( DataFlow:: TypeTracker:: end ( ) ) }
775
+ /** Gets a reference to the `base64` module. */
776
+ DataFlow:: Node base64 ( ) { result = base64 ( DataFlow:: TypeTracker:: end ( ) ) }
774
777
775
- /**
776
- * Gets a reference to the attribute `attr_name` of the `base64` module.
777
- * WARNING: Only holds for a few predefined attributes.
778
- */
779
- private DataFlow:: Node base64_attr ( DataFlow:: TypeTracker t , string attr_name ) {
780
- attr_name in [
781
- "b64encode" , "b64decode" , "standard_b64encode" , "standard_b64decode" , "urlsafe_b64encode" ,
782
- "urlsafe_b64decode" , "b32encode" , "b32decode" , "b16encode" , "b16decode" , "encodestring" ,
783
- "decodestring" , "a85encode" , "a85decode" , "b85encode" , "b85decode" , "encodebytes" ,
784
- "decodebytes"
785
- ] and
786
- (
787
- t .start ( ) and
788
- result = DataFlow:: importNode ( "base64" + "." + attr_name )
778
+ /**
779
+ * Gets a reference to the attribute `attr_name` of the `base64` module.
780
+ * WARNING: Only holds for a few predefined attributes.
781
+ */
782
+ private DataFlow:: Node base64_attr ( DataFlow:: TypeTracker t , string attr_name ) {
783
+ attr_name in [
784
+ "b64encode" , "b64decode" , "standard_b64encode" , "standard_b64decode" , "urlsafe_b64encode" ,
785
+ "urlsafe_b64decode" , "b32encode" , "b32decode" , "b16encode" , "b16decode" , "encodestring" ,
786
+ "decodestring" , "a85encode" , "a85decode" , "b85encode" , "b85decode" , "encodebytes" ,
787
+ "decodebytes"
788
+ ] and
789
+ (
790
+ t .start ( ) and
791
+ result = DataFlow:: importNode ( "base64" + "." + attr_name )
792
+ or
793
+ t .startInAttr ( attr_name ) and
794
+ result = base64 ( )
795
+ )
789
796
or
790
- t .startInAttr ( attr_name ) and
791
- result = base64 ( )
792
- )
793
- or
794
- // Due to bad performance when using normal setup with `base64_attr(t2, attr_name).track(t2, t)`
795
- // we have inlined that code and forced a join
796
- exists ( DataFlow:: TypeTracker t2 |
797
- exists ( DataFlow:: StepSummary summary |
798
- base64_attr_first_join ( t2 , attr_name , result , summary ) and
799
- t = t2 .append ( summary )
797
+ // Due to bad performance when using normal setup with `base64_attr(t2, attr_name).track(t2, t)`
798
+ // we have inlined that code and forced a join
799
+ exists ( DataFlow:: TypeTracker t2 |
800
+ exists ( DataFlow:: StepSummary summary |
801
+ base64_attr_first_join ( t2 , attr_name , result , summary ) and
802
+ t = t2 .append ( summary )
803
+ )
800
804
)
801
- )
802
- }
803
-
804
- pragma [ nomagic]
805
- private predicate base64_attr_first_join (
806
- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res , DataFlow:: StepSummary summary
807
- ) {
808
- DataFlow:: StepSummary:: step ( base64_attr ( t2 , attr_name ) , res , summary )
809
- }
805
+ }
810
806
811
- /**
812
- * Gets a reference to the attribute `attr_name` of the `base64` module.
813
- * WARNING: Only holds for a few predefined attributes.
814
- */
815
- private DataFlow:: Node base64_attr ( string attr_name ) {
816
- result = base64_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
817
- }
807
+ pragma [ nomagic]
808
+ private predicate base64_attr_first_join (
809
+ DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res , DataFlow:: StepSummary summary
810
+ ) {
811
+ DataFlow:: StepSummary:: step ( base64_attr ( t2 , attr_name ) , res , summary )
812
+ }
818
813
819
- /** A call to any of the encode functions in the `base64` module. */
820
- private class Base64EncodeCall extends Encoding:: Range , DataFlow:: CfgNode {
821
- override CallNode node ;
822
-
823
- Base64EncodeCall ( ) {
824
- exists ( string name |
825
- name in [
826
- "b64encode" , "standard_b64encode" , "urlsafe_b64encode" , "b32encode" , "b16encode" ,
827
- "encodestring" , "a85encode" , "b85encode" , "encodebytes"
828
- ] and
829
- node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( )
830
- )
814
+ /**
815
+ * Gets a reference to the attribute `attr_name` of the `base64` module.
816
+ * WARNING: Only holds for a few predefined attributes.
817
+ */
818
+ private DataFlow:: Node base64_attr ( string attr_name ) {
819
+ result = base64_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
831
820
}
832
821
833
- override DataFlow:: Node getAnInput ( ) { result .asCfgNode ( ) = node .getArg ( 0 ) }
822
+ /** A call to any of the encode functions in the `base64` module. */
823
+ private class Base64EncodeCall extends Encoding:: Range , DataFlow:: CfgNode {
824
+ override CallNode node ;
834
825
835
- override DataFlow:: Node getOutput ( ) { result = this }
826
+ Base64EncodeCall ( ) {
827
+ exists ( string name |
828
+ name in [
829
+ "b64encode" , "standard_b64encode" , "urlsafe_b64encode" , "b32encode" , "b16encode" ,
830
+ "encodestring" , "a85encode" , "b85encode" , "encodebytes"
831
+ ] and
832
+ node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( )
833
+ )
834
+ }
836
835
837
- override string getFormat ( ) {
838
- exists ( string name | node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( ) |
839
- name in [
840
- "b64encode" , "standard_b64encode" , "urlsafe_b64encode" , "encodestring" , "encodebytes"
841
- ] and
842
- result = "Base64"
843
- or
844
- name = "b32encode" and result = "Base32"
845
- or
846
- name = "b16encode" and result = "Base16"
847
- or
848
- name = "a85encode" and result = "Ascii85"
849
- or
850
- name = "b85encode" and result = "Base85"
851
- )
852
- }
853
- }
836
+ override DataFlow:: Node getAnInput ( ) { result .asCfgNode ( ) = node .getArg ( 0 ) }
854
837
855
- /** A call to any of the decode functions in the `base64` module. */
856
- private class Base64DecodeCall extends Decoding:: Range , DataFlow:: CfgNode {
857
- override CallNode node ;
858
-
859
- Base64DecodeCall ( ) {
860
- exists ( string name |
861
- name in [
862
- "b64decode" , "standard_b64decode" , "urlsafe_b64decode" , "b32decode" , "b16decode" ,
863
- "decodestring" , "a85decode" , "b85decode" , "decodebytes"
864
- ] and
865
- node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( )
866
- )
838
+ override DataFlow:: Node getOutput ( ) { result = this }
839
+
840
+ override string getFormat ( ) {
841
+ exists ( string name | node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( ) |
842
+ name in [
843
+ "b64encode" , "standard_b64encode" , "urlsafe_b64encode" , "encodestring" , "encodebytes"
844
+ ] and
845
+ result = "Base64"
846
+ or
847
+ name = "b32encode" and result = "Base32"
848
+ or
849
+ name = "b16encode" and result = "Base16"
850
+ or
851
+ name = "a85encode" and result = "Ascii85"
852
+ or
853
+ name = "b85encode" and result = "Base85"
854
+ )
855
+ }
867
856
}
868
857
869
- override predicate mayExecuteInput ( ) { none ( ) }
858
+ /** A call to any of the decode functions in the `base64` module. */
859
+ private class Base64DecodeCall extends Decoding:: Range , DataFlow:: CfgNode {
860
+ override CallNode node ;
861
+
862
+ Base64DecodeCall ( ) {
863
+ exists ( string name |
864
+ name in [
865
+ "b64decode" , "standard_b64decode" , "urlsafe_b64decode" , "b32decode" , "b16decode" ,
866
+ "decodestring" , "a85decode" , "b85decode" , "decodebytes"
867
+ ] and
868
+ node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( )
869
+ )
870
+ }
870
871
871
- override DataFlow :: Node getAnInput ( ) { result . asCfgNode ( ) = node . getArg ( 0 ) }
872
+ override predicate mayExecuteInput ( ) { none ( ) }
872
873
873
- override DataFlow:: Node getOutput ( ) { result = this }
874
+ override DataFlow:: Node getAnInput ( ) { result . asCfgNode ( ) = node . getArg ( 0 ) }
874
875
875
- override string getFormat ( ) {
876
- exists ( string name | node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( ) |
877
- name in [
878
- "b64decode" , "standard_b64decode" , "urlsafe_b64decode" , "decodestring" , "decodebytes"
879
- ] and
880
- result = "Base64"
881
- or
882
- name = "b32decode" and result = "Base32"
883
- or
884
- name = "b16decode" and result = "Base16"
885
- or
886
- name = "a85decode" and result = "Ascii85"
876
+ override DataFlow:: Node getOutput ( ) { result = this }
877
+
878
+ override string getFormat ( ) {
879
+ exists ( string name | node .getFunction ( ) = base64_attr ( name ) .asCfgNode ( ) |
880
+ name in [
881
+ "b64decode" , "standard_b64decode" , "urlsafe_b64decode" , "decodestring" , "decodebytes"
882
+ ] and
883
+ result = "Base64"
884
+ or
885
+ name = "b32decode" and result = "Base32"
886
+ or
887
+ name = "b16decode" and result = "Base16"
888
+ or
889
+ name = "a85decode" and result = "Ascii85"
890
+ or
891
+ name = "b85decode" and result = "Base85"
892
+ )
893
+ }
894
+ }
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 )
887
919
or
888
- name = "b85decode" and result = "Base85"
920
+ t .startInAttr ( attr_name ) and
921
+ result = io ( )
889
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 )
890
947
}
891
948
}
892
949
0 commit comments