@@ -910,6 +910,26 @@ private module Stdlib {
910
910
*/
911
911
private string pathlibPathMethodExport ( ) { result in [ "as_posix" , "as_uri" ] }
912
912
913
+ /**
914
+ * Flow for type presering mehtods.
915
+ */
916
+ private predicate typePreservingCall ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
917
+ exists ( DataFlow:: AttrRead returnsPath | returnsPath .getAttributeName ( ) = pathlibPathMethod ( ) |
918
+ nodeTo .( DataFlow:: CallCfgNode ) .getFunction ( ) = returnsPath and
919
+ nodeFrom = returnsPath .getObject ( )
920
+ )
921
+ }
922
+
923
+ /**
924
+ * Flow for type presering attributes.
925
+ */
926
+ private predicate typePreservingAttribute ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
927
+ exists ( DataFlow:: AttrRead isPath | isPath .getAttributeName ( ) = pathlibPathAttribute ( ) |
928
+ nodeTo = isPath and
929
+ nodeFrom = isPath .getObject ( )
930
+ )
931
+ }
932
+
913
933
/**
914
934
* Gets a reference to a `pathlib.Path` object.
915
935
* This type tracker makes the monomorphic API use assumption.
@@ -920,26 +940,25 @@ private module Stdlib {
920
940
result = pathlib ( ) .getMember ( pathlibPathConstructor ( ) ) .getACall ( )
921
941
or
922
942
// Type-preserving call
923
- exists ( DataFlow:: AttrRead returnsPath , DataFlow:: TypeTracker t2 |
924
- returnsPath .getAttributeName ( ) = pathlibPathMethod ( ) and
925
- returnsPath .getObject ( ) .getALocalSource ( ) = pathlibPath ( t2 ) and
943
+ exists ( DataFlow:: Node nodeFrom , DataFlow:: TypeTracker t2 |
944
+ nodeFrom .getALocalSource ( ) = pathlibPath ( t2 ) and
926
945
t2 .end ( )
927
946
|
928
947
t .start ( ) and
929
- result . ( DataFlow :: CallCfgNode ) . getFunction ( ) = returnsPath
948
+ typePreservingCall ( nodeFrom , result )
930
949
)
931
950
or
932
951
// Type-preserving attribute
933
- exists ( DataFlow:: AttrRead isPath , DataFlow:: TypeTracker t2 |
934
- isPath .getAttributeName ( ) = pathlibPathAttribute ( ) and
935
- isPath .getObject ( ) .getALocalSource ( ) = pathlibPath ( t2 ) and
952
+ exists ( DataFlow:: Node nodeFrom , DataFlow:: TypeTracker t2 |
953
+ nodeFrom .getALocalSource ( ) = pathlibPath ( t2 ) and
936
954
t2 .end ( )
937
955
|
938
956
t .start ( ) and
939
- result = isPath
957
+ typePreservingAttribute ( nodeFrom , result )
940
958
)
941
959
or
942
960
// Data injection
961
+ // Special handling of the `/` operator
943
962
exists ( BinaryExprNode slash , DataFlow:: Node pathOperand , DataFlow:: TypeTracker t2 |
944
963
slash .getOp ( ) instanceof Div and
945
964
pathOperand .asCfgNode ( ) = slash .getAnOperand ( ) and
@@ -950,6 +969,7 @@ private module Stdlib {
950
969
result .asCfgNode ( ) = slash
951
970
)
952
971
or
972
+ // standard case
953
973
exists ( DataFlow:: AttrRead returnsPath , DataFlow:: TypeTracker t2 |
954
974
returnsPath .getAttributeName ( ) = pathlibPathInjection ( ) and
955
975
returnsPath .getObject ( ) .getALocalSource ( ) = pathlibPath ( t2 ) and
@@ -996,18 +1016,10 @@ private module Stdlib {
996
1016
nodeTo .getALocalSource ( ) = pathlibPath ( ) and
997
1017
(
998
1018
// Type-preserving call
999
- exists ( DataFlow:: AttrRead returnsPath |
1000
- returnsPath .getAttributeName ( ) = pathlibPathMethod ( )
1001
- |
1002
- nodeTo .( DataFlow:: CallCfgNode ) .getFunction ( ) = returnsPath and
1003
- nodeFrom = returnsPath .getObject ( )
1004
- )
1019
+ typePreservingCall ( nodeFrom , nodeTo )
1005
1020
or
1006
1021
// Type-preserving attribute
1007
- exists ( DataFlow:: AttrRead isPath | isPath .getAttributeName ( ) = pathlibPathAttribute ( ) |
1008
- nodeTo = isPath and
1009
- nodeFrom = isPath .getObject ( )
1010
- )
1022
+ typePreservingAttribute ( nodeFrom , nodeTo )
1011
1023
)
1012
1024
or
1013
1025
// Data injection
0 commit comments