Re: libedit wchar allocation issue

2011-11-17 Thread Nicholas Marriott
Sure, looks good, I'll use your version.


On Wed, Nov 16, 2011 at 02:00:51PM +0100, Stefan Sperling wrote:
 On Tue, Nov 15, 2011 at 11:09:08PM +, Nicholas Marriott wrote:
  Hi
  
  libedit miscalculates the amount of space needed for constructing it's
  wchar_t version of argv, causing it to overrun the buffer.
  
  I don't see how the output of mbstowcs can be longer than
  (sum(strlen(argv)) * sizeof (wchar_t)) so this fix should work:
  
  ok?
  
  
  Index: chartype.c
  ===
  RCS file: /cvs/src/lib/libedit/chartype.c,v
  retrieving revision 1.3
  diff -u -p -r1.3 chartype.c
  --- chartype.c  7 Jul 2011 05:40:42 -   1.3
  +++ chartype.c  15 Nov 2011 00:38:44 -
  @@ -147,7 +147,7 @@ ct_decode_argv(int argc, const char *arg
   * the argv strings. */
  for (i = 0, bufspace = 0; i  argc; ++i)
  bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
  -   ct_conv_buff_resize(conv, 0, bufspace);
  +   ct_conv_buff_resize(conv, 0, bufspace * sizeof(*p));
  if (!conv-wsize)
  return NULL;
 
 OK, your fix is good (with or without my suggestion below).
 
 Even though we have enough space the code should properly evaluate
 what mbstowcs() returns, if only to provide a good example.
 Renaming the variable isn't strictly needed but 'bytes' is very misleading.
 
 Index: chartype.c
 ===
 RCS file: /cvs/src/lib/libedit/chartype.c,v
 retrieving revision 1.3
 diff -u -p -r1.3 chartype.c
 --- chartype.c7 Jul 2011 05:40:42 -   1.3
 +++ chartype.c16 Nov 2011 12:40:13 -
 @@ -141,13 +141,13 @@ ct_decode_argv(int argc, const char *arg
   int i;
   Char *p;
   Char **wargv;
 - ssize_t bytes;
 + size_t wlen;
  
   /* Make sure we have enough space in the conversion buffer to store all
* the argv strings. */
   for (i = 0, bufspace = 0; i  argc; ++i)
   bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
 - ct_conv_buff_resize(conv, 0, bufspace);
 + ct_conv_buff_resize(conv, 0, bufspace * sizeof(*p));
   if (!conv-wsize)
   return NULL;
  
 @@ -159,15 +159,16 @@ ct_decode_argv(int argc, const char *arg
   continue;
   } else {
   wargv[i] = p;
 - bytes = mbstowcs(p, argv[i], bufspace);
 + wlen = mbstowcs(p, argv[i], bufspace);
   }
 - if (bytes == -1) {
 + if (wlen == (size_t)-1 || wlen == bufspace) {
 + /* Encoding error or not enough room for NUL. */
   el_free(wargv);
   return NULL;
   } else
 - bytes++;  /* include '\0' in the count */
 - bufspace -= bytes;
 - p += bytes;
 + wlen++; /* include NUL in the count */
 + bufspace -= wlen;
 + p += wlen;
   }
  
   return wargv;



Re: libedit wchar allocation issue

2011-11-16 Thread Stefan Sperling
On Tue, Nov 15, 2011 at 11:09:08PM +, Nicholas Marriott wrote:
 Hi
 
 libedit miscalculates the amount of space needed for constructing it's
 wchar_t version of argv, causing it to overrun the buffer.
 
 I don't see how the output of mbstowcs can be longer than
 (sum(strlen(argv)) * sizeof (wchar_t)) so this fix should work:
 
 ok?
 
 
 Index: chartype.c
 ===
 RCS file: /cvs/src/lib/libedit/chartype.c,v
 retrieving revision 1.3
 diff -u -p -r1.3 chartype.c
 --- chartype.c7 Jul 2011 05:40:42 -   1.3
 +++ chartype.c15 Nov 2011 00:38:44 -
 @@ -147,7 +147,7 @@ ct_decode_argv(int argc, const char *arg
* the argv strings. */
   for (i = 0, bufspace = 0; i  argc; ++i)
   bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
 - ct_conv_buff_resize(conv, 0, bufspace);
 + ct_conv_buff_resize(conv, 0, bufspace * sizeof(*p));
   if (!conv-wsize)
   return NULL;

OK, your fix is good (with or without my suggestion below).

Even though we have enough space the code should properly evaluate
what mbstowcs() returns, if only to provide a good example.
Renaming the variable isn't strictly needed but 'bytes' is very misleading.

Index: chartype.c
===
RCS file: /cvs/src/lib/libedit/chartype.c,v
retrieving revision 1.3
diff -u -p -r1.3 chartype.c
--- chartype.c  7 Jul 2011 05:40:42 -   1.3
+++ chartype.c  16 Nov 2011 12:40:13 -
@@ -141,13 +141,13 @@ ct_decode_argv(int argc, const char *arg
int i;
Char *p;
Char **wargv;
-   ssize_t bytes;
+   size_t wlen;
 
/* Make sure we have enough space in the conversion buffer to store all
 * the argv strings. */
for (i = 0, bufspace = 0; i  argc; ++i)
bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
-   ct_conv_buff_resize(conv, 0, bufspace);
+   ct_conv_buff_resize(conv, 0, bufspace * sizeof(*p));
if (!conv-wsize)
return NULL;
 
@@ -159,15 +159,16 @@ ct_decode_argv(int argc, const char *arg
continue;
} else {
wargv[i] = p;
-   bytes = mbstowcs(p, argv[i], bufspace);
+   wlen = mbstowcs(p, argv[i], bufspace);
}
-   if (bytes == -1) {
+   if (wlen == (size_t)-1 || wlen == bufspace) {
+   /* Encoding error or not enough room for NUL. */
el_free(wargv);
return NULL;
} else
-   bytes++;  /* include '\0' in the count */
-   bufspace -= bytes;
-   p += bytes;
+   wlen++; /* include NUL in the count */
+   bufspace -= wlen;
+   p += wlen;
}
 
return wargv;



Re: libedit wchar allocation issue

2011-11-16 Thread Owain Ainsworth
On Tue, Nov 15, 2011 at 11:09:08PM +, Nicholas Marriott wrote:
 Hi
 
 libedit miscalculates the amount of space needed for constructing it's
 wchar_t version of argv, causing it to overrun the buffer.
 
 I don't see how the output of mbstowcs can be longer than
 (sum(strlen(argv)) * sizeof (wchar_t)) so this fix should work:
 
 ok?

This seems to fix an intermittent problem I have been having with
libedit crashing during various initialisation dances.

I approve.
-- 
The wages of sin are high but you get your money's worth.



libedit wchar allocation issue

2011-11-15 Thread Nicholas Marriott
Hi

libedit miscalculates the amount of space needed for constructing it's
wchar_t version of argv, causing it to overrun the buffer.

I don't see how the output of mbstowcs can be longer than
(sum(strlen(argv)) * sizeof (wchar_t)) so this fix should work:

ok?


Index: chartype.c
===
RCS file: /cvs/src/lib/libedit/chartype.c,v
retrieving revision 1.3
diff -u -p -r1.3 chartype.c
--- chartype.c  7 Jul 2011 05:40:42 -   1.3
+++ chartype.c  15 Nov 2011 00:38:44 -
@@ -147,7 +147,7 @@ ct_decode_argv(int argc, const char *arg
 * the argv strings. */
for (i = 0, bufspace = 0; i  argc; ++i)
bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
-   ct_conv_buff_resize(conv, 0, bufspace);
+   ct_conv_buff_resize(conv, 0, bufspace * sizeof(*p));
if (!conv-wsize)
return NULL;