gpg-interface: trim CR from ssh-keygen

We need to trim \r from the output of 'ssh-keygen -Y find-principals' on Windows, or we end up calling 'ssh-keygen -Y verify' with a bogus signer identity. ssh-keygen.c:2841 contains a call to puts(3), which confirms this hypothesis. Signature verification passes with the fix. Helped-by: Pedro Martelletto <pedro@yubico.com> Signed-off-by: Fabian Stelzer <fs@gigacodes.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Fabian Stelzer committed Jan 7, 2022 at 10:07 UTC caeef01ea73ba126a6cd4dbf4a4564ecdca9a32c
1 file changed +24 -10
gpg-interface.c
+24 -10
@@ -433,7 +433,6 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
433 struct tempfile *buffer_file;
434 int ret = -1;
435 const char *line;
436 - size_t trust_size;
436 char *principal;
437 struct strbuf ssh_principals_out = STRBUF_INIT;
438 struct strbuf ssh_principals_err = STRBUF_INIT;
@@ -502,15 +501,30 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
501 ret = -1;
502 } else {
503 /* Check every principal we found (one per line) */
505 - for (line = ssh_principals_out.buf; *line;
506 - line = strchrnul(line + 1, '\n')) {
507 - while (*line == '\n')
508 - line++;
509 - if (!*line)
510 - break;
511 -
512 - trust_size = strcspn(line, "\n");
513 - principal = xmemdupz(line, trust_size);
504 + const char *next;
505 + for (line = ssh_principals_out.buf;
506 + *line;
507 + line = next) {
508 + const char *end_of_text;
509 +
510 + next = end_of_text = strchrnul(line, '\n');
511 +
512 + /* Did we find a LF, and did we have CR before it? */
513 + if (*end_of_text &&
514 + line < end_of_text &&
515 + end_of_text[-1] == '\r')
516 + end_of_text--;
517 +
518 + /* Unless we hit NUL, skip over the LF we found */
519 + if (*next)
520 + next++;
521 +
522 + /* Not all lines are data. Skip empty ones */
523 + if (line == end_of_text)
524 + continue;
525 +
526 + /* We now know we have an non-empty line. Process it */
527 + principal = xmemdupz(line, end_of_text - line);
528
529 child_process_init(&ssh_keygen);
530 strbuf_release(&ssh_keygen_out);