On Tue, Sep 06, 2016 at 01:10:36PM +0200, Vincent Lefevre wrote: > On 2016-09-05 19:07:18 -0500, Derek Martin wrote: > > On Mon, Sep 05, 2016 at 10:32:40AM -0500, Derek Martin wrote: > > > Is strfcpy() widely available? > > > > Ah, now I see that strfcpy() is a Mutt-specific macro that intends to > > make strncpy() safer. I was actually thinking of strlcpy(), which is > > equivalent to Mutt's strfcpy(); but it does not matter. ALL of these > > functions suffer from the same affliction: If dest is too small, they > > all silently lose data on copy. > > The strfcpy macro looks awful:
Firstly, I'll note that, given the existing macros don't seem to have caused anyone any grief, the exact macro syntax is largely an academic consideration. =8^) But I like those discussions, so I'll blather on a bit about it: > # define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0 Ah, that's not the definition I saw, but it turns out it's defined in several places, with two different definitions. The other one is in rfc822.c: rfc822.c:#define strfcpy(a,b,c) {if (c) {strncpy(a,b,c);a[c-1]=0;}} Note the block syntax, similar to what I used. At least on GCC, this does not cause compilation problems in the vast majority of cases, including the one you highlighted, though I can't say how other compilers might treat it, or guess what cases I might be missing... For instance, with gcc the following program (which is basically an expansion of the macro syntax I suggested) compiles and runs fine, even with -Wall -Werror: -=-=-=-=-=-=-=-=- $ cat blah.c #include <stdio.h> int main(int argc, char **argv) { if (argc > 0){ { printf("argc is %d\n", argc); }; } else { { printf("argc is not greater than zero\n"); }; } return 0; } $ gcc -Wall -Werror -o blah blah.c $ ./blah argc is 1 -=-=-=-=-=-=-=-=- I seem to recall that I once ran into a situation where the loop construct you suggested caused a problem, though I can't recall the details, and seems to me it would've been a rare case. But I think it's no longer necessary on modern compilers. And, again at least with GCC, you can put the block inside parens too, and it'll still compile fine--without the need for the loop construct, and making it completely safe to use in any context. But again, I'm not sure how other compilers would react to that syntax. I frequently use that syntax in a macro I have to ignore return values, albeit with C++: // GCC 4.6 has made it very difficult to ignore return values from some library // functions... This monstrosity solves that while keeping the intent clear. #define IGNORE_VAL(expr)\ ({ typeof(expr) __ignval __attribute((unused)) = (expr); }) But AFAIK it should work fine in C as well--with gcc. Regardless, I appear to have gotten the point across about strncpy()/strlcpy()/strfcpy() -- and if we're cleaning this up, we should probably move the macro to protos.h or similar and remove the multiple/different definitions of it elsewhere. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0xDFBEAD02 -=-=-=-=- This message is posted from an invalid address. Replying to it will result in undeliverable mail due to spam prevention. Sorry for the inconvenience.
pgp4NzoGP9PIc.pgp
Description: PGP signature