diff --git a/libretroshare/src/util/rsbase64.cc b/libretroshare/src/util/rsbase64.cc index 6b856888e..f62c40cef 100644 --- a/libretroshare/src/util/rsbase64.cc +++ b/libretroshare/src/util/rsbase64.cc @@ -21,8 +21,6 @@ * * *******************************************************************************/ -#include - #include "util/rsbase64.h" #include "util/rsdebug.h" @@ -40,6 +38,12 @@ rs_view_ptr data, size_t len, std::string& outString, bool padding, bool urlSafe ) { + if(!data || !len) + { + outString.clear(); + return; + } + const char* sDict = urlSafe ? uDict : bDict; // Workaround if input and output are the same buffer. @@ -137,9 +141,11 @@ /*static*/ size_t RsBase64::encodedSize(size_t decodedSize, bool padding) { - if(padding) return 4 * (decodedSize + 2) / 3; - return static_cast( - std::ceil(4L * static_cast(decodedSize) / 3L) ); + if(!decodedSize) return 0; + + // Thanks https://stackoverflow.com/a/45401395 + if(padding) return ceilDivision(decodedSize, 3) * 4; + return ceilDivision(decodedSize * 8, 6); } /*static*/ std::tuple RsBase64::decodedSize( diff --git a/libretroshare/src/util/rsbase64.h b/libretroshare/src/util/rsbase64.h index 0715b15ae..819870089 100644 --- a/libretroshare/src/util/rsbase64.h +++ b/libretroshare/src/util/rsbase64.h @@ -137,4 +137,8 @@ private: */ static inline bool isBase64Char(char c) { return rDict[static_cast(c)] >= 0; } + + /** Perform ceil division without floating point operations */ + static inline size_t ceilDivision(size_t dividend, size_t divisor) + { return (dividend + divisor - 1) / divisor; } };