Browse Source

Fix reading from a null-delimited socket

zrythm_meson
David Robillard 3 years ago
parent
commit
2efb107eb4
  1. 3
      NEWS
  2. 6
      src/reader.c
  3. 61
      tests/serd_test.c
  4. 2
      wscript

3
NEWS

@ -2,8 +2,9 @@ serd (0.30.3) unstable; @@ -2,8 +2,9 @@ serd (0.30.3) unstable;
* Fix EOF handling while reading in bulk or from strings
* Fix lax handling of string errors
* Fix reading from a null-delimited socket
-- David Robillard <d@drobilla.net> Sun, 27 Oct 2019 21:41:05 +0000
-- David Robillard <d@drobilla.net> Sun, 08 Dec 2019 22:20:08 +0000
serd (0.30.2) stable;

6
src/reader.c

@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "reader.h"
#include "serd_internal.h"
#include <ctype.h>
@ -343,6 +344,11 @@ serd_reader_read_chunk(SerdReader* reader) @@ -343,6 +344,11 @@ serd_reader_read_chunk(SerdReader* reader)
st = serd_byte_source_advance(&reader->source);
}
if (peek_byte(reader) == 0) {
// Skip leading null byte, for reading from a null-delimited socket
eat_byte_safe(reader, 0);
}
return st ? st : read_statement(reader) ? SERD_SUCCESS : SERD_FAILURE;
}

61
tests/serd_test.c

@ -111,6 +111,64 @@ test_file_uri(const char* hostname, @@ -111,6 +111,64 @@ test_file_uri(const char* hostname,
serd_node_free(&node);
}
static void
test_read_chunks()
{
ReaderTest* const rt = (ReaderTest*)calloc(1, sizeof(ReaderTest));
FILE* const f = tmpfile();
static const char null = 0;
SerdReader* const reader =
serd_reader_new(SERD_TURTLE, rt, free, NULL, NULL, test_sink, NULL);
assert(reader);
assert(serd_reader_get_handle(reader) == rt);
assert(f);
SerdStatus st = serd_reader_start_stream(reader, f, NULL, false);
assert(st == SERD_SUCCESS);
// Write two statement separated by null characters
fprintf(f, "@prefix eg: <http://example.org/> .\n");
fprintf(f, "eg:s eg:p eg:o1 .\n");
fwrite(&null, sizeof(null), 1, f);
fprintf(f, "eg:s eg:p eg:o2 .\n");
fwrite(&null, sizeof(null), 1, f);
fseek(f, 0, SEEK_SET);
// Read prefix
st = serd_reader_read_chunk(reader);
assert(st == SERD_SUCCESS);
assert(rt->n_statements == 0);
// Read first statement
st = serd_reader_read_chunk(reader);
assert(st == SERD_SUCCESS);
assert(rt->n_statements == 1);
// Read terminator
st = serd_reader_read_chunk(reader);
assert(st == SERD_SUCCESS); // FIXME: return SERD_FAILURE?
assert(rt->n_statements == 1);
// Read second statement (after null terminator)
st = serd_reader_read_chunk(reader);
assert(st == SERD_SUCCESS);
assert(rt->n_statements == 2);
// Read terminator
st = serd_reader_read_chunk(reader);
assert(st == SERD_SUCCESS); // FIXME: return SERD_FAILURE?
assert(rt->n_statements == 2);
// EOF
st = serd_reader_read_chunk(reader);
assert(st == SERD_SUCCESS); // FIXME: return SERD_FAILURE?
assert(rt->n_statements == 2);
serd_reader_free(reader);
fclose(f);
}
int
main(void)
{
@ -490,6 +548,9 @@ main(void) @@ -490,6 +548,9 @@ main(void)
assert(!strcmp((const char*)out, "@base <http://example.org/base> .\n"));
serd_free(out);
// Test reading a series of chunks (like from a socket)
test_read_chunks();
// Rewind and test reader
fseek(fd, 0, SEEK_SET);

2
wscript

@ -12,7 +12,7 @@ from waflib.extras import autowaf @@ -12,7 +12,7 @@ from waflib.extras import autowaf
# major increment <=> incompatible changes
# minor increment <=> compatible changes (additions)
# micro increment <=> no interface changes
SERD_VERSION = '0.30.2'
SERD_VERSION = '0.30.3'
SERD_MAJOR_VERSION = '0'
# Mandatory waf variables

Loading…
Cancel
Save