From: Junio C Hamano Date: Tue, 13 Jun 2017 20:27:05 +0000 (-0700) Subject: Merge branch 'jk/connect-symref-info-leak-fix' into maint X-Git-Tag: v2.13.2~16 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/87d4fdd9805edfe582bcbe92da638bb7eeb1725d?ds=inline;hp=-c Merge branch 'jk/connect-symref-info-leak-fix' into maint Leakfix. * jk/connect-symref-info-leak-fix: connect.c: fix leak in parse_one_symref_info() --- 87d4fdd9805edfe582bcbe92da638bb7eeb1725d diff --combined connect.c index cd21a1b6f7,8af002bf0f..c72b1d1151 --- a/connect.c +++ b/connect.c @@@ -71,7 -71,7 +71,7 @@@ static void parse_one_symref_info(struc check_refname_format(target, REFNAME_ALLOW_ONELEVEL)) /* "symref=bogus:pair */ goto reject; - item = string_list_append(symref, sym); + item = string_list_append_nodup(symref, sym); item->util = target; return; reject: @@@ -111,8 -111,8 +111,8 @@@ static void annotate_refs_with_symref_i */ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, struct ref **list, unsigned int flags, - struct sha1_array *extra_have, - struct sha1_array *shallow_points) + struct oid_array *extra_have, + struct oid_array *shallow_points) { struct ref **orig_list = list; @@@ -153,7 -153,7 +153,7 @@@ die("protocol error: expected shallow sha-1, got '%s'", arg); if (!shallow_points) die("repository on the other end cannot be shallow"); - sha1_array_append(shallow_points, old_oid.hash); + oid_array_append(shallow_points, &old_oid); continue; } @@@ -169,7 -169,7 +169,7 @@@ } if (extra_have && !strcmp(name, ".have")) { - sha1_array_append(extra_have, old_oid.hash); + oid_array_append(extra_have, &old_oid); continue; } @@@ -691,70 -691,6 +691,70 @@@ static const char *get_ssh_command(void return NULL; } +static int override_ssh_variant(int *port_option, int *needs_batch) +{ + char *variant; + + variant = xstrdup_or_null(getenv("GIT_SSH_VARIANT")); + if (!variant && + git_config_get_string("ssh.variant", &variant)) + return 0; + + if (!strcmp(variant, "plink") || !strcmp(variant, "putty")) { + *port_option = 'P'; + *needs_batch = 0; + } else if (!strcmp(variant, "tortoiseplink")) { + *port_option = 'P'; + *needs_batch = 1; + } else { + *port_option = 'p'; + *needs_batch = 0; + } + free(variant); + return 1; +} + +static void handle_ssh_variant(const char *ssh_command, int is_cmdline, + int *port_option, int *needs_batch) +{ + const char *variant; + char *p = NULL; + + if (override_ssh_variant(port_option, needs_batch)) + return; + + if (!is_cmdline) { + p = xstrdup(ssh_command); + variant = basename(p); + } else { + const char **ssh_argv; + + p = xstrdup(ssh_command); + if (split_cmdline(p, &ssh_argv) > 0) { + variant = basename((char *)ssh_argv[0]); + /* + * At this point, variant points into the buffer + * referenced by p, hence we do not need ssh_argv + * any longer. + */ + free(ssh_argv); + } else { + free(p); + return; + } + } + + if (!strcasecmp(variant, "plink") || + !strcasecmp(variant, "plink.exe")) + *port_option = 'P'; + else if (!strcasecmp(variant, "tortoiseplink") || + !strcasecmp(variant, "tortoiseplink.exe")) { + *port_option = 'P'; + *needs_batch = 1; + } + free(p); +} + /* * This returns a dummy child_process if the transport protocol does not * need fork(2), or a struct child_process object if it does. Once done, @@@ -833,8 -769,7 +833,8 @@@ struct child_process *git_connect(int f conn->in = conn->out = -1; if (protocol == PROTO_SSH) { const char *ssh; - int putty = 0, tortoiseplink = 0; + int needs_batch = 0; + int port_option = 'p'; char *ssh_host = hostandport; const char *port = NULL; transport_check_allowed("ssh"); @@@ -857,10 -792,10 +857,10 @@@ } ssh = get_ssh_command(); - if (!ssh) { - const char *base; - char *ssh_dup; - + if (ssh) + handle_ssh_variant(ssh, 1, &port_option, + &needs_batch); + else { /* * GIT_SSH is the no-shell version of * GIT_SSH_COMMAND (and must remain so for @@@ -871,10 -806,17 +871,10 @@@ ssh = getenv("GIT_SSH"); if (!ssh) ssh = "ssh"; - - ssh_dup = xstrdup(ssh); - base = basename(ssh_dup); - - tortoiseplink = !strcasecmp(base, "tortoiseplink") || - !strcasecmp(base, "tortoiseplink.exe"); - putty = tortoiseplink || - !strcasecmp(base, "plink") || - !strcasecmp(base, "plink.exe"); - - free(ssh_dup); + else + handle_ssh_variant(ssh, 0, + &port_option, + &needs_batch); } argv_array_push(&conn->args, ssh); @@@ -882,11 -824,11 +882,11 @@@ argv_array_push(&conn->args, "-4"); else if (flags & CONNECT_IPV6) argv_array_push(&conn->args, "-6"); - if (tortoiseplink) + if (needs_batch) argv_array_push(&conn->args, "-batch"); if (port) { - /* P is for PuTTY, p is for OpenSSH */ - argv_array_push(&conn->args, putty ? "-P" : "-p"); + argv_array_pushf(&conn->args, + "-%c", port_option); argv_array_push(&conn->args, port); } argv_array_push(&conn->args, ssh_host);