Skip to content

Commit

Permalink
Align checksum page error list in manifest file packs.
Browse files Browse the repository at this point in the history
This was left unaligned on purpose to save space but the sanitizer did not like it. Since this field is seldom used go ahead and align it to make the sanitizer happy.

Also add some macros to make working with alignment easier.

Found with -fsanitize=undefined.
  • Loading branch information
dwsteele committed Mar 24, 2022
1 parent 3dd7960 commit 50ee4b1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
14 changes: 14 additions & 0 deletions src/common/macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,18 @@ Adapted from PostgreSQL src/include/c.h.
((type)(expression))
#endif

/***********************************************************************************************************************************
Determine the alignment of a data type
This macro reduces to a constant so it is safe to use anywhere a constant is allowed, e.g. a switch statement case.
***********************************************************************************************************************************/
#define ALIGN_OF(type) ((size_t)&((struct {char c; type t;} *)0)->t)

/***********************************************************************************************************************************
Determine the byte offset required to align a type after an arbitrary number of bytes
This is useful for determining how to correctly align a type in a buffer that is being dynamically built up like a struct.
***********************************************************************************************************************************/
#define ALIGN_OFFSET(type, bytes) (ALIGN_OF(type) - ((bytes) % ALIGN_OF(type)))

#endif
14 changes: 8 additions & 6 deletions src/info/manifest.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,24 +315,26 @@ manifestFilePack(const Manifest *const manifest, const ManifestFile *const file)
}

// Allocate memory for the file pack
const size_t nameSize = strSize(file->name) + 1;

uint8_t *const result = memNew(
sizeof(StringPub) + strSize(file->name) + 1 + bufferPos + (file->checksumPageErrorList != NULL ?
sizeof(StringPub) + strSize(file->checksumPageErrorList) + 1 : 0));
sizeof(StringPub) + nameSize + bufferPos + (file->checksumPageErrorList != NULL ?
ALIGN_OFFSET(StringPub, nameSize + bufferPos) + sizeof(StringPub) + strSize(file->checksumPageErrorList) + 1 : 0));

// Create string object for the file name
*(StringPub *)result = (StringPub){.size = (unsigned int)strSize(file->name), .buffer = (char *)result + sizeof(StringPub)};
size_t resultPos = sizeof(StringPub);

memcpy(result + resultPos, (uint8_t *)strZ(file->name), strSize(file->name) + 1);
resultPos += strSize(file->name) + 1;
memcpy(result + resultPos, (uint8_t *)strZ(file->name), nameSize);
resultPos += nameSize;

// Copy pack data
memcpy(result + resultPos, buffer, bufferPos);

// Create string object for the checksum error list
if (file->checksumPageErrorList != NULL)
{
resultPos += bufferPos;
resultPos += bufferPos + ALIGN_OFFSET(StringPub, nameSize + bufferPos);

*(StringPub *)(result + resultPos) = (StringPub)
{.size = (unsigned int)strSize(file->checksumPageErrorList), .buffer = (char *)result + resultPos + sizeof(StringPub)};
Expand Down Expand Up @@ -414,7 +416,7 @@ manifestFileUnpack(const Manifest *const manifest, const ManifestFilePack *const
result.checksumPageError = flag & (1 << manifestFilePackFlagChecksumPageError) ? true : false;

if (flag & (1 << manifestFilePackFlagChecksumPageErrorList))
result.checksumPageErrorList = (const String *)((const uint8_t *)filePack + bufferPos);
result.checksumPageErrorList = (const String *)((const uint8_t *)filePack + bufferPos + ALIGN_OFFSET(StringPub, bufferPos));

FUNCTION_TEST_RETURN(result);
}
Expand Down

0 comments on commit 50ee4b1

Please sign in to comment.