Namespace CertCompressionAlg and use more scopers.

Change-Id: I52ab2dbf92bbdbc8cb0dd811bf9eaafe0c903b66
Reviewed-on: https://boringssl-review.googlesource.com/29808
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/include/openssl/stack.h b/include/openssl/stack.h
index 6975db6..a1cca59 100644
--- a/include/openssl/stack.h
+++ b/include/openssl/stack.h
@@ -354,11 +354,15 @@
                                           (void (*)(void *))free_func);        \
   }
 
+// DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements
+// are |type| *.
+#define DEFINE_NAMED_STACK_OF(name, type)                    \
+  BORINGSSL_DEFINE_STACK_OF_IMPL(name, type *, const type *) \
+  BORINGSSL_DEFINE_STACK_TRAITS(name, type, false)
+
 // DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are
 // |type| *.
-#define DEFINE_STACK_OF(type)                                \
-  BORINGSSL_DEFINE_STACK_OF_IMPL(type, type *, const type *) \
-  BORINGSSL_DEFINE_STACK_TRAITS(type, type, false)
+#define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type)
 
 // DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements
 // are const |type| *.
diff --git a/ssl/internal.h b/ssl/internal.h
index 14daeff..dc78f1b 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1998,17 +1998,19 @@
   uint64_t next_rotation_tv_sec = 0;
 };
 
+struct CertCompressionAlg {
+  static constexpr bool kAllowUniquePtr = true;
+
+  ssl_cert_compression_func_t compress = nullptr;
+  ssl_cert_decompression_func_t decompress = nullptr;
+  uint16_t alg_id = 0;
+};
+
 }  // namespace bssl
 
 DECLARE_LHASH_OF(SSL_SESSION)
 
-struct CertCompressionAlg {
-  ssl_cert_compression_func_t compress;
-  ssl_cert_decompression_func_t decompress;
-  uint16_t alg_id;
-};
-
-DEFINE_STACK_OF(CertCompressionAlg);
+DEFINE_NAMED_STACK_OF(CertCompressionAlg, bssl::CertCompressionAlg);
 
 namespace bssl {
 
@@ -2960,7 +2962,7 @@
   bssl::UniquePtr<STACK_OF(SRTP_PROTECTION_PROFILE)> srtp_profiles;
 
   // Defined compression algorithms for certificates.
-  STACK_OF(CertCompressionAlg) *cert_compression_algs = nullptr;
+  bssl::UniquePtr<STACK_OF(CertCompressionAlg)> cert_compression_algs;
 
   // Supported group values inherited by SSL structure
   bssl::Array<uint16_t> supported_group_list;
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index c96307d..388f661 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -563,8 +563,6 @@
   CRYPTO_MUTEX_cleanup(&lock);
   lh_SSL_SESSION_free(sessions);
   x509_method->ssl_ctx_free(this);
-  sk_CertCompressionAlg_pop_free(cert_compression_algs,
-                                 Delete<CertCompressionAlg>);
 }
 
 SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
