Return DataVector directly from CPDF_CryptoHandler::EncryptContent()

Instead of making the EncryptContent() caller create the DataVector and
then passing it in as a span, move that work into EncryptContent()
itself. As a result, CPDF_CryptoHandler::EncryptGetSize() can become a
private method.

Also remove a conditional that always evaluates to true.

Change-Id: I24b48df1c6efe475ce80ed3c9c7512ee05ca5d35
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121118
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.cpp b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
index ea28bc2..70d4466 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -47,13 +47,15 @@
   return type_obj && type_obj->GetString() == pdfium::form_fields::kSig;
 }
 
-size_t CPDF_CryptoHandler::EncryptContent(uint32_t objnum,
-                                          uint32_t gennum,
-                                          pdfium::span<const uint8_t> source,
-                                          pdfium::span<uint8_t> dest) const {
+DataVector<uint8_t> CPDF_CryptoHandler::EncryptContent(
+    uint32_t objnum,
+    uint32_t gennum,
+    pdfium::span<const uint8_t> source) const {
+  DataVector<uint8_t> dest(EncryptGetSize(source));
   if (m_Cipher == Cipher::kNone) {
     fxcrt::Copy(source, dest);
-    return source.size();
+    dest.resize(source.size());
+    return dest;
   }
   uint8_t realkey[16];
   size_t realkeylen = sizeof(realkey);
@@ -76,24 +78,24 @@
       v = (uint8_t)rand();
     }
     CRYPT_AESSetIV(m_pAESContext.get(), iv);
-    fxcrt::Copy(iv, dest);
+    auto dest_span = pdfium::make_span(dest);
+    fxcrt::Copy(iv, dest_span);
     int nblocks = source.size() / 16;
-    CRYPT_AESEncrypt(m_pAESContext.get(), dest.subspan(16).data(),
+    CRYPT_AESEncrypt(m_pAESContext.get(), dest_span.subspan(16).data(),
                      source.data(), nblocks * 16);
     uint8_t padding[16];
     fxcrt::Copy(source.subspan(nblocks * 16, source.size() % 16), padding);
     fxcrt::Fill(pdfium::make_span(padding).subspan(source.size() % 16),
                 16 - source.size() % 16);
     CRYPT_AESEncrypt(m_pAESContext.get(),
-                     dest.subspan(nblocks * 16 + 16).data(), padding, 16);
-    return 32 + nblocks * 16;
+                     dest_span.subspan(nblocks * 16 + 16).data(), padding, 16);
+    dest.resize(32 + nblocks * 16);
+    return dest;
   }
-  DCHECK_EQ(dest.size(), source.size());
-  if (dest.data() != source.data()) {
-    fxcrt::Copy(source, dest);
-  }
+  CHECK_EQ(dest.size(), source.size());
+  fxcrt::Copy(source, dest);
   CRYPT_ArcFourCryptBlock(dest, pdfium::make_span(realkey).first(realkeylen));
-  return dest.size();
+  return dest;
 }
 
 struct AESCryptContext {
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.h b/core/fpdfapi/parser/cpdf_crypto_handler.h
index 0bddb1d..aef533d 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.h
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.h
@@ -16,6 +16,7 @@
 #include "core/fdrm/fx_crypt.h"
 #include "core/fxcrt/binary_buffer.h"
 #include "core/fxcrt/bytestring.h"
+#include "core/fxcrt/data_vector.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/span.h"
@@ -38,17 +39,15 @@
   ~CPDF_CryptoHandler();
 
   bool DecryptObjectTree(RetainPtr<CPDF_Object> object);
-  size_t EncryptGetSize(pdfium::span<const uint8_t> source) const;
 
-  // Returns number of valid bytes in `dest`.
-  [[nodiscard]] size_t EncryptContent(uint32_t objnum,
-                                      uint32_t gennum,
-                                      pdfium::span<const uint8_t> source,
-                                      pdfium::span<uint8_t> dest) const;
+  DataVector<uint8_t> EncryptContent(uint32_t objnum,
+                                     uint32_t gennum,
+                                     pdfium::span<const uint8_t> source) const;
 
   bool IsCipherAES() const;
 
  private:
+  size_t EncryptGetSize(pdfium::span<const uint8_t> source) const;
   size_t DecryptGetSize(size_t src_size);
   void* DecryptStart(uint32_t objnum, uint32_t gennum);
   ByteString Decrypt(uint32_t objnum, uint32_t gennum, const ByteString& str);
diff --git a/core/fpdfapi/parser/cpdf_encryptor.cpp b/core/fpdfapi/parser/cpdf_encryptor.cpp
index 30e611f..dd1c555 100644
--- a/core/fpdfapi/parser/cpdf_encryptor.cpp
+++ b/core/fpdfapi/parser/cpdf_encryptor.cpp
@@ -22,11 +22,7 @@
   if (src_data.empty()) {
     return DataVector<uint8_t>();
   }
-  size_t estimated = m_pHandler->EncryptGetSize(src_data);
-  DataVector<uint8_t> result(estimated);
-  size_t actual = m_pHandler->EncryptContent(m_ObjNum, 0, src_data, result);
-  result.resize(actual);
-  return result;
+  return m_pHandler->EncryptContent(m_ObjNum, 0, src_data);
 }
 
 CPDF_Encryptor::~CPDF_Encryptor() = default;