Add guard in ruma_api! macro for invalid characters in path
Returns a compiler error if any non ASCII characters are found. Add trybuild test for invalid path characters.
This commit is contained in:
parent
b08b1d1819
commit
214c1b681f
@ -269,8 +269,8 @@ impl ToTokens for Api {
|
||||
*http_request.uri_mut() = ruma_api::exports::http::uri::Builder::new()
|
||||
.path_and_query(path_and_query.as_str())
|
||||
.build()
|
||||
// The only way this can fail is if the path given in the API definition is
|
||||
// invalid. It is okay to panic in that case.
|
||||
// The ruma_api! macro guards against invalid path input, but if there are
|
||||
// invalid (non ASCII) bytes in the fields with the query attribute this will panic.
|
||||
.unwrap();
|
||||
|
||||
{ #add_headers_to_request }
|
||||
|
@ -4,7 +4,7 @@ use std::convert::TryFrom;
|
||||
|
||||
use syn::{Expr, ExprLit, ExprPath, Ident, Lit, LitBool, LitStr, Member};
|
||||
|
||||
use crate::api::RawMetadata;
|
||||
use crate::{api::RawMetadata, util};
|
||||
|
||||
/// The result of processing the `metadata` section of the macro.
|
||||
pub struct Metadata {
|
||||
@ -61,6 +61,13 @@ impl TryFrom<RawMetadata> for Metadata {
|
||||
},
|
||||
"path" => match expr {
|
||||
Expr::Lit(ExprLit { lit: Lit::Str(literal), .. }) => {
|
||||
let path_str = literal.value();
|
||||
if !util::is_valid_endpoint_path(&path_str) {
|
||||
return Err(syn::Error::new_spanned(
|
||||
literal,
|
||||
"path may only contain printable ASCII characters with no spaces",
|
||||
));
|
||||
}
|
||||
path = Some(literal);
|
||||
}
|
||||
_ => return Err(syn::Error::new_spanned(expr, "expected a string literal")),
|
||||
|
@ -257,3 +257,7 @@ pub(crate) fn req_res_name_value<T>(
|
||||
*header = Some(value);
|
||||
Ok(field_kind)
|
||||
}
|
||||
|
||||
pub(crate) fn is_valid_endpoint_path(string: &str) -> bool {
|
||||
string.as_bytes().iter().all(|b| (0x21..=0x7E).contains(b))
|
||||
}
|
||||
|
@ -2,4 +2,5 @@
|
||||
fn ui() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.pass("tests/ui/01-api-sanity-check.rs");
|
||||
t.compile_fail("tests/ui/02-invalid-path.rs");
|
||||
}
|
||||
|
39
ruma-api/tests/ui/02-invalid-path.rs
Normal file
39
ruma-api/tests/ui/02-invalid-path.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use ruma_api::ruma_api;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "This will fail.",
|
||||
method: GET,
|
||||
name: "invalid_path",
|
||||
path: "µ/°/§/€",
|
||||
rate_limited: false,
|
||||
requires_authentication: false,
|
||||
}
|
||||
|
||||
request: {
|
||||
#[ruma_api(query_map)]
|
||||
pub fields: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
response: { }
|
||||
}
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "This will fail.",
|
||||
method: GET,
|
||||
name: "invalid_path",
|
||||
path: "path/to/invalid space/endpoint",
|
||||
rate_limited: false,
|
||||
requires_authentication: false,
|
||||
}
|
||||
|
||||
request: {
|
||||
#[ruma_api(query_map)]
|
||||
pub fields: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
response: { }
|
||||
}
|
||||
|
||||
fn main() {}
|
11
ruma-api/tests/ui/02-invalid-path.stderr
Normal file
11
ruma-api/tests/ui/02-invalid-path.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error: path may only contain printable ASCII characters with no spaces
|
||||
--> $DIR/02-invalid-path.rs:8:15
|
||||
|
|
||||
8 | path: "µ/°/§/€",
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: path may only contain printable ASCII characters with no spaces
|
||||
--> $DIR/02-invalid-path.rs:26:15
|
||||
|
|
||||
26 | path: "path/to/invalid space/endpoint",
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
Loading…
x
Reference in New Issue
Block a user