Awesome sauce, read description below for details.
authorArt Cancro <ajc@citadel.org>
Mon, 5 Feb 2024 22:46:34 +0000 (17:46 -0500)
committerArt Cancro <ajc@citadel.org>
Mon, 5 Feb 2024 22:46:34 +0000 (17:46 -0500)
commit9f197d0b63b09d6cc295051016a5b549a65e8588
tree97d1f0268e99ff879c9cb746f648821f692f320c
parentc552978c0ea0ab081a32d7c29ba62d4c0e8aad60
Awesome sauce, read description below for details.

My 'ctdlload' operation kept failing because there were a few user
records dumped that had insane data in them.  CtdlDecodeBase64() was
silently doing buffer overruns because it doesn't know the size of
the target buffer.

While noodling a workaround, I realized that you can pass the same
pointer to CtdlDecodeBase64() as both the source *and* target buffer.
This works because the decoded data pointer will ALWAYS be behind the
encoded data pointer.  This allows a "decode-in-place" operation!

By performing a decode-in-place and then using safestrncpy() to copy
the results to the finitely-sized string buffer in the target struct,
we guarantee no buffer overruns.  Valgrind no longer bitches about it
and the program does not crash.
citadel/utils/ctdldump.c
citadel/utils/ctdlload.c
libcitadel/lib/base64.c
libcitadel/lib/libcitadel.h
libcitadel/lib/tools.c