Skip to content

Commit ed15e58

Browse files
peffgitster
authored andcommitted
daemon: fix length computation in newline stripping
When git-daemon gets a pktline request, we strip off any trailing newline, replacing it with a NUL. Clients prior to 5ad312b (in git v1.4.0) would send: git-upload-pack repo.git\n and we need to strip it off to understand their request. After 5ad312b, we send the host attribute but no newline, like: git-upload-pack repo.git\0host=example.com\0 Both of these are parsed correctly by git-daemon. But if some client were to combine the two: git-upload-pack repo.git\n\0host=example.com\0 we don't parse it correctly. The problem is that we use the "len" variable to record the position of the NUL separator, but then decrement it when we strip the newline. So we start with: git-upload-pack repo.git\n\0host=example.com\0 ^-- len and end up with: git-upload-pack repo.git\0\0host=example.com\0 ^-- len This is arguably correct, since "len" tells us the length of the initial string, but we don't actually use it for that. What we do use it for is finding the offset of the extended attributes; they used to be at len+1, but are now at len+2. We can solve that by just leaving "len" where it is. We don't have to care about the length of the shortened string, since we just treat it like a C string. No version of Git ever produced such a string, but it seems like the daemon code meant to handle this case (and it seems like a reasonable thing for somebody to do in a 3rd-party implementation). Reported-by: Michael Haggerty <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4414a15 commit ed15e58

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

daemon.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -760,10 +760,8 @@ static int execute(void)
760760
alarm(0);
761761

762762
len = strlen(line);
763-
if (len && line[len-1] == '\n') {
764-
line[--len] = 0;
765-
pktlen--;
766-
}
763+
if (len && line[len-1] == '\n')
764+
line[len-1] = 0;
767765

768766
/* parse additional args hidden behind a NUL byte */
769767
if (len != pktlen)

t/t5570-git-daemon.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,20 @@ test_expect_success 'daemon log records all attributes' '
196196
test_cmp expect actual
197197
'
198198

199+
test_expect_success FAKENC 'hostname interpolation works after LF-stripping' '
200+
{
201+
printf "git-upload-pack /interp.git\n\0host=localhost" | packetize
202+
printf "0000"
203+
} >input &&
204+
fake_nc "$GIT_DAEMON_HOST_PORT" <input >output &&
205+
depacketize <output >output.raw &&
206+
207+
# just pick out the value of master, which avoids any protocol
208+
# particulars
209+
perl -lne "print \$1 if m{^(\\S+) refs/heads/master}" <output.raw >actual &&
210+
git -C "$repo" rev-parse master >expect &&
211+
test_cmp expect actual
212+
'
213+
199214
stop_git_daemon
200215
test_done

0 commit comments

Comments
 (0)