memcpy is marked as nonnull for its input, but ignores the input anyhow
if the declared length is zero. Our SHA2 implementations do this as
well, it was "just" MD5 and SHA1 missing, so we add the length check
here as well as along the callstack as it is really pointless to do all
these method calls for "nothing".
Reported-By: gcc -fsanitize=undefined
// Hashes::Add* - Add the contents of data or FD /*{{{*/
bool Hashes::Add(const unsigned char * const Data, unsigned long long const Size)
{
// Hashes::Add* - Add the contents of data or FD /*{{{*/
bool Hashes::Add(const unsigned char * const Data, unsigned long long const Size)
{
+ if (Size == 0)
+ return true;
bool Res = true;
APT_IGNORE_DEPRECATED_PUSH
if ((d->CalcHashes & MD5SUM) == MD5SUM)
bool Res = true;
APT_IGNORE_DEPRECATED_PUSH
if ((d->CalcHashes & MD5SUM) == MD5SUM)
static const int UntilEOF = 0;
static const int UntilEOF = 0;
- bool Add(const unsigned char * const Data, unsigned long long const Size);
- APT_DEPRECATED_MSG("Construct accordingly instead of choosing hashes while adding") bool Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes);
- inline bool Add(const char * const Data)
+ bool Add(const unsigned char * const Data, unsigned long long const Size) APT_NONNULL(2);
+ APT_DEPRECATED_MSG("Construct accordingly instead of choosing hashes while adding") bool Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes) APT_NONNULL(2);
+ inline bool Add(const char * const Data) APT_NONNULL(2)
{return Add((unsigned char const * const)Data,strlen(Data));};
{return Add((unsigned char const * const)Data,strlen(Data));};
- inline bool Add(const unsigned char * const Beg,const unsigned char * const End)
+ inline bool Add(const unsigned char * const Beg,const unsigned char * const End) APT_NONNULL(2,3)
{return Add(Beg,End-Beg);};
enum SupportedHashes { MD5SUM = (1 << 0), SHA1SUM = (1 << 1), SHA256SUM = (1 << 2),
{return Add(Beg,End-Beg);};
enum SupportedHashes { MD5SUM = (1 << 0), SHA1SUM = (1 << 1), SHA256SUM = (1 << 2),
class SummationImplementation
{
public:
class SummationImplementation
{
public:
- virtual bool Add(const unsigned char *inbuf, unsigned long long inlen) = 0;
- inline bool Add(const char *inbuf, unsigned long long const inlen)
+ virtual bool Add(const unsigned char *inbuf, unsigned long long inlen) APT_NONNULL(2) = 0;
+ inline bool Add(const char *inbuf, unsigned long long const inlen) APT_NONNULL(2)
{ return Add((const unsigned char *)inbuf, inlen); }
{ return Add((const unsigned char *)inbuf, inlen); }
- inline bool Add(const unsigned char *Data)
+ inline bool Add(const unsigned char *Data) APT_NONNULL(2)
{ return Add(Data, strlen((const char *)Data)); }
{ return Add(Data, strlen((const char *)Data)); }
- inline bool Add(const char *Data)
+ inline bool Add(const char *Data) APT_NONNULL(2)
{ return Add((const unsigned char *)Data, strlen(Data)); }
{ return Add((const unsigned char *)Data, strlen(Data)); }
- inline bool Add(const unsigned char *Beg, const unsigned char *End)
+ inline bool Add(const unsigned char *Beg, const unsigned char *End) APT_NONNULL(2,3)
{ return Add(Beg, End - Beg); }
{ return Add(Beg, End - Beg); }
- inline bool Add(const char *Beg, const char *End)
+ inline bool Add(const char *Beg, const char *End) APT_NONNULL(2,3)
{ return Add((const unsigned char *)Beg, End - Beg); }
bool AddFD(int Fd, unsigned long long Size = 0);
{ return Add((const unsigned char *)Beg, End - Beg); }
bool AddFD(int Fd, unsigned long long Size = 0);
{
if (Done == true)
return false;
{
if (Done == true)
return false;
+ if (len == 0)
+ return true;
uint32_t *buf = (uint32_t *)Buf;
uint32_t *bytes = (uint32_t *)Bytes;
uint32_t *buf = (uint32_t *)Buf;
uint32_t *bytes = (uint32_t *)Bytes;
- bool Add(const unsigned char *inbuf, unsigned long long inlen) APT_OVERRIDE;
+ bool Add(const unsigned char *inbuf, unsigned long long inlen) APT_OVERRIDE APT_NONNULL(2);
using SummationImplementation::Add;
MD5SumValue Result();
using SummationImplementation::Add;
MD5SumValue Result();
{
if (Done)
return false;
{
if (Done)
return false;
+ if (len == 0)
+ return true;
uint32_t *state = (uint32_t *)State;
uint32_t *count = (uint32_t *)Count;
uint32_t *state = (uint32_t *)State;
uint32_t *count = (uint32_t *)Count;
- bool Add(const unsigned char *inbuf, unsigned long long inlen) APT_OVERRIDE;
+ bool Add(const unsigned char *inbuf, unsigned long long inlen) APT_OVERRIDE APT_NONNULL(2);
using SummationImplementation::Add;
SHA1SumValue Result();
using SummationImplementation::Add;
SHA1SumValue Result();
protected:
bool Done;
public:
protected:
bool Done;
public:
- bool Add(const unsigned char *inbuf, unsigned long long len) APT_OVERRIDE = 0;
+ bool Add(const unsigned char *inbuf, unsigned long long len) APT_OVERRIDE APT_NONNULL(2) = 0;
unsigned char Sum[32];
public:
unsigned char Sum[32];
public:
- bool Add(const unsigned char *inbuf, unsigned long long len) APT_OVERRIDE
+ bool Add(const unsigned char *inbuf, unsigned long long len) APT_OVERRIDE APT_NONNULL(2)
{
if (Done)
return false;
{
if (Done)
return false;
unsigned char Sum[64];
public:
unsigned char Sum[64];
public:
- bool Add(const unsigned char *inbuf, unsigned long long len) APT_OVERRIDE
+ bool Add(const unsigned char *inbuf, unsigned long long len) APT_OVERRIDE APT_NONNULL(2)
{
if (Done)
return false;
{
if (Done)
return false;
FileChanges filechanges;
MemBlock add_text;
FileChanges filechanges;
MemBlock add_text;
- static bool retry_fwrite(char *b, size_t l, FileFd &f, Hashes * const start_hash, Hashes * const end_hash = nullptr)
+ static bool retry_fwrite(char *b, size_t l, FileFd &f, Hashes * const start_hash, Hashes * const end_hash = nullptr) APT_NONNULL(1)
{
if (f.Write(b, l) == false)
return false;
{
if (f.Write(b, l) == false)
return false;
- static void dump_mem(FileFd &o, char *p, size_t s, Hashes *hash) {
- retry_fwrite(p, s, o, hash);
+ static void dump_mem(FileFd &o, char *p, size_t s, Hashes *hash) APT_NONNULL(2) {
+ retry_fwrite(p, s, o, nullptr, hash);
for (ch = filechanges.begin(); ch != filechanges.end(); ++ch) {
dump_lines(out, in, ch->offset, start_hash, end_hash);
skip_lines(in, ch->del_cnt, start_hash);
for (ch = filechanges.begin(); ch != filechanges.end(); ++ch) {
dump_lines(out, in, ch->offset, start_hash, end_hash);
skip_lines(in, ch->del_cnt, start_hash);
- dump_mem(out, ch->add, ch->add_len, end_hash);
+ if (ch->add_len != 0)
+ dump_mem(out, ch->add, ch->add_len, end_hash);
}
dump_rest(out, in, start_hash, end_hash);
out.Flush();
}
dump_rest(out, in, start_hash, end_hash);
out.Flush();