From 1042068c89bd39128676ee12ee1fb6f31aab7f95 Mon Sep 17 00:00:00 2001 From: Martin Larralde Date: Mon, 28 Sep 2020 18:02:03 +0200 Subject: [PATCH] Fix issue with `Iri` rule not handling URLs without trailing slash --- src/grammar.pest | 7 +++++-- tests/parser.rs | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/grammar.pest b/src/grammar.pest index d5500e7..3945c61 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -394,8 +394,11 @@ ResourcePropertyValue = { RelationId ~ Id } Iri = @{ IriScheme ~ ":" ~ IriHierPart ~ ("?" ~ IriQuery)? ~ ("#" ~ IriFragment)? } +// NB(@althonos): IriPathAbEmpty is not mandatory if we reach the end of input +// here to allow URLs to hosts without trailing slashes, e.g. +/// 'http://example.com', which would be rejected otherwise. IriHierPart = { - ("//" ~ IriAuthority ~ IriPathAbempty ) + ("//" ~ IriAuthority ~ (IriPathAbempty | EOI) ) | IriPathAbsolute | IriPathRootless | IriPathEmpty @@ -411,7 +414,7 @@ IriPathAbempty = ${ ("/" ~ IriSegment)+ } IriPathAbsolute = ${ "/" ~ (IriSegmentNz ~ ("/" ~ IriSegment)* )? } IriPathNoScheme = ${ IriSegmentNzNc ~ ("/" ~ IriSegment)* } IriPathRootless = ${ IriSegmentNz ~ ("/" ~ IriSegment)* } -IriPathEmpty = ${ "0" ~ IriIpChar} +IriPathEmpty = ${ "" } IriSegment = @{ IriIpChar* } IriSegmentNz = @{ IriIpChar+ } diff --git a/tests/parser.rs b/tests/parser.rs index d84e0e9..a5c78ab 100644 --- a/tests/parser.rs +++ b/tests/parser.rs @@ -87,6 +87,9 @@ fn term_frame() { test_parse!(TermFrame, "[Term]\n id: TEST:001\ndef: \"test item\" []\n"); test_parse!(TermFrame, "[Term]\nid: TEST:001\n def: \"test item\" []\n"); test_parse!(TermFrame, " [Term]\nid: TEST:001\ndef: \"test item\" []\n"); + // url id + test_parse!(TermFrame, "[Term]\nid: http://example.com\ndef: \"test item\" []\n"); + test_parse!(TermFrame, "[Term]\nid: http://example.com/\ndef: \"test item\" []\n"); } #[test] @@ -134,3 +137,23 @@ fn property_value() { test_parse!(ResourcePropertyValue, "foaf:depiction http://purl.obolibrary.org/obo/plana/images/Stage2.png"); test_not_parse!(LiteralPropertyValue, "foaf:depiction http://purl.obolibrary.org/obo/plana/images/Stage2.png"); } + +#[test] +fn iri() { + test_parse!(Iri, "http://example.com"); + test_parse!(Iri, "http://example.com/"); + test_parse!(Iri, "http://example.com/with/a/path"); + test_parse!(Iri, "http://user:pass@example.com"); + test_parse!(Iri, "http://user:pass@example.com/"); + test_parse!(Iri, "http://user:pass@example.com/with/a/path"); +} + +#[test] +fn term_clause() { + test_parse!(TermClause, "xref: http://example.com"); + test_parse!(TermClause, "xref: http://example.com/"); + test_parse!(TermClause, "xref: http://example.com/with/a/path"); + test_parse!(TermClause, "xref: http://user:pass@example.com"); + test_parse!(TermClause, "xref: http://user:pass@example.com/"); + test_parse!(TermClause, "xref: http://user:pass@example.com/with/a/path"); +}