]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
More (allocation) error checking fix a type
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 4 Feb 2026 10:51:35 +0000 (11:51 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 4 Feb 2026 12:53:54 +0000 (13:53 +0100)
Signed-off-by: Otto Moerbeek <otto.moerbeek@open-xchange.com>
pdns/base64.cc
pdns/base64.hh

index 06093857973037896311ef90275f809958d3147b..5eb10a70c1ae9207340df4a286a58a7dcdf03d3e 100644 (file)
  * 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");
@@ -61,10 +74,15 @@ template int B64Decode<std::string>(const std::string& strInput, std::string& st
 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());
@@ -75,7 +93,7 @@ std::string Base64Encode(const std::string& src)
     (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);
     }
index f07814bf1b9306d015cc3e2fa0ea2dbb066b253d..eaf3e0a070716ad85ef8435510863b3ea77392ba 100644 (file)
@@ -22,5 +22,5 @@
 #pragma once
 #include <string>
 
-template<typename Container> int B64Decode(const std::string& strInput, Container& strOutput);
-std::string Base64Encode (const std::string& src);
+template <typename Container> int B64Decode(const std::string& strInput, Container& strOutput);
+std::string Base64Encode(const std::string& src);