commit de428fff65f1ef1a337a1caafb3d580433c73fc9 from: Omar Polo date: Wed Jan 13 19:00:53 2021 UTC normalize schema when parsing the IRI RFC3986 in section 3.1 "Scheme" says that > Although schemes are case-insensitive, the canonical form is > lowercase and documents that specify schemes must do so with > lowercase letters. An implementation should accept uppercase > letters as equivalent to lowercase in scheme names (e.g., allow > "HTTP" as well as "http") for the sake of robustness but should only > produce lowercase scheme names for consistency. so we cope with that. The other possibility would have been to use strcasecmp instead of strcmp when checking on the protocol, but since the "case" version, although popular, is not part of any standard AFAIK I prefer downcasing while parsing and be done with it. commit - 9862b637c2aa97e7e8d148ae9c3f92d0ca758fa7 commit + de428fff65f1ef1a337a1caafb3d580433c73fc9 blob - 1901dacc40fcb2989ebb0fb7fd604756a49d7045 blob + 1b997dd7ce1164b0ccc0735a0efdfde14706c184 --- iri.c +++ iri.c @@ -77,12 +77,19 @@ parse_scheme(struct parser *p) return 0; } - p->iri++; - while (isalnum(*p->iri) + do { + /* normalize the scheme (i.e. lowercase it) + * + * XXX: since we cannot have good things, tolower + * depends on the LC_CTYPE locale. The good things is + * that we're sure p->iri points to something in the + * ASCII range, so it shouldn't do weird stuff. */ + *p->iri = tolower(*p->iri); + p->iri++; + } while (isalnum(*p->iri) || *p->iri == '+' || *p->iri == '-' - || *p->iri == '.') - p->iri++; + || *p->iri == '.'); if (*p->iri != ':') { p->err = "illegal character in scheme"; blob - 18a102039c98f6227da39ab5bdb7dbc3b7ff8b3c blob + e3228134bbfd322a8cd8cdfefbe0343258ea7ea6 --- iri_test.c +++ iri_test.c @@ -97,6 +97,10 @@ main(void) TEST("gemini:/omarpolo.com", FAIL, empty, "FAIL with invalid marker"); TEST("gemini//omarpolo.com", FAIL, empty, "FAIL with invalid marker"); TEST("h!!p://omarpolo.com", FAIL, empty, "FAIL with invalid schema"); + TEST("GEMINI://omarpolo.com", + PASS, + IRI("gemini", "omarpolo.com", "", "", "", ""), + "Schemas are case insensitive."); /* authority */ TEST("gemini://omarpolo.com",