Allow the full range of valid form field renames.

Closes #337.
This commit is contained in:
Sergio Benitez 2017-08-02 17:37:20 -07:00
parent 944eaa3e3c
commit 952c98fc04
5 changed files with 39 additions and 8 deletions

View File

@ -19,7 +19,7 @@ rocket = { version = "0.3.0", path = "../lib/" }
log = "0.3"
[dev-dependencies]
compiletest_rs = "0.2"
compiletest_rs = "0.2.9"
[build-dependencies]
yansi = "0.3"

View File

@ -122,6 +122,18 @@ pub fn from_form_derive(ecx: &mut ExtCtxt, span: Span, meta_item: &MetaItem,
trait_def.expand(ecx, meta_item, annotated, push);
}
fn is_valid_field_name(name: &str) -> bool {
// The HTML5 spec (4.10.18.1) says 'isindex' is not allowed.
if name == "isindex" || name.is_empty() {
return false
}
// We allow all visible ASCII characters except '&', '=', and '?' since we
// use those as control characters for parsing.
name.chars()
.all(|c| (c >= ' ' && c <= '~') && c != '&' && c != '=' && c != '?')
}
pub fn extract_field_ident_name(ecx: &ExtCtxt, struct_field: &StructField)
-> (Ident, String, Span) {
let ident = match struct_field.ident {
@ -168,8 +180,10 @@ pub fn extract_field_ident_name(ecx: &ExtCtxt, struct_field: &StructField)
let name = inner_item.value_str().unwrap().as_str().to_string();
let sp = inner_item.span.shorten_upto(name.len() + 2);
if !is_valid_ident(&name) {
ecx.span_err(sp, "invalid form field identifier");
if !is_valid_field_name(&name) {
ecx.struct_span_err(sp, "invalid form field name")
.help("field names be visible ASCII characters without '&', '=', or '?'")
.emit();
}
(ident, name, sp)

View File

@ -84,7 +84,7 @@ struct MyForm10 {
#[derive(FromForm)]
struct MyForm11 {
#[form(field = "hello world")]
#[form(field = "hello&world")]
//~^ ERROR: invalid form field
first: String,
}
@ -95,3 +95,17 @@ struct MyForm12 {
//~^ ERROR: invalid form field
first: String,
}
#[derive(FromForm)]
struct MyForm13 {
#[form(field = "?")]
//~^ ERROR: invalid form field
first: String,
}
#[derive(FromForm)]
struct MyForm14 {
#[form(field = "")]
//~^ ERROR: invalid form field
first: String,
}

View File

@ -17,6 +17,8 @@ struct Form {
field_type: isize,
#[form(field = "DOUBLE")]
double: String,
#[form(field = "a.b")]
dot: isize,
}
fn parse<'f, T: FromForm<'f>>(string: &'f str, strict: bool) -> Option<T> {
@ -36,7 +38,7 @@ fn parse_strict<'f, T: FromForm<'f>>(string: &'f str) -> Option<T> {
fn main() {
let form_string = &[
"single=100", "camelCase=helloThere", "TitleCase=HiHi", "type=-2",
"DOUBLE=bing_bong"
"DOUBLE=bing_bong", "a.b=123",
].join("&");
let form: Option<Form> = parse_strict(&form_string);
@ -45,12 +47,13 @@ fn main() {
camel_case: "helloThere".into(),
title_case: "HiHi".into(),
field_type: -2,
double: "bing_bong".into()
double: "bing_bong".into(),
dot: 123,
}));
let form_string = &[
"single=100", "camel_case=helloThere", "TitleCase=HiHi", "type=-2",
"DOUBLE=bing_bong"
"DOUBLE=bing_bong", "dot=123",
].join("&");
let form: Option<Form> = parse_strict(&form_string);

View File

@ -3,7 +3,7 @@ extern crate compiletest_rs as compiletest;
use std::path::PathBuf;
fn run_mode(mode: &'static str) {
let mut config = compiletest::default_config();
let mut config = compiletest::Config::default();
let cfg_mode = mode.parse().expect("Invalid mode");
config.mode = cfg_mode;