maint: mbsalign: fix an edge case where we truncate too much
authorPádraig Brady <P@draigBrady.com>
Fri, 19 Mar 2010 21:40:05 +0000 (21:40 +0000)
committerPádraig Brady <P@draigBrady.com>
Fri, 19 Mar 2010 21:40:05 +0000 (21:40 +0000)
* gl/lib/mbsalign.c (mbsalign): Ensure the temporary destination buffer
is big enough, as it may need to be bigger than the source buffer
in the presence of single byte non printable chars.
* gl/tests/test-mbsalign.c (main): Add a test to trigger the issue.

gl/lib/mbsalign.c
gl/tests/test-mbsalign.c

index 5b55ec2d0db317b525216ecf9aebbc16b9f49257..b92fe8f7920fcdad7528ffad634c11c6a3d151eb 100644 (file)
@@ -178,6 +178,12 @@ mbsalign (const char *src, char *dest, size_t dest_size,
      then create a modified copy of it.  */
   if (wc_enabled && (conversion || (n_cols > *width)))
     {
+        if (conversion)
+          {
+             /* May have increased the size by converting
+                \t to \uFFFD for example.  */
+            src_size = wcstombs (NULL, str_wc, 0) + 1;
+          }
         newstr = malloc (src_size);
         if (newstr == NULL)
         {
index 9f8935732b2b84b87843ff41b9b3cd6754c0108d..1d894831e743a441a63d49c18c2435b128e4d5c4 100644 (file)
@@ -87,6 +87,13 @@ main (void)
       width = 4;                /* cells */
       n = mbsalign ("¹²³", dest, 0, &width, MBS_ALIGN_LEFT, 0);
       ASSERT (width == 3);
+
+      /* Test case where output is larger than input
+         (as tab converted to multi byte replacement char).  */
+      width = 4;
+      n = mbsalign ("t\tés" /* 6 including NUL */ , dest, sizeof dest,
+                    &width, MBS_ALIGN_LEFT, 0);
+      ASSERT (n == 7);
     }
 
   return 0;