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:
Ragotzy.devin 2020-07-02 10:27:49 -04:00 committed by GitHub
parent b08b1d1819
commit 214c1b681f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 3 deletions

View File

@ -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 }

View File

@ -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")),

View File

@ -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))
}

View File

@ -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");
}

View 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() {}

View 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",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^