]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
Fix sb_dupfree(), sbr_dupfree() on an empty buffer.
authorBruno Haible <bruno@clisp.org>
Thu, 17 Jul 2025 09:33:39 +0000 (11:33 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 17 Jul 2025 09:51:57 +0000 (11:51 +0200)
Reported by Marc Nieper-Wißkirchen <marc.nieper+gnu@gmail.com> at
<https://lists.gnu.org/archive/html/bug-gnulib/2025-07/msg00119.html>.

* lib/string-desc.c (_sd_new_addr, _rwsd_new_addr): Don't canonicalize
(0, non-NULL) to (0, NULL).
* lib/string-buffer.h (sb_dupfree): Fix description.
* lib/string-buffer-reversed.h (sbr_dupfree): Likewise.
* tests/test-string-buffer.c (main): Test sb_dupfree on an empty buffer.
* tests/test-string-buffer-reversed.c (main): Test sbr_dupfree on an
empty buffer.

ChangeLog
lib/string-buffer-reversed.h
lib/string-buffer.h
lib/string-desc.c
tests/test-string-buffer-reversed.c
tests/test-string-buffer.c

index 79813e051fc238db8dc45915be518fb4e509145c..b342c34550c6899cda70dffedb7eaeae6a48f3f5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2025-07-17  Bruno Haible  <bruno@clisp.org>
+
+       Fix sb_dupfree(), sbr_dupfree() on an empty buffer.
+       Reported by Marc Nieper-Wißkirchen <marc.nieper+gnu@gmail.com> at
+       <https://lists.gnu.org/archive/html/bug-gnulib/2025-07/msg00119.html>.
+       * lib/string-desc.c (_sd_new_addr, _rwsd_new_addr): Don't canonicalize
+       (0, non-NULL) to (0, NULL).
+       * lib/string-buffer.h (sb_dupfree): Fix description.
+       * lib/string-buffer-reversed.h (sbr_dupfree): Likewise.
+       * tests/test-string-buffer.c (main): Test sb_dupfree on an empty buffer.
+       * tests/test-string-buffer-reversed.c (main): Test sbr_dupfree on an
+       empty buffer.
+
 2025-07-16  Collin Funk  <collin.funk1@gmail.com>
 
        doc: Use @code around errno constants.
index 957af427b5a807249b08f32ff7b6f6efb4f48936..749e0e546b41a0ee0c8f2d46f195bfc604f82d31 100644 (file)
@@ -129,7 +129,7 @@ extern string_desc_t sbr_contents (struct string_buffer_reversed *buffer);
 extern const char * sbr_contents_c (struct string_buffer_reversed *buffer);
 
 /* Returns the contents of BUFFER and frees all other memory held by BUFFER.
-   Returns NULL upon failure or if there was an error earlier.
+   Returns (0, NULL) upon failure or if there was an error earlier.
    It is the responsibility of the caller to sd_free() the result.  */
 extern rw_string_desc_t sbr_dupfree (struct string_buffer_reversed *buffer)
   _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data);
index 99f5d40bb09cbf530472241aafbe934b1fcc2589..e87f8f6fc4afbc0fcab4f034024c2e4ac82b24e1 100644 (file)
@@ -127,7 +127,7 @@ extern string_desc_t sb_contents (struct string_buffer *buffer);
 extern const char * sb_contents_c (struct string_buffer *buffer);
 
 /* Returns the contents of BUFFER and frees all other memory held by BUFFER.
-   Returns NULL upon failure or if there was an error earlier.
+   Returns (0, NULL) upon failure or if there was an error earlier.
    It is the responsibility of the caller to sd_free() the result.  */
 extern rw_string_desc_t sb_dupfree (struct string_buffer *buffer)
   _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data);
index 7cabe4ed84c0fe398c549ab44b536f206304eddd..ba8443fe59866a40ec7209eaf13a13aa35641598 100644 (file)
@@ -154,9 +154,14 @@ _sd_new_addr (idx_t n, const char *addr)
   string_desc_t result;
 
   result._nbytes = n;
+  /* No, it is not a good idea to canonicalize (0, non-NULL) to (0, NULL).
+     Some functions that return a string_desc_t use a return value of (0, NULL)
+     to denote failure.  */
+#if 0
   if (n == 0)
     result._data = NULL;
   else
+#endif
     result._data = (char *) addr;
 
   return result;
@@ -167,9 +172,14 @@ _rwsd_new_addr (idx_t n, /*!*/const/*!*/ char *addr)
   rw_string_desc_t result;
 
   result._nbytes = n;
+  /* No, it is not a good idea to canonicalize (0, non-NULL) to (0, NULL).
+     Some functions that return a rw_string_desc_t use a return value of
+     (0, NULL) to denote failure.  */
+#if 0
   if (n == 0)
     result._data = NULL;
   else
+#endif
     result._data = (char *) addr;
 
   return result;
index 39428e6ca574eca5cb1b6dad2a8da478fb8c5efd..aeee6587f36e5206302329f2817d126bb858d44f 100644 (file)
@@ -49,6 +49,17 @@ main ()
   {
     struct string_buffer_reversed buffer;
 
+    sbr_init (&buffer);
+    rw_string_desc_t contents = sbr_dupfree (&buffer);
+    ASSERT (sd_is_empty (contents));
+    /* Here it is important to distinguish (0, NULL), which stands for an error,
+       from (0, non-NULL), which is a successful result.  */
+    ASSERT (sd_data (contents) != NULL);
+    sd_free (contents);
+  }
+  {
+    struct string_buffer_reversed buffer;
+
     sbr_init (&buffer);
     sbr_prepend1 (&buffer, '\377');
     sbr_prepend1 (&buffer, 'x');
index fa3bb82bb6de0e279504b7d27bfcef2991cdb0f2..c540aadeb9c3b296464667e3dc7928a894157479 100644 (file)
@@ -48,6 +48,17 @@ main ()
   {
     struct string_buffer buffer;
 
+    sb_init (&buffer);
+    rw_string_desc_t contents = sb_dupfree (&buffer);
+    ASSERT (sd_is_empty (contents));
+    /* Here it is important to distinguish (0, NULL), which stands for an error,
+       from (0, non-NULL), which is a successful result.  */
+    ASSERT (sd_data (contents) != NULL);
+    sd_free (contents);
+  }
+  {
+    struct string_buffer buffer;
+
     sb_init (&buffer);
     sb_append1 (&buffer, 'x');
     sb_append1 (&buffer, '\377');