diff --git a/CHANGELOG.md b/CHANGELOG.md index ec40bbc94fce46bbd18a7748b3142c8aa1fb84b4..9390e97f0ae86f405c5d4f8ddb734694f0530708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,4 +12,8 @@ - `boost::variant` has been replaced by `std::variant` and Boost is no longer needed as a dependency - If no explicit choice is made via `CMAKE_POSITION_INDEPENDENT_CODE`, the client library defaults to being built as position independent code +### Fixed + +- Pread and pwrite messages of length 0 were handled incorrectly by the server, leading to an out of bounds exception + [Unreleased]: https://gitlab.version.fz-juelich.de/SIONlib/SIONfwd/-/compare/v1.0.0...main diff --git a/src/server.cxx b/src/server.cxx index 36ebe26c36a9e0c847f2eac916f013f843e75853..b427c503b6ab27b609b86b8a6e91ad502c629768 100644 --- a/src/server.cxx +++ b/src/server.cxx @@ -362,7 +362,7 @@ struct CommunicatorReceiver { std::vector<char> buf = (args.nbyte() > 0) ? communicator_.receive_data(args.nbyte()) : std::vector<char>{}; ssize_t written = 0; while (true) { - ssize_t k = pwrite(args.fd(), &buf.at(written), args.nbyte() - written, args.offset() + written); + ssize_t k = pwrite(args.fd(), (args.nbyte() > 0) ? &buf.at(written) : nullptr, args.nbyte() - written, args.offset() + written); if (k == -1) { if (errno != EINTR) { written = -1; @@ -385,7 +385,7 @@ struct CommunicatorReceiver { std::vector<char> buf(args.nbyte()); ssize_t read = 0; while (true) { - ssize_t k = pread(args.fd(), &buf.at(read), args.nbyte() - read, args.offset() + read); + ssize_t k = pread(args.fd(), (args.nbyte() > 0) ? &buf.at(read) : nullptr, args.nbyte() - read, args.offset() + read); if (k == -1) { if (errno != EINTR) { read = -1; diff --git a/src/test-client.c b/src/test-client.c index bc06e52959351ad4eb38a79618e5fddc7860f34c..d62b2bb5e061d48390558a28fc0ae8b3fc8e0bb8 100644 --- a/src/test-client.c +++ b/src/test-client.c @@ -26,6 +26,10 @@ int main(int argc, char *argv[]) { fprintf(stderr, "wrote %" PRId64 " bytes to %d\n", written, fd); assert(written == strlen(wbuf)); + written = sionfwd_pwrite(fd, wbuf, 0, 0); + fprintf(stderr, "wrote %" PRId64 " bytes to %d\n", written, fd); + assert(written == 0); + int status = sionfwd_flush(fd); fprintf(stderr, "flushed file descriptor %d\n", fd); assert(status == 0); @@ -51,6 +55,10 @@ int main(int argc, char *argv[]) { assert(read == strlen(wbuf)); assert(strcmp(wbuf, rbuf) == 0); + read = sionfwd_pread(fd, rbuf, 0, 0); + fprintf(stderr, "read %" PRId64 " bytes from %d\n", read, fd); + assert(read == 0); + status = sionfwd_close(fd); fprintf(stderr, "closed file descriptor %d with status %d\n", fd, status); assert(status == 0);