Merge branch 'jk/http-walker-buffer-underflow-fix'
authorJunio C Hamano <gitster@pobox.com>
Fri, 17 Mar 2017 20:50:26 +0000 (13:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 Mar 2017 20:50:26 +0000 (13:50 -0700)
"Dumb http" transport used to misparse a nonsense http-alternates
response, which has been fixed.

* jk/http-walker-buffer-underflow-fix:
http-walker: fix buffer underflow processing remote alternates

1  2 
http-walker.c
diff --combined http-walker.c
index ab7d5537ae55809685c633c91e869107f73fbb5b,507c200f004a0d1e295a6ffe876667ddf20db3bf..ee049cb13df6ed6a64b1980004100a5dd55dde51
@@@ -168,11 -168,6 +168,11 @@@ static int is_alternate_allowed(const c
        };
        int i;
  
 +      if (http_follow_config != HTTP_FOLLOW_ALWAYS) {
 +              warning("alternate disabled by http.followRedirects: %s", url);
 +              return 0;
 +      }
 +
        for (i = 0; i < ARRAY_SIZE(protocols); i++) {
                const char *end;
                if (skip_prefix(url, protocols[i], &end) &&
@@@ -301,13 -296,16 +301,16 @@@ static void process_alternates_response
                                        okay = 1;
                                }
                        }
-                       /* skip "objects\n" at end */
                        if (okay) {
                                struct strbuf target = STRBUF_INIT;
                                strbuf_add(&target, base, serverlen);
-                               strbuf_add(&target, data + i, posn - i - 7);
-                               if (is_alternate_allowed(target.buf)) {
+                               strbuf_add(&target, data + i, posn - i);
+                               if (!strbuf_strip_suffix(&target, "objects")) {
+                                       warning("ignoring alternate that does"
+                                               " not end in 'objects': %s",
+                                               target.buf);
+                                       strbuf_release(&target);
+                               } else if (is_alternate_allowed(target.buf)) {
                                        warning("adding alternate object store: %s",
                                                target.buf);
                                        newalt = xmalloc(sizeof(*newalt));
                                        while (tail->next != NULL)
                                                tail = tail->next;
                                        tail->next = newalt;
 +                              } else {
 +                                      strbuf_release(&target);
                                }
                        }
                }
@@@ -338,6 -334,9 +341,6 @@@ static void fetch_alternates(struct wal
        struct alternates_request alt_req;
        struct walker_data *cdata = walker->data;
  
 -      if (http_follow_config != HTTP_FOLLOW_ALWAYS)
 -              return;
 -
        /*
         * If another request has already started fetching alternates,
         * wait for them to arrive and return to processing this request's