I just wanted to weight in real quick.  Chris proposed behavior is
exactly how I wrote the CoreBase string formatting function.  I tested
this how fprintf() works on Debian and SUSE, and came to the same
conclusions as Chris.

I believe, more to the point, is that the call to strlen isn't needed.
 A fixed precision is already given, so why waste time looking for
NULL?

Running the attached test program with valgrind does not produce an
error.  Changing the precision to 5 will, in fact, produce an invalid
read error.

Stef

On Tue, Oct 2, 2012 at 5:30 PM, Chris Ball <li...@borderlinetech.ca> wrote:
>
>> I kind of agree with your sentiments (having been bitten by that myself when 
>> logging stuff), but I investigated it at the time and GSFormat.m is right 
>> and your code is wrong.
>>
>> The reason is that the %s format deal with a nul terminated c-string 
>> argument, and by definition that's *not* an array of char whose length is 
>> determined by the precision of the format string, the nul terminator is 
>> *mandatory*.  If you code passes an argument which is not nul terminated 
>> than your code is doing something illegal and you can't really complain 
>> about *anything* that happens.
>> Also, the precision in the format works in conjunction with field width and 
>> alignment ... the format code needs to determine the length of the string 
>> you passed (using strlen) when it decides which part of the string to use 
>> ... so in the case where the rightmost part of the string should be 
>> displayed, using the precision as the length would give the wrong result.
>>
>> We could probably adapt your patch to use precision as string lengh in those 
>> cases where it will work, but you can't catch all cases that way ... so 
>> maybe it's better if people find out as soon as possible that c-strings have 
>> to be nul terminated.
>>
>> Sorry about this ... but it's a behavior inherited from the C stdio library 
>> and posix etc standards.  My own feeling is that format strings *ought* to 
>> provide some way of working with unterminated strings, but they just don't, 
>> so you have to copy the data into a big enough buffer, add the nul 
>> terminator, and use that buffer intead of the original data :-(
>
> Interesting, I've never read the actual standard, my copy of K&R (2nd ed.) 
> just
> says (in table B-1);
>
> 's' char *; characters from the string are printed until a '\0' is reached or
> until the number of characters indicated by the precision have been printed.
>
> So by from the way K&R reads it is a bug.  No idea about POSIX et. al. though.
> I find it humorous that my book opened to exactly that page and I haven't 
> looked
> in there in quite a number of years.
>
>
>         Chris.
>
> _______________________________________________
> Gnustep-dev mailing list
> Gnustep-dev@gnu.org
> https://lists.gnu.org/mailman/listinfo/gnustep-dev
#include <stdio.h>
#include <stdlib.h>

char *test;

int main (void)
{
  test = malloc (4);
  
  test[0] = 'a';
  test[1] = 'b';
  test[2] = 'c';
  test[3] = 'd';
  fprintf (stdout, "%.*s\n", 4, test);
  
  free (test);
  return 0;
}
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
https://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to