gbranden pushed a commit to branch master
in repository groff.

commit e54956cc43b206eec6db24f8142396a4a64129c0
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Apr 2 11:23:50 2025 -0500

    [libgroff]: Surrender to idiom.
    
    * src/libs/libgroff/string.cpp (string::json_extract):
    * src/libs/libgroff/symbol.cpp (symbol::json_extract): Since we return a
      pointer-to-const-char, null-terminate what we hand back.  Impedance
      matching (or, more precisely, conversion) between C strings and groff
      strings is just too hard otherwise.
---
 ChangeLog                    |  8 ++++++++
 src/libs/libgroff/string.cpp | 10 ++++++----
 src/libs/libgroff/symbol.cpp | 11 ++++++-----
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dcdb1fd4c..f728adb86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-04-02  G. Branden Robinson <[email protected]>
+
+       * src/libs/libgroff/string.cpp (string::json_extract):
+       * src/libs/libgroff/symbol.cpp (symbol::json_extract): Since we
+       return a pointer-to-const-char, null-terminate what we hand
+       back.  Impedance matching (or, more precisely, conversion)
+       between C strings and groff strings is just too hard otherwise.
+
 2025-03-30  G. Branden Robinson <[email protected]>
 
        * src/roff/nroff/tests/verbose-option-works.sh: Indirect
diff --git a/src/libs/libgroff/string.cpp b/src/libs/libgroff/string.cpp
index d78b11f6d..d350d809a 100644
--- a/src/libs/libgroff/string.cpp
+++ b/src/libs/libgroff/string.cpp
@@ -359,27 +359,29 @@ size_t string::json_length() const
 }
 
 // Like `extract()`, but double-quote the string and escape characters
-// per JSON and emit nulls.  This string is not null-terminated!
+// per JSON and emit nulls.
 const char *string::json_extract() const
 {
   const char *p = ptr;
+  char *r;
   size_t n = len;
   size_t i;
-  char *q = static_cast<char *>(calloc(this->json_length(),
+  char *q = static_cast<char *>(calloc(this->json_length() + 1,
                                       sizeof (char)));
   if (q != 0 /* nullptr */) {
-    char *r = q;
+    r = q;
     *r++ = '"';
     json_char ch;
     for (i = 0; i < n; i++, p++) {
       ch = json_encode_char(*p);
       for (size_t j = 0; j < ch.len; j++)
-        *r++ = ch.buf[j];
+       *r++ = ch.buf[j];
     }
     *r++ = '"';
   }
   else
     return strdup("\"\"");
+  *r++ = '\0';
   return q;
 }
 
diff --git a/src/libs/libgroff/symbol.cpp b/src/libs/libgroff/symbol.cpp
index 511b83373..39a0787e7 100644
--- a/src/libs/libgroff/symbol.cpp
+++ b/src/libs/libgroff/symbol.cpp
@@ -199,28 +199,29 @@ size_t symbol::json_length() const
 
 // Like `extract()`, but double-quote the string and escape characters
 // per JSON.  (Unlike groff's `string`, a `symbol` doesn't contain
-// embedded null characters.)  This string is not null-terminated!
-// (The member variable backing us up _is_ a null-terminated C string.)
+// embedded null characters.)
 const char *symbol::json_extract() const
 {
   const char *p = s;
+  char *r;
   size_t n = strlen(s);
   size_t i;
-  char *q = static_cast<char *>(calloc(this->json_length(),
+  char *q = static_cast<char *>(calloc((this->json_length() + 1),
                                       sizeof (char)));
   if (q != 0 /* nullptr */) {
-    char *r = q;
+    r = q;
     *r++ = '"';
     json_char ch;
     for (i = 0; i < n; i++, p++) {
       ch = json_encode_char(*p);
       for (size_t j = 0; j < ch.len; j++)
-        *r++ = ch.buf[j];
+       *r++ = ch.buf[j];
     }
     *r++ = '"';
   }
   else
     return strdup("\"\""); // so it can be free()d
+  *r++ = '\0';
   return q;
 }
 

_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to