forked from lix-project/lix
Avoid calling memcpy when len == 0 in filetransfer.cc
There was a bug report about a potential call to `memcpy` with a null
pointer which is not reproducible:
lix-project/lix#492
This occurred in `src/libstore/filetransfer.cc` in `InnerSource::read`.
To ensure that this doesn't happen, an early return is added before
calling `memcpy` if the length of the data to be copied is 0.
This change also adds a test that ensures that when `InnerSource::read`
is called with an empty file, it throws an `EndOfFile` exception.
Change-Id: Ia18149bee9a3488576c864f28475a3a0c9eadfbb
This commit is contained in:
parent
ed9b7f4f84
commit
51a5025913
|
@ -6,6 +6,7 @@
|
||||||
#include "signals.hh"
|
#include "signals.hh"
|
||||||
#include "compression.hh"
|
#include "compression.hh"
|
||||||
#include "strings.hh"
|
#include "strings.hh"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#if ENABLE_S3
|
#if ENABLE_S3
|
||||||
#include <aws/core/client/ClientConfiguration.h>
|
#include <aws/core/client/ClientConfiguration.h>
|
||||||
|
@ -784,8 +785,10 @@ struct curlFileTransfer : public FileTransfer
|
||||||
|
|
||||||
size_t read(char * data, size_t len) override
|
size_t read(char * data, size_t len) override
|
||||||
{
|
{
|
||||||
auto readPartial = [this](char * data, size_t len) {
|
auto readPartial = [this](char * data, size_t len) -> size_t {
|
||||||
const auto available = std::min(len, buffered.size());
|
const auto available = std::min(len, buffered.size());
|
||||||
|
if (available == 0u) return 0u;
|
||||||
|
|
||||||
memcpy(data, buffered.data(), available);
|
memcpy(data, buffered.data(), available);
|
||||||
buffered.remove_prefix(available);
|
buffered.remove_prefix(available);
|
||||||
return available;
|
return available;
|
||||||
|
|
|
@ -150,6 +150,14 @@ TEST(FileTransfer, exceptionAbortsDownload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FileTransfer, exceptionAbortsRead)
|
||||||
|
{
|
||||||
|
auto [port, srv] = serveHTTP("200 ok", "content-length: 0\r\n", [] { return ""; });
|
||||||
|
auto ft = makeFileTransfer();
|
||||||
|
char buf[10] = "";
|
||||||
|
ASSERT_THROW(ft->download(FileTransferRequest(fmt("http://[::1]:%d/index", port)))->read(buf, 10), EndOfFile);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FileTransfer, NOT_ON_DARWIN(reportsSetupErrors))
|
TEST(FileTransfer, NOT_ON_DARWIN(reportsSetupErrors))
|
||||||
{
|
{
|
||||||
auto [port, srv] = serveHTTP("404 not found", "", [] { return ""; });
|
auto [port, srv] = serveHTTP("404 not found", "", [] { return ""; });
|
||||||
|
|
Loading…
Reference in a new issue