aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-08-15 20:11:19 +0200
committerDavid Robillard <d@drobilla.net>2020-10-27 13:13:58 +0100
commit15908997ce13c5af5f8cb517b9266c04889c3d98 (patch)
tree91f0ff13685206303c4e27a3c96f17d0bf0c6595
parent2e4f78fcee15cb7cf76722c8fd0d1b18a4d8afbf (diff)
downloadserd-15908997ce13c5af5f8cb517b9266c04889c3d98.tar.gz
serd-15908997ce13c5af5f8cb517b9266c04889c3d98.tar.bz2
serd-15908997ce13c5af5f8cb517b9266c04889c3d98.zip
Improve reader error handling
-rw-r--r--src/n3.c71
1 files changed, 38 insertions, 33 deletions
diff --git a/src/n3.c b/src/n3.c
index edf26089..a21135ea 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -479,7 +479,11 @@ read_PN_CHARS(SerdReader* reader, SerdNode* dest)
static SerdStatus
read_PERCENT(SerdReader* reader, SerdNode* dest)
{
- push_byte(reader, dest, eat_byte_safe(reader, '%'));
+ SerdStatus st = push_byte(reader, dest, eat_byte_safe(reader, '%'));
+ if (st) {
+ return st;
+ }
+
const uint8_t h1 = read_HEX(reader);
const uint8_t h2 = read_HEX(reader);
if (h1 && h2) {
@@ -661,7 +665,7 @@ read_IRIREF_scheme(SerdReader* reader, SerdNode* dest)
}
}
- return r_err(reader, SERD_ERR_BAD_SYNTAX, "unexpected end of file\n");
+ return SERD_FAILURE;
}
static SerdStatus
@@ -671,9 +675,9 @@ read_IRIREF(SerdReader* reader, SerdNode** dest)
return SERD_ERR_BAD_SYNTAX;
}
- *dest = push_node(reader, SERD_URI, "", 0);
-
- if (!fancy_syntax(reader) && read_IRIREF_scheme(reader, *dest)) {
+ if (!(*dest = push_node(reader, SERD_URI, "", 0))) {
+ return SERD_ERR_OVERFLOW;
+ } else if (!fancy_syntax(reader) && read_IRIREF_scheme(reader, *dest)) {
return r_err(reader, SERD_ERR_BAD_SYNTAX, "expected IRI scheme\n");
}
@@ -739,11 +743,12 @@ read_PrefixedName(SerdReader* reader, SerdNode* dest, bool read_prefix, bool* at
return SERD_FAILURE;
}
- push_byte(reader, dest, eat_byte_safe(reader, ':'));
-
- st = read_PN_LOCAL(reader, dest, ate_dot);
+ if ((st = push_byte(reader, dest, eat_byte_safe(reader, ':'))) ||
+ (st = read_PN_LOCAL(reader, dest, ate_dot)) > SERD_FAILURE) {
+ return st;
+ }
- return (st > SERD_FAILURE) ? st : SERD_SUCCESS;
+ return SERD_SUCCESS;
}
static SerdStatus
@@ -831,21 +836,21 @@ read_iri(SerdReader* reader, SerdNode** dest, bool* ate_dot)
case '<':
return read_IRIREF(reader, dest);
default:
- if (!(*dest = push_node(reader, SERD_CURIE, "", 0))) {
- return SERD_ERR_OVERFLOW;
- }
- return read_PrefixedName(reader, *dest, true, ate_dot);
+ *dest = push_node(reader, SERD_CURIE, "", 0);
+ return *dest ? read_PrefixedName(reader, *dest, true, ate_dot)
+ : SERD_ERR_OVERFLOW;
}
}
static SerdStatus
read_literal(SerdReader* reader, SerdNode** dest, bool* ate_dot)
{
- *dest = push_node(reader, SERD_LITERAL, "", 0);
+ if (!(*dest = push_node(reader, SERD_LITERAL, "", 0))) {
+ return SERD_ERR_OVERFLOW;
+ }
SerdStatus st = read_String(reader, *dest);
if (st) {
- *dest = NULL;
return st;
}
@@ -854,17 +859,13 @@ read_literal(SerdReader* reader, SerdNode** dest, bool* ate_dot)
case '@':
eat_byte_safe(reader, '@');
(*dest)->flags |= SERD_HAS_LANGUAGE;
- if ((st = read_LANGTAG(reader))) {
- return r_err(reader, st, "bad literal\n");
- }
+ TRY(st, read_LANGTAG(reader));
break;
case '^':
eat_byte_safe(reader, '^');
eat_byte_check(reader, '^');
(*dest)->flags |= SERD_HAS_DATATYPE;
- if ((st = read_iri(reader, &datatype, ate_dot))) {
- return r_err(reader, st, "bad literal\n");
- }
+ TRY(st, read_iri(reader, &datatype, ate_dot));
break;
}
return SERD_SUCCESS;
@@ -893,8 +894,8 @@ read_verb(SerdReader* reader, SerdNode** dest)
serd_node_string(node)[0] == 'a' &&
next != ':' && !is_PN_CHARS_BASE((uint32_t)next)) {
serd_stack_pop_to(&reader->stack, orig_stack_size);
- *dest = push_node(reader, SERD_URI, NS_RDF "type", 47);
- return SERD_SUCCESS;
+ return ((*dest = push_node(reader, SERD_URI, NS_RDF "type", 47))
+ ? SERD_SUCCESS : SERD_ERR_OVERFLOW);
} else if (st > SERD_FAILURE ||
read_PrefixedName(reader, *dest, false, &ate_dot) ||
ate_dot) {
@@ -910,14 +911,14 @@ read_BLANK_NODE_LABEL(SerdReader* reader, SerdNode** dest, bool* ate_dot)
{
eat_byte_safe(reader, '_');
eat_byte_check(reader, ':');
+ if (!(*dest = push_node(reader, SERD_BLANK,
+ reader->bprefix ? reader->bprefix : "",
+ reader->bprefix_len))) {
+ return SERD_ERR_OVERFLOW;
+ }
- SerdNode* n = *dest =
- push_node(reader,
- SERD_BLANK,
- reader->bprefix ? reader->bprefix : "",
- reader->bprefix_len);
-
- int c = peek_byte(reader); // First: (PN_CHARS | '_' | [0-9])
+ SerdNode* n = *dest;
+ int c = peek_byte(reader); // First: (PN_CHARS | '_' | [0-9])
if (is_digit(c) || c == '_') {
push_byte(reader, n, eat_byte_safe(reader, c));
} else if (read_PN_CHARS(reader, n)) {
@@ -1043,6 +1044,7 @@ read_object(SerdReader* reader, ReadContext* ctx, bool emit, bool* ate_dot)
"expected: ':', '<', or '_'\n");
}
}
+
switch (c) {
case EOF: case ')':
return r_err(reader, SERD_ERR_BAD_SYNTAX, "expected object\n");
@@ -1083,8 +1085,11 @@ read_object(SerdReader* reader, ReadContext* ctx, bool emit, bool* ate_dot)
!memcmp(serd_node_string(o), "false", 5))) {
o->flags |= SERD_HAS_DATATYPE;
o->type = SERD_LITERAL;
- push_node(reader, SERD_URI, XSD_BOOLEAN, XSD_BOOLEAN_LEN);
- ret = SERD_SUCCESS;
+ if (!(push_node(reader, SERD_URI, XSD_BOOLEAN, XSD_BOOLEAN_LEN))) {
+ ret = SERD_ERR_OVERFLOW;
+ } else {
+ ret = SERD_SUCCESS;
+ }
} else if (read_PN_PREFIX_tail(reader, o) > SERD_FAILURE) {
ret = SERD_ERR_BAD_SYNTAX;
} else {
@@ -1279,7 +1284,7 @@ read_labelOrSubject(SerdReader* reader, SerdNode** dest)
return SERD_ERR_BAD_SYNTAX;
}
*dest = blank_id(reader);
- return SERD_SUCCESS;
+ return *dest ? SERD_SUCCESS : SERD_ERR_OVERFLOW;
case '_':
return read_BLANK_NODE_LABEL(reader, dest, &ate_dot);
default: