From 92c783d6a5c80af365434c28d9c4717e7e31a1e0 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 15 Aug 2020 11:58:54 +0200 Subject: Harden prefixed name parsing --- NEWS | 3 ++- src/n3.c | 48 ++++++++++++++++++++++++++++++++++++--------- tests/bad/bad-pn-escape.ttl | 2 ++ tests/bad/manifest.ttl | 6 ++++++ 4 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 tests/bad/bad-pn-escape.ttl diff --git a/NEWS b/NEWS index 609ecb6e..772074cc 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ serd (0.30.5) unstable; * Fix various minor warnings and other code quality issues + * Parse prefixed names more strictly - -- David Robillard Sun, 21 Jun 2020 16:05:27 +0000 + -- David Robillard Sat, 15 Aug 2020 09:58:54 +0000 serd (0.30.4) stable; diff --git a/src/n3.c b/src/n3.c index ee9cd581..29349e22 100644 --- a/src/n3.c +++ b/src/n3.c @@ -496,10 +496,47 @@ read_PERCENT(SerdReader* reader, Ref dest) return false; } +static SerdStatus +read_PN_LOCAL_ESC(SerdReader* reader, Ref dest) +{ + eat_byte_safe(reader, '\\'); + + const int c = peek_byte(reader); + switch (c) { + case '!': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case '-': + case '.': + case '/': + case ';': + case '=': + case '?': + case '@': + case '_': + case '~': + push_byte(reader, dest, eat_byte_safe(reader, c)); + break; + default: + r_err(reader, SERD_ERR_BAD_SYNTAX, "invalid escape\n"); + return SERD_ERR_BAD_SYNTAX; + } + + return SERD_SUCCESS; +} + static SerdStatus read_PLX(SerdReader* reader, Ref dest) { - int c = peek_byte(reader); + const int c = peek_byte(reader); switch (c) { case '%': if (!read_PERCENT(reader, dest)) { @@ -507,14 +544,7 @@ read_PLX(SerdReader* reader, Ref dest) } return SERD_SUCCESS; case '\\': - eat_byte_safe(reader, c); - if (is_alpha(c = peek_byte(reader))) { - // Escapes like \u \n etc. are not supported - return SERD_ERR_BAD_SYNTAX; - } - // Allow escaping of pretty much any other character - push_byte(reader, dest, eat_byte_safe(reader, c)); - return SERD_SUCCESS; + return read_PN_LOCAL_ESC(reader, dest); default: return SERD_FAILURE; } diff --git a/tests/bad/bad-pn-escape.ttl b/tests/bad/bad-pn-escape.ttl new file mode 100644 index 00000000..2b363e89 --- /dev/null +++ b/tests/bad/bad-pn-escape.ttl @@ -0,0 +1,2 @@ +@prefix : . +:s :p :\a diff --git a/tests/bad/manifest.ttl b/tests/bad/manifest.ttl index d294f120..57fb02f7 100644 --- a/tests/bad/manifest.ttl +++ b/tests/bad/manifest.ttl @@ -62,6 +62,7 @@ <#bad-num> <#bad-object2> <#bad-object> + <#bad-pn-escape> <#bad-prefix> <#bad-semicolon-after-subject> <#bad-string> @@ -351,6 +352,11 @@ mf:name "bad-object" ; mf:action . +<#bad-pn-escape> + rdf:type rdft:TestTurtleNegativeSyntax ; + mf:name "bad-pn-escape" ; + mf:action . + <#bad-prefix> rdf:type rdft:TestTurtleNegativeSyntax ; mf:name "bad-prefix" ; -- cgit v1.2.1