• Jeff King's avatar
    remote-curl: always parse incoming refs · 2a455202
    Jeff King authored
    When remote-curl receives a list of refs from a server, it
    keeps the whole buffer intact. When we get a "list" command,
    we feed the result to get_remote_heads, and when we get a
    "fetch" or "push" command, we feed it to fetch-pack or
    send-pack, respectively.
    
    If the HTTP response from the server is truncated for any
    reason, we will get an incomplete ref advertisement. If we
    then feed this incomplete list to fetch-pack, one of a few
    things may happen:
    
      1. If the truncation is in a packet header, fetch-pack
         will notice the bogus line and complain.
    
      2. If the truncation is inside a packet, fetch-pack will
         keep waiting for us to send the rest of the packet,
         which we never will.
    
      3. If the truncation is at a packet boundary, fetch-pack
         will keep waiting for us to send the next packet, which
         we never will.
    
    As a result, fetch-pack hangs, waiting for input.  However,
    remote-curl believes it has sent all of the advertisement,
    and therefore waits for fetch-pack to speak. The two
    processes end up in a deadlock.
    
    We do notice the broken ref list if we feed it to
    get_remote_heads. So if git asks the helper to do a "list"
    followed by a "fetch", we are safe; we'll abort during the
    list operation, which parses the refs.
    
    This patch teaches remote-curl to always parse and save the
    incoming ref list when we read the ref advertisement from a
    server. That means that we will always verify and abort
    before even running fetch-pack (or send-pack) when reading a
    corrupted list, even if we do not run the "list" command
    explicitly.
    
    Since we save the result, in the common case of running
    "list" then "fetch", we do not do any extra parsing at all.
    In the case of just a "fetch", we do an extra round of
    parsing, but only once.
    
    Note also that the "fetch" case will now also initialize
    server_capabilities from the remote (in remote-curl; we
    already would do so inside fetch-pack).  Doing "list+fetch"
    already does this. It doesn't actually matter now, but the
    new behavior is arguably more correct, should remote-curl
    ever start caring about the server's capability list.
    Signed-off-by: default avatarJeff King <peff@peff.net>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    2a455202
remote-curl.c 21.3 KB