Merge branch 'ah/fix-http-push'
authorJunio C Hamano <gitster@pobox.com>
Wed, 16 Jul 2014 18:33:11 +0000 (11:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 16 Jul 2014 18:33:11 +0000 (11:33 -0700)
An ancient rewrite passed a wrong pointer to a curl library
function in a rarely used code path.

* ah/fix-http-push:
http-push.c: make CURLOPT_IOCTLDATA a usable pointer

1  2 
http-push.c
diff --combined http-push.c
index 6c3cc1725a9461876c7db11b9818eb553afb2fc2,3bcf8073eee90f4905911f4bba5f9bddcfb13ca6..952f8ede49daf4e275c42cc0682bb01c4c58446a
@@@ -64,7 -64,8 +64,7 @@@ enum XML_Status 
  #define LOCK_TIME 600
  #define LOCK_REFRESH 30
  
 -/* bits #0-15 in revision.h */
 -
 +/* Remember to update object flag allocation in object.h */
  #define LOCAL    (1u<<16)
  #define REMOTE   (1u<<17)
  #define FETCHING (1u<<18)
@@@ -199,7 -200,7 +199,7 @@@ static void curl_setup_http(CURL *curl
        curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
  #ifndef NO_CURL_IOCTL
        curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
-       curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &buffer);
+       curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);
  #endif
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);
        curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