@@ -2034,44 +2032,36 @@
                                      ssl_cert_decompression_func_t decompress) {
   assert(compress != nullptr || decompress != nullptr);
 
-  for (CertCompressionAlg *alg : ctx->cert_compression_algs) {
+  for (const auto *alg : ctx->cert_compression_algs.get()) {
     if (alg->alg_id == alg_id) {
       return 0;
     }
   }
 
-  CertCompressionAlg *alg = reinterpret_cast<CertCompressionAlg *>(
-      OPENSSL_malloc(sizeof(CertCompressionAlg)));
+  UniquePtr<CertCompressionAlg> alg = MakeUnique<CertCompressionAlg>();
   if (alg == nullptr) {
-    goto err;
+    return 0;
   }
 
-  OPENSSL_memset(alg, 0, sizeof(CertCompressionAlg));
   alg->alg_id = alg_id;
   alg->compress = compress;
   alg->decompress = decompress;
 
   if (ctx->cert_compression_algs == nullptr) {
-    ctx->cert_compression_algs = sk_CertCompressionAlg_new_null();
+    ctx->cert_compression_algs.reset(sk_CertCompressionAlg_new_null());
     if (ctx->cert_compression_algs == nullptr) {
-      goto err;
+      return 0;
     }
   }
 
-  if (!sk_CertCompressionAlg_push(ctx->cert_compression_algs, alg)) {
-    goto err;
+  if (!PushToStack(ctx->cert_compression_algs.get(), std::move(alg))) {
+    if (sk_CertCompressionAlg_num(ctx->cert_compression_algs.get()) == 0) {
+      ctx->cert_compression_algs.reset();
+      return 0;
+    }
   }
 
   return 1;
-
-err:
-  OPENSSL_free(alg);
-  if (ctx->cert_compression_algs != nullptr &&
-      sk_CertCompressionAlg_num(ctx->cert_compression_algs) == 0) {
-    sk_CertCompressionAlg_free(ctx->cert_compression_algs);
-    ctx->cert_compression_algs = nullptr;
-  }
-  return 0;
 }
 
 void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, int enabled) {
diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc
index cfb4cef..2e06129 100644
--- a/ssl/t1_lib.cc
+++ b/ssl/t1_lib.cc
@@ -2743,7 +2743,7 @@
   bool first = true;
   CBB contents, algs;
 
-  for (const auto& alg : hs->ssl->ctx->cert_compression_algs) {
+  for (const auto *alg : hs->ssl->ctx->cert_compression_algs.get()) {
     if (alg->decompress == nullptr) {
       continue;
     }
@@ -2782,7 +2782,7 @@
   }
 
   const size_t num_algs =
-      sk_CertCompressionAlg_num(hs->ssl->ctx->cert_compression_algs);
+      sk_CertCompressionAlg_num(hs->ssl->ctx->cert_compression_algs.get());
 
   CBS alg_ids;
   if (!CBS_get_u8_length_prefixed(contents, &alg_ids) ||
@@ -2810,8 +2810,8 @@
     given_alg_ids[given_alg_idx++] = alg_id;
 
     for (size_t i = 0; i < num_algs; i++) {
-      const auto *alg =
-          sk_CertCompressionAlg_value(hs->ssl->ctx->cert_compression_algs, i);
+      const auto *alg = sk_CertCompressionAlg_value(
+          hs->ssl->ctx->cert_compression_algs.get(), i);
       if (alg->alg_id == alg_id && alg->compress != nullptr) {
         if (i < best_index) {
           best_index = i;
@@ -2833,8 +2833,9 @@
       ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
     hs->cert_compression_negotiated = true;
     hs->cert_compression_alg_id =
-        sk_CertCompressionAlg_value(hs->ssl->ctx->cert_compression_algs,
-                                    best_index)->alg_id;
+        sk_CertCompressionAlg_value(hs->ssl->ctx->cert_compression_algs.get(),
+                                    best_index)
+            ->alg_id;
   }
 
   return true;
diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc
index b9f5163..d6ebb4c 100644
--- a/ssl/tls13_both.cc
+++ b/ssl/tls13_both.cc
@@ -131,7 +131,7 @@
     }
 
     ssl_cert_decompression_func_t decompress = nullptr;
-    for (const auto& alg : ssl->ctx->cert_compression_algs) {
+    for (const auto* alg : ssl->ctx->cert_compression_algs.get()) {
       if (alg->alg_id == alg_id) {
         decompress = alg->decompress;
         break;
@@ -505,7 +505,7 @@
   }
 
   const CertCompressionAlg *alg = nullptr;
-  for (CertCompressionAlg *candidate : ssl->ctx->cert_compression_algs) {
+  for (const auto *candidate : ssl->ctx->cert_compression_algs.get()) {
     if (candidate->alg_id == hs->cert_compression_alg_id) {
       alg = candidate;
       break;