@@ -825,6 +825,19 @@ impl Violation for SuspiciousFTPLibUsage {
825
825
826
826
/// S301, S302, S303, S304, S305, S306, S307, S308, S310, S311, S312, S313, S314, S315, S316, S317, S318, S319, S320, S321, S323
827
827
pub ( crate ) fn suspicious_function_call ( checker : & mut Checker , call : & ExprCall ) {
828
+ /// Returns `true` if the iterator starts with the given prefix.
829
+ fn has_prefix ( mut chars : impl Iterator < Item = char > , prefix : & str ) -> bool {
830
+ for expected in prefix. chars ( ) {
831
+ let Some ( actual) = chars. next ( ) else {
832
+ return false ;
833
+ } ;
834
+ if actual != expected {
835
+ return false ;
836
+ }
837
+ }
838
+ true
839
+ }
840
+
828
841
let Some ( diagnostic_kind) = checker. semantic ( ) . resolve_qualified_name ( call. func . as_ref ( ) ) . and_then ( |qualified_name| {
829
842
match qualified_name. segments ( ) {
830
843
// Pickle
@@ -857,16 +870,14 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) {
857
870
match call. arguments . find_argument ( "url" , 0 ) {
858
871
// If the `url` argument is a string literal, allow `http` and `https` schemes.
859
872
Some ( Expr :: StringLiteral ( ast:: ExprStringLiteral { value, .. } ) ) => {
860
- let url = value. to_str ( ) . trim_start ( ) ;
861
- if url. starts_with ( "http://" ) || url. starts_with ( "https://" ) {
873
+ if has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "http://" ) || has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "https://" ) {
862
874
return None ;
863
875
}
864
876
} ,
865
877
// If the `url` argument is an f-string literal, allow `http` and `https` schemes.
866
878
Some ( Expr :: FString ( ast:: ExprFString { value, .. } ) ) => {
867
879
if let Some ( ast:: FStringElement :: Literal ( ast:: FStringLiteralElement { value, .. } ) ) = value. elements ( ) . next ( ) {
868
- let url = value. trim_start ( ) ;
869
- if url. starts_with ( "http://" ) || url. starts_with ( "https://" ) {
880
+ if has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "http://" ) || has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "https://" ) {
870
881
return None ;
871
882
}
872
883
}
@@ -883,17 +894,15 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) {
883
894
match call. arguments . find_argument ( "url" , 0 ) {
884
895
// If the `url` argument is a string literal, allow `http` and `https` schemes.
885
896
Some ( Expr :: StringLiteral ( ast:: ExprStringLiteral { value, .. } ) ) => {
886
- let url = value. to_str ( ) . trim_start ( ) ;
887
- if url. starts_with ( "http://" ) || url. starts_with ( "https://" ) {
897
+ if has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "http://" ) || has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "https://" ) {
888
898
return None ;
889
899
}
890
900
} ,
891
901
892
902
// If the `url` argument is an f-string literal, allow `http` and `https` schemes.
893
903
Some ( Expr :: FString ( ast:: ExprFString { value, .. } ) ) => {
894
904
if let Some ( ast:: FStringElement :: Literal ( ast:: FStringLiteralElement { value, .. } ) ) = value. elements ( ) . next ( ) {
895
- let url = value. trim_start ( ) ;
896
- if url. starts_with ( "http://" ) || url. starts_with ( "https://" ) {
905
+ if has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "http://" ) || has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "https://" ) {
897
906
return None ;
898
907
}
899
908
}
@@ -905,17 +914,15 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) {
905
914
match arguments. find_argument ( "url" , 0 ) {
906
915
// If the `url` argument is a string literal, allow `http` and `https` schemes.
907
916
Some ( Expr :: StringLiteral ( ast:: ExprStringLiteral { value, .. } ) ) => {
908
- let url = value. to_str ( ) . trim_start ( ) ;
909
- if url. starts_with ( "http://" ) || url. starts_with ( "https://" ) {
917
+ if has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "http://" ) || has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "https://" ) {
910
918
return None ;
911
919
}
912
920
} ,
913
921
914
922
// If the `url` argument is an f-string literal, allow `http` and `https` schemes.
915
923
Some ( Expr :: FString ( ast:: ExprFString { value, .. } ) ) => {
916
924
if let Some ( ast:: FStringElement :: Literal ( ast:: FStringLiteralElement { value, .. } ) ) = value. elements ( ) . next ( ) {
917
- let url = value. trim_start ( ) ;
918
- if url. starts_with ( "http://" ) || url. starts_with ( "https://" ) {
925
+ if has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "http://" ) || has_prefix ( value. chars ( ) . skip_while ( |c| c. is_whitespace ( ) ) , "https://" ) {
919
926
return None ;
920
927
}
921
928
}
0 commit comments