aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-08-15 11:58:54 +0200
committerDavid Robillard <d@drobilla.net>2020-08-15 22:52:03 +0200
commit92c783d6a5c80af365434c28d9c4717e7e31a1e0 (patch)
tree8329ec4227f0e78c774cc34ab1f4eb2c5b840844 /src
parenta23f71a0854a8e6e42fe3b2890ef2ab0ebc15aaf (diff)
downloadserd-92c783d6a5c80af365434c28d9c4717e7e31a1e0.tar.gz
serd-92c783d6a5c80af365434c28d9c4717e7e31a1e0.tar.bz2
serd-92c783d6a5c80af365434c28d9c4717e7e31a1e0.zip
Harden prefixed name parsing
Diffstat (limited to 'src')
-rw-r--r--src/n3.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/src/n3.c b/src/n3.c
index ee9cd581..29349e22 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -497,9 +497,46 @@ read_PERCENT(SerdReader* reader, Ref dest)
}
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;
}