Hello Ali,
On 25/2/22 17:22, Ali Farzanrad wrote:
"Alejandro Colomar (man-pages)" <[email protected]> wrote:
char dest[SIZE];
char *end;
end = &dest[SIZE - 1];
stpecpy(dest, "Hello world", end);
Perfect way to introduce new hidden backdoors!
Just use realloc `dest' to a new value, but forget to update `end'
properly:
size_t size = 7;
char *dest = malloc(size);
char *end = &dest[size - 1];
stpecpy(dest, "Hello ", end);
dest = realloc(dest, size + 6)
end += 6;
stpecpy(dest, "World!", end);
There are three bugs there:
- Not really concatenating, but overwriting instead.
This one is unrelated to 'end'. It is related to the fact that
this function doesn't search the NUL byte, but instead is the user
who needs to update the pointer (from the previous call to stpecpy()).
- Not checking realloc(3) for NULL. Both snippets share the same bug.
Be careful with realloc(3) :-)
- Not updating 'end' from an offset of the new 'dest'.
However, I guess the first bug was accidental, and that the
intention was to concatenate the two strings. Apart from that,
one would need to update all pointers with offsets to avoid the 3rd bug.
Since realloc(3) is likely going to be much slower than strlcat(3bsd),
I'd say, go ahead and use strlcat(3bsd) if you need to realloc(3).
Providing one or the other, shouldn't imply providing it exclusively.
There are cases where one would be more suitable than the other;
there's no perfect function that can be the best everywhere.
The worst scenario for strlcat(3bsd) is a loop (see for example
<https://github.com/openbsd/src/blob/2207c4325726fdc5c4bcd0011af0fdf7d3dab137/lib/libcurses/trace/lib_tracebits.c#L96>).
There's no readability problem, which
is nice, but it has a serious performance problem: quadratic
time complexity, and is fixed simply by using stpecpy():
for (int i = 0; i < n; i++) {
p = stpecpy(p, s[i], e);
}
vs
for (int i = 0; i < n; i++) {
strlcat(p, s[i], size);
}
The worst scenario (or the worst I've seen so far) for stpecpy() is
realloc(3). In this case there's no performance penalty, but writing
the code is a PITA, and better avoided, as you suggested.
Regards,
Alex