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