aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-05-10 15:31:22 +0200
committerDavid Robillard <d@drobilla.net>2018-06-10 19:57:44 +0000
commite3a491db47da8ae03d6390e71652ca53779fb393 (patch)
tree83e87c0400b575bf42738e7136ae58df2d17fb22
parentd208424fdb4e8b516aff2a5a0d03fc7411909471 (diff)
downloadserd-e3a491db47da8ae03d6390e71652ca53779fb393.tar.gz
serd-e3a491db47da8ae03d6390e71652ca53779fb393.tar.bz2
serd-e3a491db47da8ae03d6390e71652ca53779fb393.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 e2bcf196..1b02c2be 100644
--- a/src/byte_source.c
+++ b/src/byte_source.c
@@ -65,9 +65,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) {
@@ -85,7 +84,6 @@ serd_byte_source_open_string(SerdByteSource* source, const uint8_t* utf8)
memset(source, '\0', sizeof(*source));
source->cur = cur;
source->read_buf = utf8;
- source->prepared = true;
return SERD_SUCCESS;
}
@@ -111,13 +109,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 d515aaab..e9210927 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -348,16 +348,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