stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Travis Vitek" <Travis.Vi...@roguewave.com>
Subject RE: svn commit: r647908 - in /stdcxx/trunk/tests: self/0.printf.cpp src/fmt_defs.h src/printf.cpp
Date Mon, 14 Apr 2008 23:00:26 GMT
 

>Martin Sebor wrote:
>
>Travis Vitek wrote:
>>  
>> 
>> Martin Sebor wrote 
>>
>>> Wouldn't (*pbufsize == maxsize) in that case so that _rw_bufcat()
>>> would never need to allocate new space to begin with (or it would
>>> fail trying).
>>>
>> 
>> That only tells me if I've reached the maximum allowed 
>> buffer size. It tells me nothing about where the *pbufsize
>> bytes were allocated from, and that is exactly what I need,
>> right?
>
>Right. But nothing in printf.cpp should ever try to deallocate
>the buffer except _rw_bufcat() to reallocate it, and _rw_bufcat()
>should avoid reallocating when (*pbufsize == maxsize).

See discussion on this below.

>
>> 
>> I mean there are cases where (*pbufsize != maxsize) and we 
>> don't want to deallocate the buffer. Consider this case which
>> is taken from the test library...
>> 
>>   static int
>>   _rw_vsystem (const char *cmd, va_list va)
>>   {
>>       RW_ASSERT (0 != cmd);
>> 
>>       char buffer [256];
>>       char *buf = buffer;
>> 
>>       size_t bufsize = sizeof buffer;
>> 
>>       rw_vasnprintf (&buf, &bufsize, cmd, va);
>> 
>>       // <snip>
>>    }
>> 
>> We definitely don't want `buf' to be deallocated, that much is clear.
>> But how can `maxsize' possibly tell us anything about `buf'?
>
>Here, rw_vasnprintf() should arrange for maxsize to be set to
>bufsize so that _rw_bufcat() doesn't try to reallocate it when
>it runs out of space. I realize that changes would be need to
>make it work this way but it seems that it should be doable
>with the existing machinery, no?

Unless I'm totally misunderstanding you (it seems that I may be), this
would limit maximum command line length to 256 characters.

>
>Btw., this patch (applied to printf.cpp before rev 647908)
>*seems* to do what I'm describing except that rw_printf()
>croaks with the error:
>
>stdcxx/tests/src/printf.cpp:1027: rw_vasnprintf(0x7fbffff538, 
>0x7fbffff530, "%s", va_list) error: errno = 12: Cannot allocate memory
>
>Replacing it with a return statement with the short count
>shouldn't be too hard.
>
>Index: tests/src/printf.cpp
>===================================================================
>--- tests/src/printf.cpp        (revision 647907)
>+++ tests/src/printf.cpp        (working copy)
>@@ -955,11 +955,18 @@
>  #define vacpy DONT_TOUCH_ME
>
>      size_t default_bufsize = 1024;
>-    if (0 == pbufsize)
>-        pbufsize = &default_bufsize;
>+    size_t maxbufsize;
>
>-    Buffer buf = { pbuf, pbufsize, _RWSTD_SIZE_MAX, 0 };
>+    if (0 == pbufsize) {
>+        pbufsize   = &default_bufsize;
>+        maxbufsize = _RWSTD_SIZE_MAX;
>+    }
>+    else {
>+        maxbufsize = *pbufsize;
>+    }
>
>+    Buffer buf = { pbuf, pbufsize, maxbufsize, 0 };
>

I believe that if you applied this patch you would run into all sorts of
trouble in the test suite. Consider the following code (which is not
unlike that which is not totally unlike some code that is in the
21.strings.cpp]

  char   buf* = 0;
  size_t bufsz = 0;

  rw_vasnprintf (&buf, &bufsz, "%s", "hello world!");
  rw_vasnprintf (&buf, &bufsz, "%{+}%s", "goodbye world!");

The first call has pbufsize != 0 && *pbufsize == 0. So buf.maxsize is
going to be set to 0, and *buf.pbufsize will also be 0. In the first
call to _rw_bufcat() we would check (*pbufsize == maxsize), which would
pass, and we would never allocate [according to comments above]? That is
no good. So lets say we do allocate, but we use (*pbufsize == maxsize)
as a flag to not deallocate. Both values are 0, so we don't deallocate.
We then allocate space for the string and copy it in. The value of
*buf.pbufsize is set to something above 12 [say 15], which will set
bufsz to that same value.

The second call as pbufsize != 0 && *pbufsize == 15. We set buf.maxsize
to 15 by the above code. Eventually we get back down to _rw_bufcat().
There isn't enough space. We check (*pbufsize == maxsize), which is
false, so we do deallocate. When we calculate the new buffer size, there
is already a test to ensure we don't grow past maxsize. In this case, we
would like to allocate a total of 27 bytes. But 27 is greater than
maxsize, so we get a failure.

>
>Martin
>

Mime
View raw message