]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
base64: Wrap `BIO` objects in smart pointers
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 5 Feb 2026 10:41:00 +0000 (11:41 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 5 Feb 2026 10:58:08 +0000 (11:58 +0100)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/base64.cc

index 886c77d0369c9620d60112f19124e78878d55009..1ef8d2fc9844b2da00498964a09392e849a15b98 100644 (file)
@@ -24,7 +24,9 @@
 
 #include "base64.hh"
 #include <limits>
+#include <memory>
 #include <stdexcept>
+
 #include <boost/scoped_array.hpp>
 #include <openssl/bio.h>
 #include <openssl/evp.h>
@@ -42,27 +44,24 @@ int B64Decode(const std::string& src, Container& dst)
   }
   const size_t dlen = (src.length() * 6 + 7) / 8;
   dst.resize(dlen);
-  BIO* bio = BIO_new(BIO_s_mem());
-  if (bio == nullptr) {
+  auto bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_new(BIO_s_mem()), BIO_free_all);
+  if (!bio) {
     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);
+  if (BIO_write(bio.get(), src.c_str(), src.length()) != static_cast<int>(src.length())) {
     throw std::runtime_error("BIO_write failed");
   }
-  BIO* b64 = BIO_new(BIO_f_base64());
+  auto* 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);
+  bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_push(b64, bio.release()), BIO_free_all);
+  BIO_set_flags(bio.get(), BIO_FLAGS_BASE64_NO_NL);
   auto olen = BIO_read(b64, &dst.at(0), dlen);
-  if ((olen == 0 || olen == -1) && BIO_should_retry(bio)) {
-    BIO_free_all(bio);
+  if ((olen == 0 || olen == -1) && BIO_should_retry(bio.get())) {
     throw std::runtime_error("BIO_read failed to read all data from memory buffer");
   }
-  BIO_free_all(bio);
+  bio.reset();
   if (olen > 0) {
     dst.resize(olen);
     return 0;
@@ -75,30 +74,28 @@ template int B64Decode<std::string>(const std::string& strInput, std::string& st
 std::string Base64Encode(const std::string& src)
 {
   if (!src.empty()) {
-    BIO* b64 = BIO_new(BIO_f_base64());
-    if (b64 == nullptr) {
+    auto bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_new(BIO_s_mem()), BIO_free_all);
+    if (!bio) {
       throw std::runtime_error("BIO_new failed");
     }
-    BIO* bio = BIO_new(BIO_s_mem());
-    if (bio == nullptr) {
-      BIO_free_all(b64);
+    auto* b64 = BIO_new(BIO_f_base64());
+    if (b64 == nullptr) {
       throw 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());
+    bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_push(b64, bio.release()), BIO_free_all);
+    BIO_set_flags(bio.get(), BIO_FLAGS_BASE64_NO_NL);
+    int bioWriteRet = BIO_write(bio.get(), src.c_str(), src.length());
     if (bioWriteRet < 0 || static_cast<size_t>(bioWriteRet) != src.length()) {
-      BIO_free_all(bio);
       throw std::runtime_error("BIO_write failed to write all data to memory buffer");
     }
-    (void)BIO_flush(bio);
+    (void)BIO_flush(bio.get());
     char* pp;
     std::string out;
-    auto olen = BIO_get_mem_data(bio, &pp);
+    auto olen = BIO_get_mem_data(bio.get(), &pp);
     if (olen > 0) {
       out = std::string(pp, olen);
     }
-    BIO_free_all(bio);
+    bio.reset();
     return out;
   }
   return "";