diff options
author | David Robillard <d@drobilla.net> | 2020-08-15 11:58:54 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-08-15 22:52:03 +0200 |
commit | 92c783d6a5c80af365434c28d9c4717e7e31a1e0 (patch) | |
tree | 8329ec4227f0e78c774cc34ab1f4eb2c5b840844 /src | |
parent | a23f71a0854a8e6e42fe3b2890ef2ab0ebc15aaf (diff) | |
download | serd-92c783d6a5c80af365434c28d9c4717e7e31a1e0.tar.gz serd-92c783d6a5c80af365434c28d9c4717e7e31a1e0.tar.bz2 serd-92c783d6a5c80af365434c28d9c4717e7e31a1e0.zip |
Harden prefixed name parsing
Diffstat (limited to 'src')
-rw-r--r-- | src/n3.c | 48 |
1 files changed, 39 insertions, 9 deletions
@@ -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; } |