strlcpy: source and destination points to the same object

489 Views Asked by At

I am just beginning to understand strlcpy.

size_t strlcpy(char *destination, const char *source, size_t size);

My hypothetical question is: What if the destination and source point to the same object?

Example:

char destination[100];

const char*source = "text";

destination = source;

strlcpy(destination, source, sizeof(destination))

What goes on in the backend?

Is strlcpy aware that the source and destination share the same pointer?

Or

Does it blindly copy over and wastes cpu cycles - copying over the bytes which are the same?

3

There are 3 best solutions below

2
chux - Reinstate Monica On BEST ANSWER

What if the destination and source point to the same object?

strlcpy() is not part of the C standard library. Its precise functionality may vary from compiler to compiler. Review the documentation of the particular compiler/library to get the best answer.

As part of BSD systems, strlcpy(3) - Linux man page, I did not find anything dis-allowing overlap.


Since C99, keyword restrict helps answer the "What if the destination and source point to the same object?" part.

If the signature was as below, than using destination, source that reference overlapped data is undefined behavior. Anything may happen.

size_t strlcpy(char * restrict destination, const char * restrict source, size_t size);

If the signature was as below and compiler is compliant to C99 or later, than using destination, source that may overlap is defined behavior.

If the signature was as below and compiler is not complaint to C99 or later, than using destination, source that may overlap is likely undefined behavior unless the documentation addresses this case.

size_t strlcpy(char * destination, const char *source, size_t size);
0
Nico Gatti On

strlcpy will copy the buffer length and ensure that the string is 0'ended. It won't check that your dest and src are the same, its on you to validate that pointers are targetting the same address. If not, it will just rewrite the data and ensure the last byte of the dest is a 0.

0
Nate Eldredge On

Since strlcpy isn't defined by the ISO C standard nor any other "official" standard I know of, there isn't necessarily a canonical answer to this question.

The closest thing to an official specification for this function is probably the OpenBSD man page, since the function was introduced in a paper co-authored by Theo de Raadt, the creator of OpenBSD. (The paper's first author is Todd C. Miller.) This man page says:

If the src and dst strings overlap, the behavior is undefined.

In particular, you can see in the source that with that particular implementation, if you were to do

char buf[20] = "hello world";
char *dest = buf+2;
strlcpy(dest, buf, 18);

then dest would end up pointing to the string "heheheheheheheheh" instead of "hello world" as you would probably have wanted.

Since this is the case for at least one prominent implementation, you would be well advised never to call the function on potentially overlapping strings, as your code will at the very least be less portable.