@@@ -719,10 -720,14 +719,10 @@@ static int fetch_indices(void
        return ret;
  }
  
 -static void one_remote_object(const char *hex)
 +static void one_remote_object(const unsigned char *sha1)
  {
 -      unsigned char sha1[20];
        struct object *obj;
  
 -      if (get_sha1_hex(hex, sha1) != 0)
 -              return;
 -
        obj = lookup_object(sha1);
        if (!obj)
                obj = parse_object(sha1);
@@@ -763,13 -768,15 +763,13 @@@ static void handle_new_lock_ctx(struct 
  
        if (tag_closed && ctx->cdata) {
                if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) {
 -                      lock->owner = xmalloc(strlen(ctx->cdata) + 1);
 -                      strcpy(lock->owner, ctx->cdata);
 +                      lock->owner = xstrdup(ctx->cdata);
                } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
 -                      if (!prefixcmp(ctx->cdata, "Second-"))
 -                              lock->timeout =
 -                                      strtol(ctx->cdata + 7, NULL, 10);
 +                      const char *arg;
 +                      if (skip_prefix(ctx->cdata, "Second-", &arg))
 +                              lock->timeout = strtol(arg, NULL, 10);
                } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
 -                      lock->token = xmalloc(strlen(ctx->cdata) + 1);
 -                      strcpy(lock->token, ctx->cdata);
 +                      lock->token = xstrdup(ctx->cdata);
  
                        git_SHA1_Init(&sha_ctx);
                        git_SHA1_Update(&sha_ctx, lock->token, strlen(lock->token));
@@@ -850,7 -857,8 +850,7 @@@ static struct remote_lock *lock_remote(
        struct xml_ctx ctx;
        char *escaped;
  
 -      url = xmalloc(strlen(repo->url) + strlen(path) + 1);
 -      sprintf(url, "%s%s", repo->url, path);
 +      url = xstrfmt("%s%s", repo->url, path);
  
        /* Make sure leading directories exist for the remote ref */
        ep = strchr(url + strlen(repo->url) + 1, '/');
@@@ -1013,38 -1021,26 +1013,38 @@@ static void remote_ls(const char *path
                      void (*userFunc)(struct remote_ls_ctx *ls),
                      void *userData);
  
 +/* extract hex from sharded "xx/x{40}" filename */
 +static int get_sha1_hex_from_objpath(const char *path, unsigned char *sha1)
 +{
 +      char hex[40];
 +
 +      if (strlen(path) != 41)
 +              return -1;
 +
 +      memcpy(hex, path, 2);
 +      path += 2;
 +      path++; /* skip '/' */
 +      memcpy(hex, path, 38);
 +
 +      return get_sha1_hex(hex, sha1);
 +}
 +
  static void process_ls_object(struct remote_ls_ctx *ls)
  {
        unsigned int *parent = (unsigned int *)ls->userData;
 -      char *path = ls->dentry_name;
 -      char *obj_hex;
 +      const char *path = ls->dentry_name;
 +      unsigned char sha1[20];
  
        if (!strcmp(ls->path, ls->dentry_name) && (ls->flags & IS_DIR)) {
                remote_dir_exists[*parent] = 1;
                return;
        }
  
 -      if (strlen(path) != 49)
 +      if (!skip_prefix(path, "objects/", &path) ||
 +          get_sha1_hex_from_objpath(path, sha1))
                return;
 -      path += 8;
 -      obj_hex = xmalloc(strlen(path));
 -      /* NB: path is not null-terminated, can not use strlcpy here */
 -      memcpy(obj_hex, path, 2);
 -      strcpy(obj_hex + 2, path + 3);
 -      one_remote_object(obj_hex);
 -      free(obj_hex);
 +
 +      one_remote_object(sha1);
  }
  
  static void process_ls_ref(struct remote_ls_ctx *ls)
@@@ -1122,7 -1118,7 +1122,7 @@@ static void remote_ls(const char *path
                      void (*userFunc)(struct remote_ls_ctx *ls),
                      void *userData)
  {
 -      char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
 +      char *url = xstrfmt("%s%s", repo->url, path);
        struct active_request_slot *slot;
        struct slot_results results;
        struct strbuf in_buffer = STRBUF_INIT;
        ls.userData = userData;
        ls.userFunc = userFunc;
  
 -      sprintf(url, "%s%s", repo->url, path);
 -
        strbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);
  
        dav_headers = curl_slist_append(dav_headers, "Depth: 1");
@@@ -1539,9 -1537,10 +1539,9 @@@ static void update_remote_info_refs(str
  
  static int remote_exists(const char *path)
  {
 -      char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
 +      char *url = xstrfmt("%s%s", repo->url, path);
        int ret;
  
 -      sprintf(url, "%s%s", repo->url, path);
  
        switch (http_get_strbuf(url, NULL, NULL)) {
        case HTTP_OK:
  
  static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
  {
 -      char *url;
 +      char *url = xstrfmt("%s%s", repo->url, path);
        struct strbuf buffer = STRBUF_INIT;
 -
 -      url = xmalloc(strlen(repo->url) + strlen(path) + 1);
 -      sprintf(url, "%s%s", repo->url, path);
 +      const char *name;
  
        if (http_get_strbuf(url, &buffer, NULL) != HTTP_OK)
                die("Couldn't get %s for remote symref\n%s", url,
                return;
  
        /* If it's a symref, set the refname; otherwise try for a sha1 */
 -      if (!prefixcmp((char *)buffer.buf, "ref: ")) {
 -              *symref = xmemdupz((char *)buffer.buf + 5, buffer.len - 6);
 +      if (skip_prefix(buffer.buf, "ref: ", &name)) {
 +              *symref = xmemdupz(name, buffer.len - (name - buffer.buf));
        } else {
                get_sha1_hex(buffer.buf, sha1);
        }
@@@ -1673,7 -1674,8 +1673,7 @@@ static int delete_remote_branch(const c
        fprintf(stderr, "Removing remote branch '%s'\n", remote_ref->name);
        if (dry_run)
                return 0;
 -      url = xmalloc(strlen(repo->url) + strlen(remote_ref->name) + 1);
 -      sprintf(url, "%s%s", repo->url, remote_ref->name);
 +      url = xstrfmt("%s%s", repo->url, remote_ref->name);
        slot = get_active_slot();
        slot->results = &results;
        curl_setup_http_get(slot->curl, url, DAV_DELETE);
@@@ -1731,7 -1733,7 +1731,7 @@@ int main(int argc, char **argv
  
        git_extract_argv0_path(argv[0]);
  
 -      repo = xcalloc(sizeof(*repo), 1);
 +      repo = xcalloc(1, sizeof(*repo));
  
        argv++;
        for (i = 1; i < argc; i++, argv++) {