aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-05-10 15:31:22 +0200
committerDavid Robillard <d@drobilla.net>2018-05-27 18:21:57 +0200
commit56fcd25f5258ecc31cca2e728ab0913cec99c057 (patch)
tree792d8764338dda5c48b55e632f036a11ccb8bfbe
parentb5eeb621520d9c0c2647bfa1bfb53045a75a8b6e (diff)
downloadserd-56fcd25f5258ecc31cca2e728ab0913cec99c057.tar.gz
serd-56fcd25f5258ecc31cca2e728ab0913cec99c057.tar.bz2
serd-56fcd25f5258ecc31cca2e728ab0913cec99c057.zip
Fix byte source to never read past end of strings
-rw-r--r--src/byte_source.c27
-rw-r--r--src/reader.c12
2 files changed, 21 insertions, 18 deletions
diff --git a/src/byte_source.c b/src/byte_source.c
index b77c1885..c48d8ef7 100644
--- a/src/byte_source.c
+++ b/src/byte_source.c
@@ -67,9 +67,8 @@ serd_byte_source_open_source(SerdByteSource* source,
SerdStatus
serd_byte_source_prepare(SerdByteSource* source)
{
- if (!source->prepared) {
- source->eof = false;
- source->prepared = true;
+ source->prepared = true;
+ if (source->from_stream) {
if (source->page_size > 1) {
return serd_byte_source_page(source);
} else if (source->from_stream) {
@@ -87,7 +86,6 @@ serd_byte_source_open_string(SerdByteSource* source, const char* utf8)
memset(source, '\0', sizeof(*source));
source->cur = cur;
source->read_buf = utf8;
- source->prepared = true;
return SERD_SUCCESS;
}
@@ -113,13 +111,22 @@ serd_byte_source_advance(SerdByteSource* source)
default: ++source->cur.col;
}
- if (source->from_stream && !paging) {
- if (source->read_func(&source->read_byte, 1, 1, source->stream) == 0) {
- return (source->error_func(source->stream)
- ? SERD_ERR_UNKNOWN : SERD_FAILURE);
+ // Reset EOF marker for reading from sockets/pipes
+ source->eof = source->eof && !source->from_stream;
+
+ if (source->from_stream && paging) {
+ if (++source->read_head == source->page_size) {
+ st = serd_byte_source_page(source);
}
- } else if (++source->read_head == source->page_size && paging) {
- st = serd_byte_source_page(source);
+ } else if (source->from_stream) {
+ if (!source->read_func(&source->read_byte, 1, 1, source->stream)) {
+ st = source->error_func(source->stream) ? SERD_ERR_UNKNOWN
+ : SERD_FAILURE;
+ }
+ } else if (source->eof) {
+ st = SERD_FAILURE; // Can't read past end of string
+ } else {
+ ++source->read_head; // Move to next character in string
}
return st;
diff --git a/src/reader.c b/src/reader.c
index b4cf4f34..c02a2a13 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -342,16 +342,12 @@ serd_reader_read_chunk(SerdReader* reader)
{
SerdStatus st = SERD_SUCCESS;
if (!reader->source.prepared) {
- if ((st = serd_reader_prepare(reader))) {
- return st;
- }
+ st = serd_reader_prepare(reader);
} else if (reader->source.eof) {
- reader->source.eof = false;
- if ((st = serd_byte_source_advance(&reader->source))) {
- return st;
- }
+ st = serd_byte_source_advance(&reader->source);
}
- return read_statement(reader) ? SERD_SUCCESS : SERD_FAILURE;
+
+ return st ? st : read_statement(reader) ? SERD_SUCCESS : SERD_FAILURE;
}
SERD_API