Benjamin Schieder


2009 August 31 | 5 comments

Suppose you have a char foo[11]; that you want to put a 10-Byte Text into. For simplicity you copy and paste a line that you had used just a little earlier:

strncpy(foo, "1234567890", 10);

To me, this first looked harmless and even worked fine. At least, mostly. I pretty soon found out that strncpy doesnr't add a final \\0. So in the end it became this after all:
sprintf(foo, "1234567890");


Category: blog

Tags: TechSucks


From: mirabilos
2009-08-31 10:20:47 +0200

Just use ☺ That one will always ensure
the output is a valid C string if its input is.

From: P2501
2009-08-31 13:41:23 +0200

Ugh. Beginners mistake. You ordered strncpy to copy ten bytes, and so it did. Check the manpage.
Really, the only safe and portable way to do this is:
foo[sizeof(foo)-1] = '';
strlcpy does a better job, but it's BSD-specific.

From: blindcoder
2009-08-31 17:30:18 +0200

Guess it means I've been away from C for far too long if I make these mistakes :-)
Switching from doing Perl and bash for one, two years back to a 'You asked for it, you got it'-language does these things to me.

From: mirabilos
2009-09-01 14:36:13 +0200

strlcpy is not BSD-specific. Actually, almost everyone EXCEPT glibc and
eglibc package it. On Debian, it’s in libbsd. And it’s very few code to
add to the own package, which is what mksh does. Less than GNUlib.
It's better to use memcpy than strncpy.

From: P2501
2009-09-01 15:43:19 +0200

(/me goes checking once more)
Okay. Looks like almost everyone else has adopted strlcpy by now, so yes, it's not really BSD-specific anymore. Even uClibc and dietlibc have it.
It's just the glibc maintainers who claim that strlcpy is non-standard and unsafe (as it doesn't completely avoid boundary errors), and therefore should not be supported. Oh, well...

Post a comment

All comments are held for moderation; basic HTML formatting is accepted.

Name: (required)
E-mail: (required, not published)
Website: (optional)