Convert fx_random.cpp to use safe types
Simpler to make this conversion than to justify 10 or so uses of
unsafe buffers.
-- beef up test for one caller thru this entire codepath.
Change-Id: If8f5e93ee4f307f28735dcc7129fd496706930a4
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/116554
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index 175fd9d..fd68d79 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -22,6 +22,7 @@
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_random.h"
+#include "core/fxcrt/span_util.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"
#include "third_party/base/notreached.h"
@@ -555,7 +556,7 @@
if (m_Revision >= 5) {
uint32_t random[4];
- FX_Random_GenerateMT(random, std::size(random));
+ FX_Random_GenerateMT(random);
CRYPT_sha2_context sha;
CRYPT_SHA256Start(&sha);
CRYPT_SHA256Update(&sha, reinterpret_cast<uint8_t*>(random),
@@ -655,8 +656,8 @@
// In ISO 32000 Supplement for ExtensionLevel 3, Algorithm 3.10 says bytes 12
// to 15 should be random data.
- uint32_t* buf_random = reinterpret_cast<uint32_t*>(&buf[12]);
- FX_Random_GenerateMT(buf_random, 1);
+ auto random_span = pdfium::make_span(buf).subspan(12, 4);
+ FX_Random_GenerateMT(fxcrt::reinterpret_span<uint32_t>(random_span));
CRYPT_aes_context aes = {};
CRYPT_AESSetKey(&aes, m_EncryptKey, sizeof(m_EncryptKey));
diff --git a/core/fxcrt/fx_random.cpp b/core/fxcrt/fx_random.cpp
index 8a8182d..26a0596 100644
--- a/core/fxcrt/fx_random.cpp
+++ b/core/fxcrt/fx_random.cpp
@@ -6,6 +6,8 @@
#include "core/fxcrt/fx_random.h"
+#include <array>
+
#include "build/build_config.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_string.h"
@@ -28,7 +30,7 @@
struct MTContext {
uint32_t mti;
- uint32_t mt[MT_N];
+ std::array<uint32_t, MT_N> mt;
};
bool g_bHaveGlobalSeed = false;
@@ -84,35 +86,34 @@
void* FX_Random_MT_Start(uint32_t dwSeed) {
MTContext* pContext = FX_Alloc(MTContext, 1);
- uint32_t* pBuf = pContext->mt;
- pBuf[0] = dwSeed;
- for (uint32_t i = 1; i < MT_N; i++)
- pBuf[i] = (1812433253UL * (pBuf[i - 1] ^ (pBuf[i - 1] >> 30)) + i);
-
+ pContext->mt[0] = dwSeed;
+ for (uint32_t i = 1; i < MT_N; i++) {
+ const uint32_t prev = pContext->mt[i - 1];
+ pContext->mt[i] = (1812433253UL * (prev ^ (prev >> 30)) + i);
+ }
pContext->mti = MT_N;
return pContext;
}
uint32_t FX_Random_MT_Generate(void* pContext) {
MTContext* pMTC = static_cast<MTContext*>(pContext);
- uint32_t* pBuf = pMTC->mt;
uint32_t v;
if (pMTC->mti >= MT_N) {
- static const uint32_t mag[2] = {0, MT_Matrix_A};
+ static constexpr std::array<uint32_t, 2> mag = {{0, MT_Matrix_A}};
uint32_t kk;
for (kk = 0; kk < MT_N - MT_M; kk++) {
- v = (pBuf[kk] & MT_Upper_Mask) | (pBuf[kk + 1] & MT_Lower_Mask);
- pBuf[kk] = pBuf[kk + MT_M] ^ (v >> 1) ^ mag[v & 1];
+ v = (pMTC->mt[kk] & MT_Upper_Mask) | (pMTC->mt[kk + 1] & MT_Lower_Mask);
+ pMTC->mt[kk] = pMTC->mt[kk + MT_M] ^ (v >> 1) ^ mag[v & 1];
}
for (; kk < MT_N - 1; kk++) {
- v = (pBuf[kk] & MT_Upper_Mask) | (pBuf[kk + 1] & MT_Lower_Mask);
- pBuf[kk] = pBuf[kk + (MT_M - MT_N)] ^ (v >> 1) ^ mag[v & 1];
+ v = (pMTC->mt[kk] & MT_Upper_Mask) | (pMTC->mt[kk + 1] & MT_Lower_Mask);
+ pMTC->mt[kk] = pMTC->mt[kk + (MT_M - MT_N)] ^ (v >> 1) ^ mag[v & 1];
}
- v = (pBuf[MT_N - 1] & MT_Upper_Mask) | (pBuf[0] & MT_Lower_Mask);
- pBuf[MT_N - 1] = pBuf[MT_M - 1] ^ (v >> 1) ^ mag[v & 1];
+ v = (pMTC->mt[MT_N - 1] & MT_Upper_Mask) | (pMTC->mt[0] & MT_Lower_Mask);
+ pMTC->mt[MT_N - 1] = pMTC->mt[MT_M - 1] ^ (v >> 1) ^ mag[v & 1];
pMTC->mti = 0;
}
- v = pBuf[pMTC->mti++];
+ v = pMTC->mt[pMTC->mti++];
v ^= (v >> 11);
v ^= (v << 7) & 0x9d2c5680UL;
v ^= (v << 15) & 0xefc60000UL;
@@ -124,10 +125,10 @@
FX_Free(pContext);
}
-void FX_Random_GenerateMT(uint32_t* pBuffer, int32_t iCount) {
+void FX_Random_GenerateMT(pdfium::span<uint32_t> pBuffer) {
void* pContext = ContextFromNextGlobalSeed();
- while (iCount-- > 0)
- *pBuffer++ = FX_Random_MT_Generate(pContext);
-
+ for (size_t i = 0; i < pBuffer.size(); ++i) {
+ pBuffer[i] = FX_Random_MT_Generate(pContext);
+ }
FX_Random_MT_Close(pContext);
}
diff --git a/core/fxcrt/fx_random.h b/core/fxcrt/fx_random.h
index c6cbd5e..635e8cc 100644
--- a/core/fxcrt/fx_random.h
+++ b/core/fxcrt/fx_random.h
@@ -9,10 +9,12 @@
#include <stdint.h>
+#include "third_party/base/containers/span.h"
+
void* FX_Random_MT_Start(uint32_t dwSeed);
void FX_Random_MT_Close(void* pContext);
uint32_t FX_Random_MT_Generate(void* pContext);
-void FX_Random_GenerateMT(uint32_t* pBuffer, int32_t iCount);
+void FX_Random_GenerateMT(pdfium::span<uint32_t> pBuffer);
#endif // CORE_FXCRT_FX_RANDOM_H_
diff --git a/core/fxcrt/fx_random_unittest.cpp b/core/fxcrt/fx_random_unittest.cpp
index 1361e24..0c6b9b0 100644
--- a/core/fxcrt/fx_random_unittest.cpp
+++ b/core/fxcrt/fx_random_unittest.cpp
@@ -18,7 +18,7 @@
std::set<std::array<uint32_t, 16>> seen;
std::array<uint32_t, 16> current;
for (int i = 0; i < 3600; ++i) {
- FX_Random_GenerateMT(current.data(), 16);
+ FX_Random_GenerateMT(current);
EXPECT_TRUE(seen.insert(current).second);
}
}
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index b591122..6dc2975 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -24,6 +24,7 @@
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_random.h"
#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/span_util.h"
#include "core/fxcrt/widetext_buffer.h"
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_class.h"
@@ -492,7 +493,8 @@
ByteString GUIDString(bool bSeparator) {
uint8_t data[16];
- FX_Random_GenerateMT(reinterpret_cast<uint32_t*>(data), 4);
+ auto random_span = pdfium::make_span(data);
+ FX_Random_GenerateMT(fxcrt::reinterpret_span<uint32_t>(random_span));
data[6] = (data[6] & 0x0F) | 0x40;
ByteString bsGUID;
diff --git a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
index 602a744..89f651f 100644
--- a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
@@ -4,6 +4,9 @@
#include <math.h>
+#include <algorithm>
+
+#include "core/fxcrt/fx_extension.h"
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_isolatetracker.h"
@@ -913,7 +916,12 @@
CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
v8::Local<v8::Value> value = GetValue();
- EXPECT_TRUE(fxv8::IsString(value));
+ ASSERT_TRUE(fxv8::IsString(value));
+ ByteString bstr = fxv8::ToByteString(isolate(), value.As<v8::String>());
+ EXPECT_EQ(bstr.GetLength(), 32u);
+ EXPECT_TRUE(std::all_of(bstr.begin(), bstr.end(), FXSYS_IsHexDigit));
+ EXPECT_TRUE(
+ std::any_of(bstr.begin(), bstr.end(), [](char c) { return c != '0'; }));
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Upper) {