diff options
author | David Robillard <d@drobilla.net> | 2016-05-29 18:34:09 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2016-05-29 18:34:09 -0400 |
commit | 8f7cac4752d427f833969d316542d7a82b4602ea (patch) | |
tree | 27dcc29cbca11aee2127ddcdc71a246fbed077e9 | |
parent | 78e55b937ce347eef6387499ddd91d06d73e3a7c (diff) | |
download | serd-8f7cac4752d427f833969d316542d7a82b4602ea.tar.gz serd-8f7cac4752d427f833969d316542d7a82b4602ea.tar.bz2 serd-8f7cac4752d427f833969d316542d7a82b4602ea.zip |
Fix handling of file I/O errors
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/reader.c | 13 | ||||
-rw-r--r-- | src/serdi.c | 12 | ||||
-rw-r--r-- | wscript | 11 |
4 files changed, 31 insertions, 8 deletions
@@ -1,11 +1,12 @@ serd (0.22.3) unstable; + * Report I/O errors with message and return appropriate status code * Fix potential out of bounds read * Fix unaligned memory access, undefined behaviour which breaks on ARM * Fix documentation generation * Update serdi man page - -- David Robillard <d@drobilla.net> Tue, 17 May 2016 11:58:20 -0400 + -- David Robillard <d@drobilla.net> Sun, 29 May 2016 18:33:41 -0400 serd (0.22.0) stable; diff --git a/src/reader.c b/src/reader.c index e6af0b1c..5465dba6 100644 --- a/src/reader.c +++ b/src/reader.c @@ -87,6 +87,7 @@ struct SerdReaderImpl { bool paging; ///< True iff reading a page at a time bool strict; ///< True iff strict parsing bool eof; + bool error; bool seen_genid; #ifdef SERD_STACK_CHECK Ref* allocs; ///< Stack of push offsets @@ -115,7 +116,13 @@ page(SerdReader* reader) if (n_read == 0) { reader->file_buf[0] = '\0'; reader->eof = true; - return ferror(reader->fd) ? SERD_ERR_UNKNOWN : SERD_FAILURE; + if (ferror(reader->fd)) { + reader->error = true; + return r_err(reader, SERD_ERR_UNKNOWN, + "read error: %s\n", strerror(errno)); + } else { + return SERD_FAILURE; + } } else if (n_read < SERD_PAGE_SIZE) { reader->file_buf[n_read] = '\0'; } @@ -1446,7 +1453,7 @@ read_statement(SerdReader* reader) switch (peek_byte(reader)) { case '\0': reader->eof = true; - return true; + return !reader->error; case '@': TRY_RET(read_directive(reader)); read_ws_star(reader); @@ -1472,7 +1479,7 @@ read_turtleDoc(SerdReader* reader) while (!reader->eof) { TRY_RET(read_statement(reader)); } - return true; + return !reader->error; } SERD_API diff --git a/src/serdi.c b/src/serdi.c index 2054470e..9332519b 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -252,15 +252,19 @@ main(int argc, char** argv) } serd_reader_free(reader); + serd_writer_finish(writer); + serd_writer_free(writer); + serd_env_free(env); + serd_node_free(&base); if (from_file) { fclose(in_fd); } - serd_writer_finish(writer); - serd_writer_free(writer); - serd_env_free(env); - serd_node_free(&base); + if (fclose(out_fd)) { + perror("serdi: write error"); + status = SERD_ERR_UNKNOWN; + } return (status > SERD_FAILURE) ? 1 : 0; } @@ -416,6 +416,17 @@ def test(ctx): 'serdi_static %s > %s' % (nul, nul)], 0, name='serdi-cmd-good') + # Test read error by reading a directory + autowaf.run_test(ctx, APPNAME, + 'serdi_static "file://%s/"' % srcdir, + 1, name='read_error') + + # Test write error by writing to /dev/full + if os.path.exists('/dev/full'): + autowaf.run_test(ctx, APPNAME, + 'serdi_static "file://%s/tests/good/manifest.ttl" > /dev/full' % srcdir, + 1, name='write_error') + autowaf.run_tests(ctx, APPNAME, [ 'serdi_static -q "file://%s/tests/bad-id-clash.ttl" > %s' % (srcdir, nul), 'serdi_static > %s' % nul, |