There's been some effort to replace uses of strncpy() and our homegrown
StrNCpy() macro with strlcpy().  I had my nose rubbed today in the fact
that that isn't always a good transformation.  The reason why not is that
strlcpy() is defined to return strlen(src), which means that even after
it's transferred all the bytes it's going to, it keeps walking down the
source string looking for a '\0'.  Therefore:

1. Using strlcpy to copy from sources that are not known null-terminated
is outright unsafe: someday, you'll fall off the end of memory and

2. Even with a known null-terminated string, using strlcpy to chop small
pieces out of it is not bright, because each call will traverse all the
rest of the input.  This means for example that extracting N words out
of a long string will spend O(N^2) time in strlcpy.

I ran into the latter effect in tab-complete.c; the old coding there
used strlcpy as a substitute for memcpy and explicit placement of
a trailing '\0'.  We hadn't noticed the problem because it never got
done more than nine times per query, but with the new dispensation
of parsing the whole input line, the O(N^2) cost became obvious.

I did a quick troll looking for places where we might have either an
actual bug or a performance problem worth worrying about, and did not find
others, though it was a very quick scan and I might've missed something.

In general, I would say that it's best to use strlcpy() only as a safety
blanket to protect fixed-length buffers that you're not really intending
to overflow.  If you are expecting it to actually truncate strings in
normal use, there is a significant risk that You're Doing It Wrong.
Caveat programmer.

                        regards, tom lane

Sent via pgsql-hackers mailing list (
To make changes to your subscription:

Reply via email to