aboutsummaryrefslogtreecommitdiffstats
path: root/src/reader.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-06-29 12:21:09 -0400
committerDavid Robillard <d@drobilla.net>2017-06-29 12:21:09 -0400
commit195e4bcff3c4dfd3fe8bbf0df57d53ce89ca99e8 (patch)
tree952b067c7ace8afb1f78cb51ac032d18565c94a8 /src/reader.c
parent21211d73053d0a66a1da601472c68598cfc53595 (diff)
downloadserd-195e4bcff3c4dfd3fe8bbf0df57d53ce89ca99e8.tar.gz
serd-195e4bcff3c4dfd3fe8bbf0df57d53ce89ca99e8.tar.bz2
serd-195e4bcff3c4dfd3fe8bbf0df57d53ce89ca99e8.zip
Fix strict parsing of abolute URI schemes
Diffstat (limited to 'src/reader.c')
-rw-r--r--src/reader.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/reader.c b/src/reader.c
index 29526223..54e2724a 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -773,35 +773,44 @@ read_LANGTAG(SerdReader* reader)
return ref;
}
-typedef enum { PREFIX, GOOD, BAD} SchemeState;
-
-static inline bool
-check_scheme(SerdReader* reader, uint8_t c, SchemeState* state)
+static bool
+read_IRIREF_scheme(SerdReader* reader, Ref dest)
{
- if (!supports_relative_iris(reader) && *state == PREFIX) {
- if (c == ':') {
- *state = GOOD;
- } else if (!isalpha(c)) {
- *state = BAD;
+ uint8_t c = peek_byte(reader);
+ if (!isalpha(c)) {
+ return r_err(reader, SERD_ERR_BAD_SYNTAX,
+ "bad IRI scheme start `%c'\n", c);
+ }
+
+ while ((c = peek_byte(reader))) {
+ if (c == '>') {
+ return r_err(reader, SERD_ERR_BAD_SYNTAX, "missing IRI scheme\n");
+ } else if (!is_uri_scheme_char(c)) {
return r_err(reader, SERD_ERR_BAD_SYNTAX,
- "syntax does not support relative IRIs\n");
+ "bad IRI scheme char `%X'\n", c);
+ }
+
+ push_byte(reader, dest, eat_byte_safe(reader, c));
+ if (c == ':') {
+ return true; // End of scheme
}
}
- return true;
+
+ return false;
}
static Ref
read_IRIREF(SerdReader* reader)
{
TRY_RET(eat_byte_check(reader, '<'));
- Ref ref = push_node(reader, SERD_URI, "", 0);
- SchemeState scheme = PREFIX;
- uint32_t code;
+ Ref ref = push_node(reader, SERD_URI, "", 0);
+ if (!supports_relative_iris(reader) && !read_IRIREF_scheme(reader, ref)) {
+ return pop_node(reader, ref);
+ }
+
+ uint32_t code;
while (true) {
const uint8_t c = peek_byte(reader);
- if (!check_scheme(reader, c, &scheme)) {
- return pop_node(reader, ref);
- }
switch (c) {
case '"': case '<': case '^': case '`': case '{': case '|': case '}':
r_err(reader, SERD_ERR_BAD_SYNTAX,