Explain preconditions whenever UNSAFE_BUFFER_USAGE.
Prototype what a requirement that all UNSAFE_BUFFER_USAGE be
accompanied by a `/ PRECONDITIONS` comment would look like. Such
a requirement (as opposed to writing `// SAFETY`, say) allows
better documentation.
Bug: 415821827
Change-Id: I2456ab7fbdc9b272df834d883ab72257cc9a33d8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/131610
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/gif/lzw_decompressor.h b/core/fxcodec/gif/lzw_decompressor.h
index 50fe0f7..1d572d0 100644
--- a/core/fxcodec/gif/lzw_decompressor.h
+++ b/core/fxcodec/gif/lzw_decompressor.h
@@ -42,6 +42,8 @@
void SetSource(pdfium::span<const uint8_t> src_buf) {
avail_input_ = src_buf;
}
+
+ // PRECONDITIONS: `dest_buf` must point to memory of `*dest_size` bytes.
UNSAFE_BUFFER_USAGE Status Decode(uint8_t* dest_buf, uint32_t* dest_size);
// Used by unittests, should not be called in production code.
diff --git a/core/fxcodec/jbig2/JBig2_Image.h b/core/fxcodec/jbig2/JBig2_Image.h
index a56960c..55d7e3e 100644
--- a/core/fxcodec/jbig2/JBig2_Image.h
+++ b/core/fxcodec/jbig2/JBig2_Image.h
@@ -48,8 +48,9 @@
int GetPixel(int32_t x, int32_t y) const;
void SetPixel(int32_t x, int32_t y, int v);
- // SAFETY: propogated to caller via UNSAFE_BUFFER_USAGE.
+ // PRECONDITIONS: `y` must refer to a line within the image.
UNSAFE_BUFFER_USAGE uint8_t* GetLineUnsafe(int32_t y) const {
+ // SAFETY: propogated to caller via UNSAFE_BUFFER_USAGE.
return UNSAFE_BUFFERS(data() + y * stride_);
}
diff --git a/core/fxcrt/bytestring.h b/core/fxcrt/bytestring.h
index 3beb998..92aaf8b 100644
--- a/core/fxcrt/bytestring.h
+++ b/core/fxcrt/bytestring.h
@@ -36,6 +36,7 @@
~ByteString() = default;
+ // PRECONDITIONS: `pStr` must point to `len` valid bytes.
UNSAFE_BUFFER_USAGE ByteString(const char* pStr, size_t len);
UNSAFE_BUFFER_USAGE ByteString(const uint8_t* pStr, size_t len);
diff --git a/core/fxcrt/fixed_size_data_vector.h b/core/fxcrt/fixed_size_data_vector.h
index fd01fae..e72e88d 100644
--- a/core/fxcrt/fixed_size_data_vector.h
+++ b/core/fxcrt/fixed_size_data_vector.h
@@ -131,6 +131,7 @@
pdfium::span<const T> last(size_t count) const { return span().last(count); }
private:
+ // PRECONDITIONS: `ptr` must point to `size` consecutive T elements.
UNSAFE_BUFFER_USAGE FixedSizeDataVector(T* ptr, size_t size)
: data_(ptr), size_(size) {}
diff --git a/core/fxcrt/fx_extension.h b/core/fxcrt/fx_extension.h
index af2c932..8f5b54e 100644
--- a/core/fxcrt/fx_extension.h
+++ b/core/fxcrt/fx_extension.h
@@ -29,6 +29,7 @@
float FXSYS_wcstof(WideStringView pwsStr, size_t* pUsedLen);
+// PRECONDITIONS: `dstStr` and `srcStr` must point to `count` valid wchars.
UNSAFE_BUFFER_USAGE wchar_t* FXSYS_wcsncpy(wchar_t* dstStr,
const wchar_t* srcStr,
size_t count);
diff --git a/core/fxcrt/widestring.h b/core/fxcrt/widestring.h
index 7dc81c4..a5f203e 100644
--- a/core/fxcrt/widestring.h
+++ b/core/fxcrt/widestring.h
@@ -40,6 +40,7 @@
~WideString() = default;
+ // PRECONDITIONS: `pStr` must point to `len` valid wchars.
UNSAFE_BUFFER_USAGE WideString(const wchar_t* pStr, size_t len);
// Make a one-character string from one wide char.
diff --git a/core/fxcrt/zip.h b/core/fxcrt/zip.h
index 738030f..8a44a16 100644
--- a/core/fxcrt/zip.h
+++ b/core/fxcrt/zip.h
@@ -49,6 +49,7 @@
return lhs.first == rhs.first;
}
+ // PRECONDITIONS: Iter must not have reached end().
UNSAFE_BUFFER_USAGE Iter& operator++() {
// SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE.
UNSAFE_BUFFERS(++first);
@@ -85,6 +86,7 @@
return lhs.first == rhs.first;
}
+ // PRECONDITIONS: Iter must not have reached end().
UNSAFE_BUFFER_USAGE Iter& operator++() {
// SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE.
UNSAFE_BUFFERS(++first);
diff --git a/core/fxge/dib/fx_dib.h b/core/fxge/dib/fx_dib.h
index 6ca3062..ed6cbfd 100644
--- a/core/fxge/dib/fx_dib.h
+++ b/core/fxge/dib/fx_dib.h
@@ -211,32 +211,36 @@
((uint8_t)(argb >> 16) | ((uint8_t)(argb >> 8)) << 8 | \
((uint8_t)(argb)) << 16 | ((uint8_t)(argb >> 24) << 24))
-// SAFETY: Caller must ensure 4 valid bytes at `p`.
+// PRECONDITIONS: Caller must ensure 4 valid bytes at `p`.
UNSAFE_BUFFER_USAGE inline FX_ARGB FXARGB_GetDIB(const uint8_t* p) {
+ // SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE.
return ArgbEncode(UNSAFE_BUFFERS(p[3]), UNSAFE_BUFFERS(p[2]),
UNSAFE_BUFFERS(p[1]), UNSAFE_BUFFERS(p[0]));
}
-// SAFETY: Caller must ensure 4 valid bytes at `p`.
+// PRECONDITIONS: Caller must ensure 4 valid bytes at `p`.
UNSAFE_BUFFER_USAGE inline void FXARGB_SetDIB(uint8_t* p, uint32_t argb) {
+ // SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE.
UNSAFE_BUFFERS(p[0]) = FXARGB_B(argb);
UNSAFE_BUFFERS(p[1]) = FXARGB_G(argb);
UNSAFE_BUFFERS(p[2]) = FXARGB_R(argb);
UNSAFE_BUFFERS(p[3]) = FXARGB_A(argb);
}
-// SAFETY: Caller must ensure 4 valid bytes at `p`.
+// PRECONDITIONS: Caller must ensure 4 valid bytes at `p`.
UNSAFE_BUFFER_USAGE inline void FXARGB_SetRGBOrderDIB(uint8_t* p,
uint32_t argb) {
+ // SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE.
UNSAFE_BUFFERS(p[0]) = FXARGB_R(argb);
UNSAFE_BUFFERS(p[1]) = FXARGB_G(argb);
UNSAFE_BUFFERS(p[2]) = FXARGB_B(argb);
UNSAFE_BUFFERS(p[3]) = FXARGB_A(argb);
}
-// SAFETY: Caller must ensure 3 valid bytes at `dest` and `src`.
+// PRECONDITIONS: Caller must ensure 3 valid bytes at `dest` and `src`.
UNSAFE_BUFFER_USAGE inline void ReverseCopy3Bytes(uint8_t* dest,
const uint8_t* src) {
+ // SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE.
UNSAFE_BUFFERS(dest[2] = src[0]);
UNSAFE_BUFFERS(dest[1] = src[1]);
UNSAFE_BUFFERS(dest[0] = src[2]);
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index 90cdc96..6231757 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -274,15 +274,18 @@
CPDFSDK_InteractiveForm* FormHandleToInteractiveForm(FPDF_FORMHANDLE hHandle);
+// PRECONDITIONS: `wide_string` must be terminated by a NUL FPDF_WCHAR.
UNSAFE_BUFFER_USAGE ByteString
ByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string);
+// PRECONDITIONS: `wide_string` must be terminated by a NUL FPDF_WCHAR.
UNSAFE_BUFFER_USAGE WideString
WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string);
// Public APIs are not consistent w.r.t. the type used to represent buffer
// length, while internal code generally expects size_t. Use StrictNumeric here
// to make sure the length types fit in a size_t.
+// PRECONDITIONS: `buffer` must point to `buflen` valid bytes.
UNSAFE_BUFFER_USAGE pdfium::span<char> SpanFromFPDFApiArgs(
void* buffer,
pdfium::StrictNumeric<size_t> buflen);
diff --git a/fpdfsdk/fpdf_structtree.cpp b/fpdfsdk/fpdf_structtree.cpp
index ab37c6a..5ca81f1 100644
--- a/fpdfsdk/fpdf_structtree.cpp
+++ b/fpdfsdk/fpdf_structtree.cpp
@@ -20,6 +20,7 @@
namespace {
+// PRECONDITIONS: `buffer` must point to `buflen` valid bytes.
UNSAFE_BUFFER_USAGE unsigned long WideStringToBuffer(const WideString& str,
void* buffer,
unsigned long buflen) {