[libc-commits] [libc] [libc] Fix off by one in long double buffer size (PR #80889)

via libc-commits libc-commits at lists.llvm.org
Tue Feb 6 10:28:54 PST 2024


https://github.com/michaelrj-google created https://github.com/llvm/llvm-project/pull/80889

The size for the long double BLOCK_BUFFER_LEN is calculated based on the
properties of the long double type. Somewhere in the calculation, the
result was mis-rounded so that the buffer was one element too small.
This patch fixes the issue and adds asserts to catch it sooner in the
future.


>From d8068a924ba03c68918fd29501b43e7adba5f0b6 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Tue, 6 Feb 2024 10:25:14 -0800
Subject: [PATCH] [libc] Fix off by one in long double buffer size

The size for the long double BLOCK_BUFFER_LEN is calculated based on the
properties of the long double type. Somewhere in the calculation, the
result was mis-rounded so that the buffer was one element too small.
This patch fixes the issue and adds asserts to catch it sooner in the
future.
---
 libc/src/__support/float_to_string.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/float_to_string.h b/libc/src/__support/float_to_string.h
index 1431aeffa5b210..f30110d47b2192 100644
--- a/libc/src/__support/float_to_string.h
+++ b/libc/src/__support/float_to_string.h
@@ -651,7 +651,8 @@ template <> class FloatToString<long double> {
   int int_block_index = 0;
 
   static constexpr size_t BLOCK_BUFFER_LEN =
-      internal::div_ceil(internal::log10_pow2(FLOAT_AS_INT_WIDTH), BLOCK_SIZE);
+      internal::div_ceil(internal::log10_pow2(FLOAT_AS_INT_WIDTH), BLOCK_SIZE) +
+      1;
   BlockInt block_buffer[BLOCK_BUFFER_LEN] = {0};
   size_t block_buffer_valid = 0;
 
@@ -693,6 +694,7 @@ template <> class FloatToString<long double> {
       int_block_index = 0;
 
       while (float_as_int > 0) {
+        LIBC_ASSERT(int_block_index < static_cast<int>(BLOCK_BUFFER_LEN));
         block_buffer[int_block_index] = grab_digits(float_as_int);
         ++int_block_index;
       }
@@ -785,6 +787,8 @@ template <> class FloatToString<long double> {
     if (block_index > static_cast<int>(block_buffer_valid) || block_index < 0)
       return 0;
 
+    LIBC_ASSERT(block_index < static_cast<int>(BLOCK_BUFFER_LEN));
+
     return block_buffer[block_index];
   }
 



More information about the libc-commits mailing list