]> git.ipfire.org Git - thirdparty/git.git/commitdiff
strbuf_readlink(): avoid calling `readlink()` twice in corner-cases
authorKarsten Blees <blees@dcon.de>
Tue, 16 Dec 2025 15:33:47 +0000 (15:33 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 17 Dec 2025 23:21:06 +0000 (08:21 +0900)
The `strbuf_readlink()` function calls `readlink()`` twice if the hint
argument specifies the exact size of the link target (e.g. by passing
stat.st_size as returned by `lstat()`). This is necessary because
`readlink(..., hint) == hint` could mean that the buffer was too small.

Use `hint + 1` as buffer size to prevent this.

Signed-off-by: Karsten Blees <blees@dcon.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
strbuf.c

index 6c3851a7f84d72ebf5719723dc7f0ac9cf60edf3..44a8f6a554ee43933d79d3106bbf3b6168116fe8 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -578,12 +578,12 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
        while (hint < STRBUF_MAXLINK) {
                ssize_t len;
 
-               strbuf_grow(sb, hint);
-               len = readlink(path, sb->buf, hint);
+               strbuf_grow(sb, hint + 1);
+               len = readlink(path, sb->buf, hint + 1);
                if (len < 0) {
                        if (errno != ERANGE)
                                break;
-               } else if (len < hint) {
+               } else if (len <= hint) {
                        strbuf_setlen(sb, len);
                        return 0;
                }