The length parameters in mbstowcs and wcstombs are limits on the
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 21 Jun 2007 14:10:01 +0000 (14:10 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 21 Jun 2007 14:10:01 +0000 (14:10 +0000)
_output_ length, not the input length. Adjust accordingly.

This has the side effect of working around what I believe to be a
bug in DJGPP's mbstowcs(), namely that if you give it a string which
exactly fits in the output length _without_ the trailing NUL, then
it will write n-1 characters of the string plus a NUL where I
believe it should write n characters of the string and no NUL.

git-svn-id: svn://svn.tartarus.org/sgt/halibut@7622 cda61777-01e9-0310-a592-d414129be87e

ustring.c

index 95477a5..3d18a4f 100644 (file)
--- a/ustring.c
+++ b/ustring.c
@@ -172,17 +172,18 @@ char *utoa_locale_dup(wchar_t const *s)
      * This variant uses the C library locale.
      */
     char *ret;
-    int len;
+    int len, outlen;
     size_t siz;
 
     len = ustrlen(s);
 
-    ret = snewn(1 + MB_CUR_MAX * len, char);
+    outlen = 1 + MB_CUR_MAX * len;
+    ret = snewn(outlen+1, char);
 
-    siz = wcstombs(ret, s, len);
+    siz = wcstombs(ret, s, outlen);
 
     if (siz) {
-       assert(siz <= (size_t)(MB_CUR_MAX * len));
+       assert(siz <= (size_t)(outlen));
        ret[siz] = '\0';
        ret = sresize(ret, siz+1, char);
        return ret;
@@ -203,17 +204,18 @@ wchar_t *ufroma_locale_dup(char const *s)
      * This variant uses the C library locale.
      */
     wchar_t *ret;
-    int len;
+    int len, outlen;
     size_t siz;
 
     len = strlen(s);
 
-    ret = snewn(1 + 2*len, wchar_t);  /* be conservative */
+    outlen = 1 + 2*len;
+    ret = snewn(outlen+1, wchar_t);  /* be conservative */
 
-    siz = mbstowcs(ret, s, len);
+    siz = mbstowcs(ret, s, outlen);
 
     if (siz) {
-       assert(siz <= (size_t)(2 * len));
+       assert(siz <= (size_t)(outlen));
        ret[siz] = L'\0';
        ret = sresize(ret, siz+1, wchar_t);
        return ret;