* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifdef HAVE_CONFIG_H
+
#include "config.h"
-#endif
+
#include "base64.hh"
#include <stdexcept>
#include <boost/scoped_array.hpp>
#include <openssl/bio.h>
#include <openssl/evp.h>
-template<typename Container> int B64Decode(const std::string& src, Container& dst)
+
+template <typename Container> int B64Decode(const std::string& src, Container& dst)
{
if (src.empty() ) {
dst.clear();
return 0;
}
- int dlen = ( src.length() * 6 + 7 ) / 8 ;
- ssize_t olen = 0;
+ // check if the dlen computation might overflow or it does not fit into an int (for IO_write)
+ if (src.length() > std::numeric_limits<size_t>::max() / 7 || src.length() > std::numeric_limits<int>::max()) {
+ throw std::runtime_error("B64Decode too large");
+ }
+ const size_t dlen = (src.length() * 6 + 7) / 8 ;
dst.resize(dlen);
- BIO *bio, *b64;
- bio = BIO_new(BIO_s_mem());
- BIO_write(bio, src.c_str(), src.length());
- b64 = BIO_new(BIO_f_base64());
+ BIO* bio = BIO_new(BIO_s_mem());
+ if (bio == nullptr) {
+ throw std::runtime_error("BIO_new failed");
+ }
+ if (BIO_write(bio, src.c_str(), src.length()) != static_cast<int>(src.length())) {
+ BIO_free_all(bio);
+ throw std::runtime_error("BIO_write failed");
+ }
+ BIO* b64 = BIO_new(BIO_f_base64());
+ if (b64 == nullptr) {
+ BIO_free_all(bio);
+ throw std::runtime_error("BIO_new failed");
+ }
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
- olen = BIO_read(b64, &dst.at(0), dlen);
+ ssize_t olen = BIO_read(b64, &dst.at(0), dlen);
if ((olen == 0 || olen == -1) && BIO_should_retry(bio)) {
BIO_free_all(bio);
throw std::runtime_error("BIO_read failed to read all data from memory buffer");
std::string Base64Encode(const std::string& src)
{
if (!src.empty()) {
- size_t olen = 0;
- BIO *bio, *b64;
- b64 = BIO_new(BIO_f_base64());
- bio = BIO_new(BIO_s_mem());
+ BIO* b64 = BIO_new(BIO_f_base64());
+ if (b64 == nullptr) {
+ throw std::runtime_error("BIO_new failed");
+ }
+ BIO* bio = BIO_new(BIO_s_mem());
+ if (bio == nullptr) {
+ BIO_free_all(b64);
+ std::runtime_error("BIO_new failed");
+ }
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
int bioWriteRet = BIO_write(bio, src.c_str(), src.length());
(void)BIO_flush(bio);
char* pp;
std::string out;
- olen = BIO_get_mem_data(bio, &pp);
+ size_t olen = BIO_get_mem_data(bio, &pp);
if (olen > 0) {
out = std::string(pp, olen);
}