2

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?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • There are various implementations, but take a look at one example's source code - https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/arm/strlcpy.c.auto.html – OldProgrammer Mar 06 '20 at 19:11
  • 2
    "[The behaviour is undefined if the strings overlap](https://en.cppreference.com/w/c/string/byte/strcpy)". As far as I know that is true of all string copying functions from ``. – M Oehm Mar 06 '20 at 19:11
  • 2
    From the man page on my system: "If the src and dst strings overlap, the behavior is undefined." – EdmCoff Mar 06 '20 at 19:11
  • 3
    From the documentation, behavior is undefined. memmove will safely copy overlapping strings – agbinfo Mar 06 '20 at 19:11

3 Answers3

1

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);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • "If the signature was as below and compiler is compliant to C99 or later, than using destination, source that may overlap is defined behavior." Well, "defined" in the sense that the C language allows you to make such a call. But nobody is guaranteeing that `strlcpy` will actually do anything reasonable when you do so. – Nate Eldredge Mar 06 '20 at 22:19
  • @NateEldredge Perhaps. IAC, should `strlcpy()` get adapted into Std C lib, I'd expect `restrict` or explicit function definition. Until then, prudent coding would assume the worse and not attempt overlapping buffers. – chux - Reinstate Monica Mar 06 '20 at 23:57
1

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.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
0

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.