mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
[flake8-bandit
] Support explicit string concatenations in S310 HTTP detection (#12315)
Closes https://github.com/astral-sh/ruff/issues/12314.
This commit is contained in:
parent
7a7c601d5e
commit
18c364d5df
4 changed files with 225 additions and 200 deletions
|
@ -2,6 +2,7 @@ import urllib.request
|
||||||
|
|
||||||
urllib.request.urlopen(url='http://www.google.com')
|
urllib.request.urlopen(url='http://www.google.com')
|
||||||
urllib.request.urlopen(url=f'http://www.google.com')
|
urllib.request.urlopen(url=f'http://www.google.com')
|
||||||
|
urllib.request.urlopen(url='http://' + 'www' + '.google.com')
|
||||||
urllib.request.urlopen(url='http://www.google.com', **kwargs)
|
urllib.request.urlopen(url='http://www.google.com', **kwargs)
|
||||||
urllib.request.urlopen(url=f'http://www.google.com', **kwargs)
|
urllib.request.urlopen(url=f'http://www.google.com', **kwargs)
|
||||||
urllib.request.urlopen('http://www.google.com')
|
urllib.request.urlopen('http://www.google.com')
|
||||||
|
@ -11,6 +12,7 @@ urllib.request.urlopen(url)
|
||||||
|
|
||||||
urllib.request.Request(url='http://www.google.com')
|
urllib.request.Request(url='http://www.google.com')
|
||||||
urllib.request.Request(url=f'http://www.google.com')
|
urllib.request.Request(url=f'http://www.google.com')
|
||||||
|
urllib.request.Request(url='http://' + 'www' + '.google.com')
|
||||||
urllib.request.Request(url='http://www.google.com', **kwargs)
|
urllib.request.Request(url='http://www.google.com', **kwargs)
|
||||||
urllib.request.Request(url=f'http://www.google.com', **kwargs)
|
urllib.request.Request(url=f'http://www.google.com', **kwargs)
|
||||||
urllib.request.Request('http://www.google.com')
|
urllib.request.Request('http://www.google.com')
|
||||||
|
@ -20,15 +22,18 @@ urllib.request.Request(url)
|
||||||
|
|
||||||
urllib.request.URLopener().open(fullurl='http://www.google.com')
|
urllib.request.URLopener().open(fullurl='http://www.google.com')
|
||||||
urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
||||||
|
urllib.request.URLopener().open(fullurl='http://' + 'www' + '.google.com')
|
||||||
urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
||||||
urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
||||||
urllib.request.URLopener().open('http://www.google.com')
|
urllib.request.URLopener().open('http://www.google.com')
|
||||||
urllib.request.URLopener().open(f'http://www.google.com')
|
urllib.request.URLopener().open(f'http://www.google.com')
|
||||||
|
urllib.request.URLopener().open('http://' + 'www' + '.google.com')
|
||||||
urllib.request.URLopener().open('file:///foo/bar/baz')
|
urllib.request.URLopener().open('file:///foo/bar/baz')
|
||||||
urllib.request.URLopener().open(url)
|
urllib.request.URLopener().open(url)
|
||||||
|
|
||||||
urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'))
|
urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'))
|
||||||
urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'))
|
urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'))
|
||||||
|
urllib.request.urlopen(url=urllib.request.Request('http://' + 'www' + '.google.com'))
|
||||||
urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'), **kwargs)
|
urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'), **kwargs)
|
||||||
urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'), **kwargs)
|
urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'), **kwargs)
|
||||||
urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! Check for calls to suspicious functions, or calls into suspicious modules.
|
//! Check for calls to suspicious functions, or calls into suspicious modules.
|
||||||
//!
|
//!
|
||||||
//! See: <https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html>
|
//! See: <https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html>
|
||||||
|
use itertools::Either;
|
||||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation};
|
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::{self as ast, Decorator, Expr, ExprCall};
|
use ruff_python_ast::{self as ast, Decorator, Expr, ExprCall, Operator};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
@ -838,6 +839,43 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the iterator starts with an HTTP or HTTPS prefix.
|
||||||
|
fn has_http_prefix(chars: impl Iterator<Item = char> + Clone) -> bool {
|
||||||
|
has_prefix(chars.clone().skip_while(|c| c.is_whitespace()), "http://")
|
||||||
|
|| has_prefix(chars.skip_while(|c| c.is_whitespace()), "https://")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the leading characters for an expression, if it's a string literal, f-string, or
|
||||||
|
/// string concatenation.
|
||||||
|
fn leading_chars(expr: &Expr) -> Option<impl Iterator<Item = char> + Clone + '_> {
|
||||||
|
match expr {
|
||||||
|
// Ex) `"foo"`
|
||||||
|
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => {
|
||||||
|
Some(Either::Left(value.chars()))
|
||||||
|
}
|
||||||
|
// Ex) f"foo"
|
||||||
|
Expr::FString(ast::ExprFString { value, .. }) => {
|
||||||
|
value.elements().next().and_then(|element| {
|
||||||
|
if let ast::FStringElement::Literal(ast::FStringLiteralElement {
|
||||||
|
value, ..
|
||||||
|
}) = element
|
||||||
|
{
|
||||||
|
Some(Either::Right(value.chars()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Ex) "foo" + "bar"
|
||||||
|
Expr::BinOp(ast::ExprBinOp {
|
||||||
|
op: Operator::Add,
|
||||||
|
left,
|
||||||
|
..
|
||||||
|
}) => leading_chars(left),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let Some(diagnostic_kind) = checker.semantic().resolve_qualified_name(call.func.as_ref()).and_then(|qualified_name| {
|
let Some(diagnostic_kind) = checker.semantic().resolve_qualified_name(call.func.as_ref()).and_then(|qualified_name| {
|
||||||
match qualified_name.segments() {
|
match qualified_name.segments() {
|
||||||
// Pickle
|
// Pickle
|
||||||
|
@ -864,26 +902,12 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) {
|
||||||
["django", "utils", "safestring" | "html", "mark_safe"] => Some(SuspiciousMarkSafeUsage.into()),
|
["django", "utils", "safestring" | "html", "mark_safe"] => Some(SuspiciousMarkSafeUsage.into()),
|
||||||
// URLOpen (`Request`)
|
// URLOpen (`Request`)
|
||||||
["urllib", "request", "Request"] |
|
["urllib", "request", "Request"] |
|
||||||
["six", "moves", "urllib", "request","Request"] => {
|
["six", "moves", "urllib", "request", "Request"] => {
|
||||||
// If the `url` argument is a string literal or an f string, allow `http` and `https` schemes.
|
// If the `url` argument is a string literal or an f-string, allow `http` and `https` schemes.
|
||||||
if call.arguments.args.iter().all(|arg| !arg.is_starred_expr()) && call.arguments.keywords.iter().all(|keyword| keyword.arg.is_some()) {
|
if call.arguments.args.iter().all(|arg| !arg.is_starred_expr()) && call.arguments.keywords.iter().all(|keyword| keyword.arg.is_some()) {
|
||||||
match call.arguments.find_argument("url", 0) {
|
if call.arguments.find_argument("url", 0).and_then(leading_chars).is_some_and(has_http_prefix) {
|
||||||
// If the `url` argument is a string literal, allow `http` and `https` schemes.
|
|
||||||
Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) => {
|
|
||||||
if has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "http://") || has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "https://") {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// If the `url` argument is an f-string literal, allow `http` and `https` schemes.
|
|
||||||
Some(Expr::FString(ast::ExprFString { value, .. })) => {
|
|
||||||
if let Some(ast::FStringElement::Literal(ast::FStringLiteralElement { value, .. })) = value.elements().next() {
|
|
||||||
if has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "http://") || has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "https://") {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(SuspiciousURLOpenUsage.into())
|
Some(SuspiciousURLOpenUsage.into())
|
||||||
}
|
}
|
||||||
|
@ -892,44 +916,20 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) {
|
||||||
["six", "moves", "urllib", "request", "urlopen" | "urlretrieve" ] => {
|
["six", "moves", "urllib", "request", "urlopen" | "urlretrieve" ] => {
|
||||||
if call.arguments.args.iter().all(|arg| !arg.is_starred_expr()) && call.arguments.keywords.iter().all(|keyword| keyword.arg.is_some()) {
|
if call.arguments.args.iter().all(|arg| !arg.is_starred_expr()) && call.arguments.keywords.iter().all(|keyword| keyword.arg.is_some()) {
|
||||||
match call.arguments.find_argument("url", 0) {
|
match call.arguments.find_argument("url", 0) {
|
||||||
// If the `url` argument is a string literal, allow `http` and `https` schemes.
|
|
||||||
Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) => {
|
|
||||||
if has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "http://") || has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "https://") {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// If the `url` argument is an f-string literal, allow `http` and `https` schemes.
|
|
||||||
Some(Expr::FString(ast::ExprFString { value, .. })) => {
|
|
||||||
if let Some(ast::FStringElement::Literal(ast::FStringLiteralElement { value, .. })) = value.elements().next() {
|
|
||||||
if has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "http://") || has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "https://") {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// If the `url` argument is a `urllib.request.Request` object, allow `http` and `https` schemes.
|
// If the `url` argument is a `urllib.request.Request` object, allow `http` and `https` schemes.
|
||||||
Some(Expr::Call(ExprCall { func, arguments, .. })) => {
|
Some(Expr::Call(ExprCall { func, arguments, .. })) => {
|
||||||
if checker.semantic().resolve_qualified_name(func.as_ref()).is_some_and(|name| name.segments() == ["urllib", "request", "Request"]) {
|
if checker.semantic().resolve_qualified_name(func.as_ref()).is_some_and(|name| name.segments() == ["urllib", "request", "Request"]) {
|
||||||
match arguments.find_argument("url", 0) {
|
if arguments.find_argument("url", 0).and_then(leading_chars).is_some_and(has_http_prefix) {
|
||||||
// If the `url` argument is a string literal, allow `http` and `https` schemes.
|
|
||||||
Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) => {
|
|
||||||
if has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "http://") || has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "https://") {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// If the `url` argument is an f-string literal, allow `http` and `https` schemes.
|
// If the `url` argument is a string literal, allow `http` and `https` schemes.
|
||||||
Some(Expr::FString(ast::ExprFString { value, .. })) => {
|
Some(expr) => {
|
||||||
if let Some(ast::FStringElement::Literal(ast::FStringLiteralElement { value, .. })) = value.elements().next() {
|
if leading_chars(expr).is_some_and(has_http_prefix) {
|
||||||
if has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "http://") || has_prefix(value.chars().skip_while(|c| c.is_whitespace()), "https://") {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -1,212 +1,232 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
|
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
|
||||||
---
|
---
|
||||||
S310.py:5:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
3 | urllib.request.urlopen(url='http://www.google.com')
|
|
||||||
4 | urllib.request.urlopen(url=f'http://www.google.com')
|
|
||||||
5 | urllib.request.urlopen(url='http://www.google.com', **kwargs)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
6 | urllib.request.urlopen(url=f'http://www.google.com', **kwargs)
|
|
||||||
7 | urllib.request.urlopen('http://www.google.com')
|
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:6:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:6:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
4 | urllib.request.urlopen(url=f'http://www.google.com')
|
4 | urllib.request.urlopen(url=f'http://www.google.com')
|
||||||
5 | urllib.request.urlopen(url='http://www.google.com', **kwargs)
|
5 | urllib.request.urlopen(url='http://' + 'www' + '.google.com')
|
||||||
6 | urllib.request.urlopen(url=f'http://www.google.com', **kwargs)
|
6 | urllib.request.urlopen(url='http://www.google.com', **kwargs)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
7 | urllib.request.urlopen('http://www.google.com')
|
7 | urllib.request.urlopen(url=f'http://www.google.com', **kwargs)
|
||||||
8 | urllib.request.urlopen(f'http://www.google.com')
|
8 | urllib.request.urlopen('http://www.google.com')
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:9:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:7:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
7 | urllib.request.urlopen('http://www.google.com')
|
5 | urllib.request.urlopen(url='http://' + 'www' + '.google.com')
|
||||||
8 | urllib.request.urlopen(f'http://www.google.com')
|
6 | urllib.request.urlopen(url='http://www.google.com', **kwargs)
|
||||||
9 | urllib.request.urlopen('file:///foo/bar/baz')
|
7 | urllib.request.urlopen(url=f'http://www.google.com', **kwargs)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
10 | urllib.request.urlopen(url)
|
8 | urllib.request.urlopen('http://www.google.com')
|
||||||
|
9 | urllib.request.urlopen(f'http://www.google.com')
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:10:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:10:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
8 | urllib.request.urlopen(f'http://www.google.com')
|
8 | urllib.request.urlopen('http://www.google.com')
|
||||||
9 | urllib.request.urlopen('file:///foo/bar/baz')
|
9 | urllib.request.urlopen(f'http://www.google.com')
|
||||||
10 | urllib.request.urlopen(url)
|
10 | urllib.request.urlopen('file:///foo/bar/baz')
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
11 |
|
|
||||||
12 | urllib.request.Request(url='http://www.google.com')
|
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:14:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
12 | urllib.request.Request(url='http://www.google.com')
|
|
||||||
13 | urllib.request.Request(url=f'http://www.google.com')
|
|
||||||
14 | urllib.request.Request(url='http://www.google.com', **kwargs)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
15 | urllib.request.Request(url=f'http://www.google.com', **kwargs)
|
|
||||||
16 | urllib.request.Request('http://www.google.com')
|
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:15:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
13 | urllib.request.Request(url=f'http://www.google.com')
|
|
||||||
14 | urllib.request.Request(url='http://www.google.com', **kwargs)
|
|
||||||
15 | urllib.request.Request(url=f'http://www.google.com', **kwargs)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
16 | urllib.request.Request('http://www.google.com')
|
|
||||||
17 | urllib.request.Request(f'http://www.google.com')
|
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:18:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
16 | urllib.request.Request('http://www.google.com')
|
|
||||||
17 | urllib.request.Request(f'http://www.google.com')
|
|
||||||
18 | urllib.request.Request('file:///foo/bar/baz')
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
19 | urllib.request.Request(url)
|
11 | urllib.request.urlopen(url)
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:19:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:11:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
17 | urllib.request.Request(f'http://www.google.com')
|
9 | urllib.request.urlopen(f'http://www.google.com')
|
||||||
18 | urllib.request.Request('file:///foo/bar/baz')
|
10 | urllib.request.urlopen('file:///foo/bar/baz')
|
||||||
19 | urllib.request.Request(url)
|
11 | urllib.request.urlopen(url)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
20 |
|
12 |
|
||||||
21 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
13 | urllib.request.Request(url='http://www.google.com')
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:16:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
14 | urllib.request.Request(url=f'http://www.google.com')
|
||||||
|
15 | urllib.request.Request(url='http://' + 'www' + '.google.com')
|
||||||
|
16 | urllib.request.Request(url='http://www.google.com', **kwargs)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
17 | urllib.request.Request(url=f'http://www.google.com', **kwargs)
|
||||||
|
18 | urllib.request.Request('http://www.google.com')
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:17:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
15 | urllib.request.Request(url='http://' + 'www' + '.google.com')
|
||||||
|
16 | urllib.request.Request(url='http://www.google.com', **kwargs)
|
||||||
|
17 | urllib.request.Request(url=f'http://www.google.com', **kwargs)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
18 | urllib.request.Request('http://www.google.com')
|
||||||
|
19 | urllib.request.Request(f'http://www.google.com')
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:20:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
18 | urllib.request.Request('http://www.google.com')
|
||||||
|
19 | urllib.request.Request(f'http://www.google.com')
|
||||||
|
20 | urllib.request.Request('file:///foo/bar/baz')
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
21 | urllib.request.Request(url)
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:21:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:21:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
19 | urllib.request.Request(url)
|
19 | urllib.request.Request(f'http://www.google.com')
|
||||||
20 |
|
20 | urllib.request.Request('file:///foo/bar/baz')
|
||||||
21 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
21 | urllib.request.Request(url)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
22 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
22 |
|
||||||
23 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
23 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:22:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
21 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
|
||||||
22 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
23 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
|
||||||
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:23:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:23:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
21 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
21 | urllib.request.Request(url)
|
||||||
22 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
22 |
|
||||||
23 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
23 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
||||||
25 | urllib.request.URLopener().open('http://www.google.com')
|
25 | urllib.request.URLopener().open(fullurl='http://' + 'www' + '.google.com')
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:24:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:24:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
22 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
23 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
||||||
23 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
||||||
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
25 | urllib.request.URLopener().open('http://www.google.com')
|
25 | urllib.request.URLopener().open(fullurl='http://' + 'www' + '.google.com')
|
||||||
26 | urllib.request.URLopener().open(f'http://www.google.com')
|
26 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:25:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:25:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
23 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
23 | urllib.request.URLopener().open(fullurl='http://www.google.com')
|
||||||
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
||||||
25 | urllib.request.URLopener().open('http://www.google.com')
|
25 | urllib.request.URLopener().open(fullurl='http://' + 'www' + '.google.com')
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
26 | urllib.request.URLopener().open(f'http://www.google.com')
|
26 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
||||||
27 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
27 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:26:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:26:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
24 | urllib.request.URLopener().open(fullurl=f'http://www.google.com')
|
||||||
25 | urllib.request.URLopener().open('http://www.google.com')
|
25 | urllib.request.URLopener().open(fullurl='http://' + 'www' + '.google.com')
|
||||||
26 | urllib.request.URLopener().open(f'http://www.google.com')
|
26 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
27 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
27 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
||||||
28 | urllib.request.URLopener().open(url)
|
28 | urllib.request.URLopener().open('http://www.google.com')
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:27:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:27:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
25 | urllib.request.URLopener().open('http://www.google.com')
|
25 | urllib.request.URLopener().open(fullurl='http://' + 'www' + '.google.com')
|
||||||
26 | urllib.request.URLopener().open(f'http://www.google.com')
|
26 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
||||||
27 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
27 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
28 | urllib.request.URLopener().open(url)
|
28 | urllib.request.URLopener().open('http://www.google.com')
|
||||||
|
29 | urllib.request.URLopener().open(f'http://www.google.com')
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:28:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:28:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
26 | urllib.request.URLopener().open(f'http://www.google.com')
|
26 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs)
|
||||||
27 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
27 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
||||||
28 | urllib.request.URLopener().open(url)
|
28 | urllib.request.URLopener().open('http://www.google.com')
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
29 |
|
29 | urllib.request.URLopener().open(f'http://www.google.com')
|
||||||
30 | urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'))
|
30 | urllib.request.URLopener().open('http://' + 'www' + '.google.com')
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:29:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
27 | urllib.request.URLopener().open(fullurl=f'http://www.google.com', **kwargs)
|
||||||
|
28 | urllib.request.URLopener().open('http://www.google.com')
|
||||||
|
29 | urllib.request.URLopener().open(f'http://www.google.com')
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
30 | urllib.request.URLopener().open('http://' + 'www' + '.google.com')
|
||||||
|
31 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:30:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
28 | urllib.request.URLopener().open('http://www.google.com')
|
||||||
|
29 | urllib.request.URLopener().open(f'http://www.google.com')
|
||||||
|
30 | urllib.request.URLopener().open('http://' + 'www' + '.google.com')
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
31 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
||||||
|
32 | urllib.request.URLopener().open(url)
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:31:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
29 | urllib.request.URLopener().open(f'http://www.google.com')
|
||||||
|
30 | urllib.request.URLopener().open('http://' + 'www' + '.google.com')
|
||||||
|
31 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
32 | urllib.request.URLopener().open(url)
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:32:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:32:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
30 | urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'))
|
30 | urllib.request.URLopener().open('http://' + 'www' + '.google.com')
|
||||||
31 | urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'))
|
31 | urllib.request.URLopener().open('file:///foo/bar/baz')
|
||||||
32 | urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'), **kwargs)
|
32 | urllib.request.URLopener().open(url)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
33 | urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'), **kwargs)
|
33 |
|
||||||
34 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
34 | urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'))
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:33:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
31 | urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'))
|
|
||||||
32 | urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'), **kwargs)
|
|
||||||
33 | urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'), **kwargs)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
34 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
|
||||||
35 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:36:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
34 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
|
||||||
35 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
|
||||||
36 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
37 | urllib.request.urlopen(urllib.request.Request(url))
|
|
||||||
|
|
|
||||||
|
|
||||||
S310.py:36:24: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
|
||||||
|
|
|
||||||
34 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
|
||||||
35 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
|
||||||
36 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
|
||||||
37 | urllib.request.urlopen(urllib.request.Request(url))
|
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:37:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:37:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
35 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
35 | urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'))
|
||||||
36 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
36 | urllib.request.urlopen(url=urllib.request.Request('http://' + 'www' + '.google.com'))
|
||||||
37 | urllib.request.urlopen(urllib.request.Request(url))
|
37 | urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'), **kwargs)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
38 | urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'), **kwargs)
|
||||||
|
39 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:38:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
36 | urllib.request.urlopen(url=urllib.request.Request('http://' + 'www' + '.google.com'))
|
||||||
|
37 | urllib.request.urlopen(url=urllib.request.Request('http://www.google.com'), **kwargs)
|
||||||
|
38 | urllib.request.urlopen(url=urllib.request.Request(f'http://www.google.com'), **kwargs)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
39 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
||||||
|
40 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:41:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
39 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
||||||
|
40 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
||||||
|
41 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
42 | urllib.request.urlopen(urllib.request.Request(url))
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:41:24: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
39 | urllib.request.urlopen(urllib.request.Request('http://www.google.com'))
|
||||||
|
40 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
||||||
|
41 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
42 | urllib.request.urlopen(urllib.request.Request(url))
|
||||||
|
|
|
||||||
|
|
||||||
|
S310.py:42:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
||||||
|
40 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
||||||
|
41 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
||||||
|
42 | urllib.request.urlopen(urllib.request.Request(url))
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
|
|
|
||||||
|
|
||||||
S310.py:37:24: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
S310.py:42:24: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
|
||||||
|
|
|
|
||||||
35 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
40 | urllib.request.urlopen(urllib.request.Request(f'http://www.google.com'))
|
||||||
36 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
41 | urllib.request.urlopen(urllib.request.Request('file:///foo/bar/baz'))
|
||||||
37 | urllib.request.urlopen(urllib.request.Request(url))
|
42 | urllib.request.urlopen(urllib.request.Request(url))
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310
|
||||||
|
|
|
|
||||||
|
|
|
@ -1720,7 +1720,7 @@ impl StringLiteralValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the [`char`]s of each string literal part.
|
/// Returns an iterator over the [`char`]s of each string literal part.
|
||||||
pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
|
pub fn chars(&self) -> impl Iterator<Item = char> + Clone + '_ {
|
||||||
self.iter().flat_map(|part| part.value.chars())
|
self.iter().flat_map(|part| part.value.chars())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue