git_reference *git_reference__alloc_symbolic( const char *name, const char *target) { git_reference *ref; assert(name && target); ref = alloc_ref(name); if (!ref) return NULL; ref->type = GIT_REF_SYMBOLIC; if ((ref->target.symbolic = git__strdup(target)) == NULL) { git__free(ref); return NULL; } return ref; }
int git_transport_new(git_transport **out, const char *url) { git_transport_cb fn; git_transport *transport; int error; fn = transport_new_fn(url); error = fn(&transport); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to create new transport"); transport->url = git__strdup(url); if (transport->url == NULL) return GIT_ENOMEM; *out = transport; return GIT_SUCCESS; }
static int curls_certificate(git_cert **out, git_stream *stream) { int error; CURLcode res; struct curl_slist *slist; struct curl_certinfo *certinfo; git_vector strings = GIT_VECTOR_INIT; curl_stream *s = (curl_stream *) stream; if ((res = curl_easy_getinfo(s->handle, CURLINFO_CERTINFO, &certinfo)) != CURLE_OK) return seterr_curl(s); /* No information is available, can happen with SecureTransport */ if (certinfo->num_of_certs == 0) { s->cert_info.parent.cert_type = GIT_CERT_NONE; s->cert_info.data = NULL; s->cert_info.len = 0; return 0; } if ((error = git_vector_init(&strings, 8, NULL)) < 0) return error; for (slist = certinfo->certinfo[0]; slist; slist = slist->next) { char *str = git__strdup(slist->data); GITERR_CHECK_ALLOC(str); git_vector_insert(&strings, str); } /* Copy the contents of the vector into a strarray so we can expose them */ s->cert_info_strings.strings = (char **) strings.contents; s->cert_info_strings.count = strings.length; s->cert_info.parent.cert_type = GIT_CERT_STRARRAY; s->cert_info.data = &s->cert_info_strings; s->cert_info.len = strings.length; *out = &s->cert_info.parent; return 0; }
static int rebase_alloc(git_rebase **out, const git_rebase_options *rebase_opts) { git_rebase *rebase = git__calloc(1, sizeof(git_rebase)); GIT_ERROR_CHECK_ALLOC(rebase); *out = NULL; if (rebase_opts) memcpy(&rebase->options, rebase_opts, sizeof(git_rebase_options)); else git_rebase_init_options(&rebase->options, GIT_REBASE_OPTIONS_VERSION); if (rebase_opts && rebase_opts->rewrite_notes_ref) { rebase->options.rewrite_notes_ref = git__strdup(rebase_opts->rewrite_notes_ref); GIT_ERROR_CHECK_ALLOC(rebase->options.rewrite_notes_ref); } *out = rebase; return 0; }
int git_cred_ssh_key_from_agent(git_cred **cred, const char *username) { git_cred_ssh_key *c; assert(cred); c = git__calloc(1, sizeof(git_cred_ssh_key)); GITERR_CHECK_ALLOC(c); c->parent.credtype = GIT_CREDTYPE_SSH_KEY; c->parent.free = ssh_key_free; if (username) { c->username = git__strdup(username); GITERR_CHECK_ALLOC(c->username); } c->privatekey = NULL; *cred = &c->parent; return 0; }
static int append_entry(git_treebuilder *bld, const char *filename, const git_oid *id, unsigned int attributes) { git_tree_entry *entry; if ((entry = git__malloc(sizeof(git_tree_entry))) == NULL) return GIT_ENOMEM; memset(entry, 0x0, sizeof(git_tree_entry)); entry->filename = git__strdup(filename); entry->filename_len = strlen(entry->filename); bld->entry_count++; git_oid_cpy(&entry->oid, id); entry->attr = attributes; if (git_vector_insert(&bld->entries, entry) < 0) return GIT_ENOMEM; return GIT_SUCCESS; }
int git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, const char *filename, const git_oid *id, unsigned int attributes) { git_tree_entry *entry; int pos; assert(bld && id && filename); if (!valid_attributes(attributes)) return GIT_ERROR; if ((pos = git_vector_bsearch2(&bld->entries, entry_search_cmp, filename)) != GIT_ENOTFOUND) { entry = git_vector_get(&bld->entries, pos); if (entry->removed) { entry->removed = 0; bld->entry_count++; } } else { if ((entry = git__malloc(sizeof(git_tree_entry))) == NULL) return GIT_ENOMEM; memset(entry, 0x0, sizeof(git_tree_entry)); entry->filename = git__strdup(filename); entry->filename_len = strlen(entry->filename); bld->entry_count++; } git_oid_cpy(&entry->oid, id); entry->attr = attributes; if (pos == GIT_ENOTFOUND) { if (git_vector_insert(&bld->entries, entry) < 0) return GIT_ENOMEM; } if (entry_out != NULL) *entry_out = entry; return GIT_SUCCESS; }
int gitfo_mkdir_recurs(const char *path, int mode) { int error; char *pp, *sp; char *path_copy = git__strdup(path); if (path_copy == NULL) return GIT_ENOMEM; error = GIT_SUCCESS; pp = path_copy; #ifdef GIT_WIN32 if (!is_windows_rooted_path(pp)) pp += 2; /* Skip the drive name (eg. C: or D:) */ #endif while (error == GIT_SUCCESS && (sp = strchr(pp, '/')) != 0) { if (sp != pp && gitfo_isdir(path_copy) < GIT_SUCCESS) { *sp = 0; error = gitfo_mkdir(path_copy, mode); /* Do not choke while trying to recreate an existing directory */ if (errno == EEXIST) error = GIT_SUCCESS; *sp = '/'; } pp = sp + 1; } if (*(pp - 1) != '/' && error == GIT_SUCCESS) error = gitfo_mkdir(path, mode); free(path_copy); return error; }
int git_openssl_stream_new(git_stream **out, const char *host, const char *port) { int error; openssl_stream *st; st = git__calloc(1, sizeof(openssl_stream)); GITERR_CHECK_ALLOC(st); #ifdef GIT_CURL error = git_curl_stream_new(&st->io, host, port); #else error = git_socket_stream_new(&st->io, host, port); #endif if (error < 0) return error; st->ssl = SSL_new(git__ssl_ctx); if (st->ssl == NULL) { giterr_set(GITERR_SSL, "failed to create ssl object"); return -1; } st->host = git__strdup(host); GITERR_CHECK_ALLOC(st->host); st->parent.version = GIT_STREAM_VERSION; st->parent.encrypted = 1; st->parent.proxy_support = git_stream_supports_proxy(st->io); st->parent.connect = openssl_connect; st->parent.certificate = openssl_certificate; st->parent.set_proxy = openssl_set_proxy; st->parent.read = openssl_read; st->parent.write = openssl_write; st->parent.close = openssl_close; st->parent.free = openssl_free; *out = (git_stream *) st; return 0; }
static void write_invalid_filename(git_repository *repo, const char *fn_orig) { git_index *index; git_oid expected; const git_index_entry *entry; git_buf path = GIT_BUF_INIT; char *fn; cl_git_pass(git_repository_index(&index, repo)); cl_assert(git_index_entrycount(index) == 0); /* * Sneak a valid path into the index, we'll update it * to an invalid path when we try to write the index. */ fn = git__strdup(fn_orig); replace_char(fn, '/', '_'); git_buf_joinpath(&path, "./invalid", fn); cl_git_mkfile(path.ptr, NULL); cl_git_pass(git_index_add_bypath(index, fn)); cl_assert(entry = git_index_get_bypath(index, fn, 0)); /* kids, don't try this at home */ replace_char((char *)entry->path, '_', '/'); /* write-tree */ cl_git_fail(git_index_write_tree(&expected, index)); p_unlink(path.ptr); cl_git_pass(git_index_remove_all(index, NULL, NULL, NULL)); git_buf_free(&path); git_index_free(index); git__free(fn); }
int git_blob_create_fromstream(git_writestream **out, git_repository *repo, const char *hintpath) { int error; git_buf path = GIT_BUF_INIT; blob_writestream *stream; assert(out && repo); stream = git__calloc(1, sizeof(blob_writestream)); GITERR_CHECK_ALLOC(stream); if (hintpath) { stream->hintpath = git__strdup(hintpath); GITERR_CHECK_ALLOC(stream->hintpath); } stream->repo = repo; stream->parent.write = blob_writestream_write; stream->parent.close = blob_writestream_close; stream->parent.free = blob_writestream_free; if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0 || (error = git_buf_joinpath(&path, path.ptr, "streamed")) < 0) goto cleanup; if ((error = git_filebuf_open_withsize(&stream->fbuf, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY, 0666, 2 * 1024 * 1024)) < 0) goto cleanup; *out = (git_writestream *) stream; cleanup: if (error < 0) blob_writestream_free((git_writestream *) stream); git_buf_dispose(&path); return error; }
int git_cred_ssh_custom_new( git_cred **cred, const char *username, const char *publickey, size_t publickey_len, git_cred_sign_callback sign_callback, void *sign_data) { git_cred_ssh_custom *c; assert(cred); c = git__calloc(1, sizeof(git_cred_ssh_custom)); GITERR_CHECK_ALLOC(c); c->parent.credtype = GIT_CREDTYPE_SSH_CUSTOM; c->parent.free = ssh_custom_free; if (username) { c->username = git__strdup(username); GITERR_CHECK_ALLOC(c->username); } if (publickey_len > 0) { c->publickey = git__malloc(publickey_len); GITERR_CHECK_ALLOC(c->publickey); memcpy(c->publickey, publickey, publickey_len); } c->publickey_len = publickey_len; c->sign_callback = sign_callback; c->sign_data = sign_data; *cred = &c->parent; return 0; }
static int git_proto_stream_alloc( git_subtransport *t, const char *url, const char *cmd, const char *host, const char *port, git_smart_subtransport_stream **stream) { git_proto_stream *s; if (!stream) return -1; s = git__calloc(1, sizeof(git_proto_stream)); GIT_ERROR_CHECK_ALLOC(s); s->parent.subtransport = &t->parent; s->parent.read = git_proto_stream_read; s->parent.write = git_proto_stream_write; s->parent.free = git_proto_stream_free; s->cmd = cmd; s->url = git__strdup(url); if (!s->url) { git__free(s); return -1; } if ((git_socket_stream_new(&s->io, host, port)) < 0) return -1; GIT_ERROR_CHECK_VERSION(s->io, GIT_STREAM_VERSION, "git_stream"); *stream = &s->parent; return 0; }
static int filter_check( git_filter *self, void **payload, /* points to NULL ptr on entry, may be set */ const git_filter_source *src, const char **attr_values) { GIT_UNUSED(self); GIT_UNUSED(src); if (GIT_ATTR_UNSPECIFIED(attr_values[0])) return GIT_PASSTHROUGH; if (GIT_ATTR_FALSE(attr_values[0])) return GIT_PASSTHROUGH; if (GIT_ATTR_TRUE(attr_values[0])) return GIT_PASSTHROUGH; *payload = git__strdup(attr_values[0]); if (!*payload) return 1; return 0; }
void test_blame_getters__initialize(void) { size_t i; git_blame_options opts = GIT_BLAME_OPTIONS_INIT; git_blame_hunk hunks[] = { { 3, {{0}}, 1, NULL, {{0}}, "a", 0}, { 3, {{0}}, 4, NULL, {{0}}, "b", 0}, { 3, {{0}}, 7, NULL, {{0}}, "c", 0}, { 3, {{0}}, 10, NULL, {{0}}, "d", 0}, { 3, {{0}}, 13, NULL, {{0}}, "e", 0}, }; g_blame = git_blame__alloc(NULL, opts, ""); for (i=0; i<5; i++) { git_blame_hunk *h = git__calloc(1, sizeof(git_blame_hunk)); h->final_start_line_number = hunks[i].final_start_line_number; h->orig_path = git__strdup(hunks[i].orig_path); h->lines_in_hunk = hunks[i].lines_in_hunk; git_vector_insert(&g_blame->hunks, h); } }
static int repo_init_find_dir(repo_init *results, const char* path) { char temp_path[GIT_PATH_MAX]; int path_len; int error = GIT_SUCCESS; error = gitfo_prettify_dir_path(temp_path, path); if (error < GIT_SUCCESS) return error; path_len = strlen(temp_path); if (!results->is_bare) { strcpy(temp_path + path_len - 1, GIT_DIR); path_len = path_len + strlen(GIT_DIR) - 1; /* Skip the leading slash from the constant */ } if (path_len >= GIT_PATH_MAX - MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH) return GIT_ENOTAREPO; results->path_repository = git__strdup(temp_path); return GIT_SUCCESS; }
static int rebase_alloc(git_rebase **out, const git_rebase_options *rebase_opts) { git_rebase *rebase = git__calloc(1, sizeof(git_rebase)); GITERR_CHECK_ALLOC(rebase); *out = NULL; if (rebase_opts) memcpy(&rebase->options, rebase_opts, sizeof(git_rebase_options)); else git_rebase_init_options(&rebase->options, GIT_REBASE_OPTIONS_VERSION); if (rebase_opts && rebase_opts->rewrite_notes_ref) { rebase->options.rewrite_notes_ref = git__strdup(rebase_opts->rewrite_notes_ref); GITERR_CHECK_ALLOC(rebase->options.rewrite_notes_ref); } if ((rebase->options.checkout_options.checkout_strategy & (GIT_CHECKOUT_SAFE | GIT_CHECKOUT_FORCE)) == 0) rebase->options.checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE; *out = rebase; return 0; }
int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch) { // Ported from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/remote.c#L518-636 size_t llen; int is_glob = 0; const char *lhs, *rhs; int flags; assert(refspec && input); memset(refspec, 0x0, sizeof(git_refspec)); refspec->push = !is_fetch; lhs = input; if (*lhs == '+') { refspec->force = 1; lhs++; } rhs = strrchr(lhs, ':'); /* * Before going on, special case ":" (or "+:") as a refspec * for matching refs. */ if (!is_fetch && rhs == lhs && rhs[1] == '\0') { refspec->matching = 1; return 0; } if (rhs) { size_t rlen = strlen(++rhs); is_glob = (1 <= rlen && strchr(rhs, '*')); refspec->dst = git__strndup(rhs, rlen); } llen = (rhs ? (size_t)(rhs - lhs - 1) : strlen(lhs)); if (1 <= llen && memchr(lhs, '*', llen)) { if ((rhs && !is_glob) || (!rhs && is_fetch)) goto invalid; is_glob = 1; } else if (rhs && is_glob) goto invalid; refspec->pattern = is_glob; refspec->src = git__strndup(lhs, llen); flags = GIT_REF_FORMAT_ALLOW_ONELEVEL | GIT_REF_FORMAT_REFSPEC_SHORTHAND | (is_glob ? GIT_REF_FORMAT_REFSPEC_PATTERN : 0); if (is_fetch) { /* * LHS * - empty is allowed; it means HEAD. * - otherwise it must be a valid looking ref. */ if (!*refspec->src) ; /* empty is ok */ else if (!git_reference__is_valid_name(refspec->src, flags)) goto invalid; /* * RHS * - missing is ok, and is same as empty. * - empty is ok; it means not to store. * - otherwise it must be a valid looking ref. */ if (!refspec->dst) ; /* ok */ else if (!*refspec->dst) ; /* ok */ else if (!git_reference__is_valid_name(refspec->dst, flags)) goto invalid; } else { /* * LHS * - empty is allowed; it means delete. * - when wildcarded, it must be a valid looking ref. * - otherwise, it must be an extended SHA-1, but * there is no existing way to validate this. */ if (!*refspec->src) ; /* empty is ok */ else if (is_glob) { if (!git_reference__is_valid_name(refspec->src, flags)) goto invalid; } else { ; /* anything goes, for now */ } /* * RHS * - missing is allowed, but LHS then must be a * valid looking ref. * - empty is not allowed. * - otherwise it must be a valid looking ref. */ if (!refspec->dst) { if (!git_reference__is_valid_name(refspec->src, flags)) goto invalid; } else if (!*refspec->dst) { goto invalid; } else { if (!git_reference__is_valid_name(refspec->dst, flags)) goto invalid; } /* if the RHS is empty, then it's a copy of the LHS */ if (!refspec->dst) { refspec->dst = git__strdup(refspec->src); GITERR_CHECK_ALLOC(refspec->dst); } } refspec->string = git__strdup(input); GITERR_CHECK_ALLOC(refspec->string); return 0; invalid: giterr_set( GITERR_INVALID, "'%s' is not a valid refspec.", input); return -1; }
static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size) { size_t path_length, entry_size; uint16_t flags_raw; const char *path_ptr; const struct entry_short *source; if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size) return 0; source = (const struct entry_short *)(buffer); dest->ctime.seconds = ntohl(source->ctime.seconds); dest->ctime.nanoseconds = ntohl(source->ctime.nanoseconds); dest->mtime.seconds = ntohl(source->mtime.seconds); dest->mtime.nanoseconds = ntohl(source->mtime.nanoseconds); dest->dev = ntohl(source->dev); dest->ino = ntohl(source->ino); dest->mode = ntohl(source->mode); dest->uid = ntohl(source->uid); dest->gid = ntohl(source->gid); dest->file_size = ntohl(source->file_size); git_oid_cpy(&dest->oid, &source->oid); dest->flags = ntohs(source->flags); if (dest->flags & GIT_IDXENTRY_EXTENDED) { struct entry_long *source_l = (struct entry_long *)source; path_ptr = source_l->path; flags_raw = ntohs(source_l->flags_extended); memcpy(&dest->flags_extended, &flags_raw, 2); } else path_ptr = source->path; path_length = dest->flags & GIT_IDXENTRY_NAMEMASK; /* if this is a very long string, we must find its * real length without overflowing */ if (path_length == 0xFFF) { const char *path_end; path_end = memchr(path_ptr, '\0', buffer_size); if (path_end == NULL) return 0; path_length = path_end - path_ptr; } if (dest->flags & GIT_IDXENTRY_EXTENDED) entry_size = long_entry_size(path_length); else entry_size = short_entry_size(path_length); if (INDEX_FOOTER_SIZE + entry_size > buffer_size) return 0; dest->path = git__strdup(path_ptr); assert(dest->path); return entry_size; }
static git_index_tree *read_tree_internal( const char **buffer_in, const char *buffer_end, git_index_tree *parent) { git_index_tree *tree; const char *name_start, *buffer; if ((tree = git__malloc(sizeof(git_index_tree))) == NULL) return NULL; memset(tree, 0x0, sizeof(git_index_tree)); tree->parent = parent; buffer = name_start = *buffer_in; if ((buffer = memchr(buffer, '\0', buffer_end - buffer)) == NULL) goto error_cleanup; /* NUL-terminated tree name */ tree->name = git__strdup(name_start); if (++buffer >= buffer_end) goto error_cleanup; /* Blank-terminated ASCII decimal number of entries in this tree */ tree->entries = strtol(buffer, (char **)&buffer, 10); if (*buffer != ' ' || ++buffer >= buffer_end) goto error_cleanup; /* Number of children of the tree, newline-terminated */ tree->children_count = strtol(buffer, (char **)&buffer, 10); if (*buffer != '\n' || ++buffer >= buffer_end) goto error_cleanup; /* 160-bit SHA-1 for this tree and it's children */ if (buffer + GIT_OID_RAWSZ > buffer_end) goto error_cleanup; git_oid_mkraw(&tree->oid, (const unsigned char *)buffer); buffer += GIT_OID_RAWSZ; /* Parse children: */ if (tree->children_count > 0) { unsigned int i; tree->children = git__malloc(tree->children_count * sizeof(git_index_tree *)); if (tree->children == NULL) goto error_cleanup; for (i = 0; i < tree->children_count; ++i) { tree->children[i] = read_tree_internal(&buffer, buffer_end, tree); if (tree->children[i] == NULL) goto error_cleanup; } } *buffer_in = buffer; return tree; error_cleanup: git_index_tree__free(tree); return NULL; }
int git_index_insert(git_index *index, const git_index_entry *source_entry) { git_index_entry *offset; size_t path_length; int position; assert(index && source_entry); if (source_entry->path == NULL) return GIT_EMISSINGOBJDATA; position = git_index_find(index, source_entry->path); if (position == GIT_ENOTFOUND) { /* Resize the entries array */ if (index->entry_count + 1 > index->entries_size) { git_index_entry *new_entries; size_t new_size; new_size = (unsigned int)(index->entries_size * 1.5f); if (new_size < 8) new_size = 8; if ((new_entries = git__malloc(new_size * sizeof(git_index_entry))) == NULL) return GIT_ENOMEM; memcpy(new_entries, index->entries, index->entry_count * sizeof(git_index_entry)); free(index->entries); index->entries_size = new_size; index->entries = new_entries; } offset = &index->entries[index->entry_count]; index->entry_count++; index->sorted = 0; } else { offset = &index->entries[position]; free(offset->path); } memcpy(offset, source_entry, sizeof(git_index_entry)); /* duplicate the path string so we own it */ offset->path = git__strdup(offset->path); if (offset->path == NULL) return GIT_ENOMEM; /* make sure that the path length flag is correct */ path_length = strlen(offset->path); offset->flags &= ~GIT_IDXENTRY_NAMEMASK; if (path_length < GIT_IDXENTRY_NAMEMASK) offset->flags |= path_length & GIT_IDXENTRY_NAMEMASK; else offset->flags |= GIT_IDXENTRY_NAMEMASK;; /* TODO: force the extended index entry flag? */ assert(offset->path); return GIT_SUCCESS; }
static int _git_ssh_setup_conn( ssh_subtransport *t, const char *url, const char *cmd, git_smart_subtransport_stream **stream) { char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL; const char *default_port="22"; int auth_methods, error = 0; size_t i; ssh_stream *s; git_cred *cred = NULL; LIBSSH2_SESSION* session=NULL; LIBSSH2_CHANNEL* channel=NULL; t->current_stream = NULL; *stream = NULL; if (ssh_stream_alloc(t, url, cmd, stream) < 0) return -1; s = (ssh_stream *)*stream; s->session = NULL; s->channel = NULL; for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) { const char *p = ssh_prefixes[i]; if (!git__prefixcmp(url, p)) { if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0) goto done; goto post_extract; } } if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0) goto done; port = git__strdup(default_port); GITERR_CHECK_ALLOC(port); post_extract: if ((error = git_socket_stream_new(&s->io, host, port)) < 0 || (error = git_stream_connect(s->io)) < 0) goto done; if ((error = _git_ssh_session_create(&session, s->io)) < 0) goto done; if (t->owner->certificate_check_cb != NULL) { git_cert_hostkey cert = {{ 0 }}, *cert_ptr; const char *key; cert.parent.cert_type = GIT_CERT_HOSTKEY_LIBSSH2; key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); if (key != NULL) { cert.type |= GIT_CERT_SSH_SHA1; memcpy(&cert.hash_sha1, key, 20); } key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); if (key != NULL) { cert.type |= GIT_CERT_SSH_MD5; memcpy(&cert.hash_md5, key, 16); } if (cert.type == 0) { giterr_set(GITERR_SSH, "unable to get the host key"); error = -1; goto done; } /* We don't currently trust any hostkeys */ giterr_clear(); cert_ptr = &cert; error = t->owner->certificate_check_cb((git_cert *) cert_ptr, 0, host, t->owner->message_cb_payload); if (error < 0) { if (!giterr_last()) giterr_set(GITERR_NET, "user cancelled hostkey check"); goto done; } } /* we need the username to ask for auth methods */ if (!user) { if ((error = request_creds(&cred, t, NULL, GIT_CREDTYPE_USERNAME)) < 0) goto done; user = git__strdup(((git_cred_username *) cred)->username); cred->free(cred); cred = NULL; if (!user) goto done; } else if (user && pass) { if ((error = git_cred_userpass_plaintext_new(&cred, user, pass)) < 0) goto done; } if ((error = list_auth_methods(&auth_methods, session, user)) < 0) goto done; error = GIT_EAUTH; /* if we already have something to try */ if (cred && auth_methods & cred->credtype) error = _git_ssh_authenticate_session(session, cred); while (error == GIT_EAUTH) { if (cred) { cred->free(cred); cred = NULL; } if ((error = request_creds(&cred, t, user, auth_methods)) < 0) goto done; if (strcmp(user, git_cred__username(cred))) { giterr_set(GITERR_SSH, "username does not match previous request"); error = -1; goto done; } error = _git_ssh_authenticate_session(session, cred); } if (error < 0) goto done; channel = libssh2_channel_open_session(session); if (!channel) { error = -1; ssh_error(session, "Failed to open SSH channel"); goto done; } libssh2_channel_set_blocking(channel, 1); s->session = session; s->channel = channel; t->current_stream = s; done: if (error < 0) { ssh_stream_free(*stream); if (session) libssh2_session_free(session); } if (cred) cred->free(cred); git__free(host); git__free(port); git__free(path); git__free(user); git__free(pass); return error; }
int git_commit__parse_raw(void *_commit, const char *data, size_t size) { git_commit *commit = _commit; const char *buffer_start = data, *buffer; const char *buffer_end = buffer_start + size; git_oid parent_id; size_t header_len; git_signature dummy_sig; buffer = buffer_start; /* Allocate for one, which will allow not to realloc 90% of the time */ git_array_init_to_size(commit->parent_ids, 1); GITERR_CHECK_ARRAY(commit->parent_ids); /* The tree is always the first field */ if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0) goto bad_buffer; /* * TODO: commit grafts! */ while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) { git_oid *new_id = git_array_alloc(commit->parent_ids); GITERR_CHECK_ALLOC(new_id); git_oid_cpy(new_id, &parent_id); } commit->author = git__malloc(sizeof(git_signature)); GITERR_CHECK_ALLOC(commit->author); if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0) return -1; /* Some tools create multiple author fields, ignore the extra ones */ while (!git__prefixncmp(buffer, buffer_end - buffer, "author ")) { if (git_signature__parse(&dummy_sig, &buffer, buffer_end, "author ", '\n') < 0) return -1; git__free(dummy_sig.name); git__free(dummy_sig.email); } /* Always parse the committer; we need the commit time */ commit->committer = git__malloc(sizeof(git_signature)); GITERR_CHECK_ALLOC(commit->committer); if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0) return -1; /* Parse add'l header entries */ while (buffer < buffer_end) { const char *eoln = buffer; if (buffer[-1] == '\n' && buffer[0] == '\n') break; while (eoln < buffer_end && *eoln != '\n') ++eoln; if (git__prefixncmp(buffer, buffer_end - buffer, "encoding ") == 0) { buffer += strlen("encoding "); commit->message_encoding = git__strndup(buffer, eoln - buffer); GITERR_CHECK_ALLOC(commit->message_encoding); } if (eoln < buffer_end && *eoln == '\n') ++eoln; buffer = eoln; } header_len = buffer - buffer_start; commit->raw_header = git__strndup(buffer_start, header_len); GITERR_CHECK_ALLOC(commit->raw_header); /* point "buffer" to data after header, +1 for the final LF */ buffer = buffer_start + header_len + 1; /* extract commit message */ if (buffer <= buffer_end) commit->raw_message = git__strndup(buffer, buffer_end - buffer); else commit->raw_message = git__strdup(""); GITERR_CHECK_ALLOC(commit->raw_message); return 0; bad_buffer: giterr_set(GITERR_OBJECT, "failed to parse bad commit object"); return -1; }
void test_submodule_modify__edit_and_save(void) { git_submodule *sm1, *sm2; char *old_url; git_submodule_ignore_t old_ignore; git_submodule_update_t old_update; git_repository *r2; int old_fetchrecurse; cl_git_pass(git_submodule_lookup(&sm1, g_repo, "sm_changed_head")); old_url = git__strdup(git_submodule_url(sm1)); /* modify properties of submodule */ cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL)); old_ignore = git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED); old_update = git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE); old_fetchrecurse = git_submodule_set_fetch_recurse_submodules(sm1, 1); cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm1)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm1)); /* revert without saving (and confirm setters return old value) */ cl_git_pass(git_submodule_set_url(sm1, old_url)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_DEFAULT)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_DEFAULT)); cl_assert_equal_i( 1, git_submodule_set_fetch_recurse_submodules(sm1, old_fetchrecurse)); /* check that revert was successful */ cl_assert_equal_s(old_url, git_submodule_url(sm1)); cl_assert_equal_i((int)old_ignore, (int)git_submodule_ignore(sm1)); cl_assert_equal_i((int)old_update, (int)git_submodule_update(sm1)); cl_assert_equal_i( old_fetchrecurse, git_submodule_fetch_recurse_submodules(sm1)); /* modify properties of submodule (again) */ cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL)); git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED); git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE); git_submodule_set_fetch_recurse_submodules(sm1, 1); /* call save */ cl_git_pass(git_submodule_save(sm1)); /* attempt to "revert" values */ git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_DEFAULT); git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_DEFAULT); /* but ignore and update should NOT revert because the DEFAULT * should now be the newly saved value... */ cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm1)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm1)); /* call reload and check that the new values are loaded */ cl_git_pass(git_submodule_reload(sm1)); cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm1)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm1)); /* open a second copy of the repo and compare submodule */ cl_git_pass(git_repository_open(&r2, "submod2")); cl_git_pass(git_submodule_lookup(&sm2, r2, "sm_changed_head")); cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm2)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm2)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm2)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm2)); git_repository_free(r2); git__free(old_url); }
static int _git_ssh_setup_conn( ssh_subtransport *t, const char *url, const char *cmd, git_smart_subtransport_stream **stream) { char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL; const char *default_port="22"; int auth_methods, error = 0; ssh_stream *s; git_cred *cred = NULL; LIBSSH2_SESSION* session=NULL; LIBSSH2_CHANNEL* channel=NULL; *stream = NULL; if (ssh_stream_alloc(t, url, cmd, stream) < 0) return -1; s = (ssh_stream *)*stream; if (!git__prefixcmp(url, prefix_ssh)) { if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0) goto on_error; } else { if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0) goto on_error; port = git__strdup(default_port); GITERR_CHECK_ALLOC(port); } /* we need the username to ask for auth methods */ if (!user) { if ((error = request_creds(&cred, t, NULL, GIT_CREDTYPE_USERNAME)) < 0) goto on_error; user = git__strdup(((git_cred_username *) cred)->username); cred->free(cred); cred = NULL; if (!user) goto on_error; } else if (user && pass) { if ((error = git_cred_userpass_plaintext_new(&cred, user, pass)) < 0) goto on_error; } if ((error = gitno_connect(&s->socket, host, port, 0)) < 0) goto on_error; if ((error = _git_ssh_session_create(&session, s->socket)) < 0) goto on_error; if ((error = list_auth_methods(&auth_methods, session, user)) < 0) goto on_error; error = GIT_EAUTH; /* if we already have something to try */ if (cred && auth_methods & cred->credtype) error = _git_ssh_authenticate_session(session, cred); while (error == GIT_EAUTH) { if (cred) { cred->free(cred); cred = NULL; } if ((error = request_creds(&cred, t, user, auth_methods)) < 0) goto on_error; if (strcmp(user, git_cred__username(cred))) { giterr_set(GITERR_SSH, "username does not match previous request"); error = -1; goto on_error; } error = _git_ssh_authenticate_session(session, cred); } if (error < 0) goto on_error; channel = libssh2_channel_open_session(session); if (!channel) { error = -1; ssh_error(session, "Failed to open SSH channel"); goto on_error; } libssh2_channel_set_blocking(channel, 1); s->session = session; s->channel = channel; t->current_stream = s; if (cred) cred->free(cred); git__free(host); git__free(port); git__free(path); git__free(user); git__free(pass); return 0; on_error: s->session = NULL; s->channel = NULL; t->current_stream = NULL; if (*stream) ssh_stream_free(*stream); if (cred) cred->free(cred); git__free(host); git__free(port); git__free(user); git__free(pass); if (session) libssh2_session_free(session); return error; }
int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) { git_buf buf = GIT_BUF_INIT; size_t j, pos; git_remote_head key; const char* formatters[] = { GIT_REFS_DIR "%s", GIT_REFS_TAGS_DIR "%s", GIT_REFS_HEADS_DIR "%s", NULL }; git_refspec *cur = git__calloc(1, sizeof(git_refspec)); GITERR_CHECK_ALLOC(cur); cur->force = spec->force; cur->push = spec->push; cur->pattern = spec->pattern; cur->matching = spec->matching; cur->string = git__strdup(spec->string); /* shorthand on the lhs */ if (git__prefixcmp(spec->src, GIT_REFS_DIR)) { for (j = 0; formatters[j]; j++) { git_buf_clear(&buf); if (git_buf_printf(&buf, formatters[j], spec->src) < 0) return -1; key.name = (char *) git_buf_cstr(&buf); if (!git_vector_search(&pos, refs, &key)) { /* we found something to match the shorthand, set src to that */ cur->src = git_buf_detach(&buf); } } } /* No shorthands found, copy over the name */ if (cur->src == NULL && spec->src != NULL) { cur->src = git__strdup(spec->src); GITERR_CHECK_ALLOC(cur->src); } if (spec->dst && git__prefixcmp(spec->dst, GIT_REFS_DIR)) { /* if it starts with "remotes" then we just prepend "refs/" */ if (!git__prefixcmp(spec->dst, "remotes/")) { git_buf_puts(&buf, GIT_REFS_DIR); } else { git_buf_puts(&buf, GIT_REFS_HEADS_DIR); } if (git_buf_puts(&buf, spec->dst) < 0) return -1; cur->dst = git_buf_detach(&buf); } git_buf_free(&buf); if (cur->dst == NULL && spec->dst != NULL) { cur->dst = git__strdup(spec->dst); GITERR_CHECK_ALLOC(cur->dst); } return git_vector_insert(out, cur); }
int git_filebuf_open(git_filebuf *file, const char *path, int flags) { int compression; size_t path_len; /* opening an already open buffer is a programming error; * assert that this never happens instead of returning * an error code */ assert(file && path && file->buffer == NULL); memset(file, 0x0, sizeof(git_filebuf)); if (flags & GIT_FILEBUF_DO_NOT_BUFFER) file->do_not_buffer = true; file->buf_size = WRITE_BUFFER_SIZE; file->buf_pos = 0; file->fd = -1; file->last_error = BUFERR_OK; /* Allocate the main cache buffer */ if (!file->do_not_buffer) { file->buffer = git__malloc(file->buf_size); GITERR_CHECK_ALLOC(file->buffer); } /* If we are hashing on-write, allocate a new hash context */ if (flags & GIT_FILEBUF_HASH_CONTENTS) { file->digest = git_hash_new_ctx(); GITERR_CHECK_ALLOC(file->digest); } compression = flags >> GIT_FILEBUF_DEFLATE_SHIFT; /* If we are deflating on-write, */ if (compression != 0) { /* Initialize the ZLib stream */ if (deflateInit(&file->zs, compression) != Z_OK) { giterr_set(GITERR_ZLIB, "Failed to initialize zlib"); goto cleanup; } /* Allocate the Zlib cache buffer */ file->z_buf = git__malloc(file->buf_size); GITERR_CHECK_ALLOC(file->z_buf); /* Never flush */ file->flush_mode = Z_NO_FLUSH; file->write = &write_deflate; } else { file->write = &write_normal; } /* If we are writing to a temp file */ if (flags & GIT_FILEBUF_TEMPORARY) { git_buf tmp_path = GIT_BUF_INIT; /* Open the file as temporary for locking */ file->fd = git_futils_mktmp(&tmp_path, path); if (file->fd < 0) { git_buf_free(&tmp_path); goto cleanup; } file->fd_is_open = true; /* No original path */ file->path_original = NULL; file->path_lock = git_buf_detach(&tmp_path); GITERR_CHECK_ALLOC(file->path_lock); } else { path_len = strlen(path); /* Save the original path of the file */ file->path_original = git__strdup(path); GITERR_CHECK_ALLOC(file->path_original); /* create the locking path by appending ".lock" to the original */ file->path_lock = git__malloc(path_len + GIT_FILELOCK_EXTLENGTH); GITERR_CHECK_ALLOC(file->path_lock); memcpy(file->path_lock, file->path_original, path_len); memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH); /* open the file for locking */ if (lock_file(file, flags) < 0) goto cleanup; } return 0; cleanup: git_filebuf_cleanup(file); return -1; }
static int cb__reflist_add(const char *ref, void *data) { char *name = git__strdup(ref); GITERR_CHECK_ALLOC(name); return git_vector_insert((git_vector *)data, name); }
static int _git_ssh_setup_conn( ssh_subtransport *t, const char *url, const char *cmd, git_smart_subtransport_stream **stream) { char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL; const char *default_port="22"; ssh_stream *s; LIBSSH2_SESSION* session=NULL; LIBSSH2_CHANNEL* channel=NULL; *stream = NULL; if (ssh_stream_alloc(t, url, cmd, stream) < 0) return -1; s = (ssh_stream *)*stream; if (!git__prefixcmp(url, prefix_ssh)) { if (gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port) < 0) goto on_error; } else { if (git_ssh_extract_url_parts(&host, &user, url) < 0) goto on_error; port = git__strdup(default_port); GITERR_CHECK_ALLOC(port); } if (gitno_connect(&s->socket, host, port, 0) < 0) goto on_error; if (user && pass) { if (git_cred_userpass_plaintext_new(&t->cred, user, pass) < 0) goto on_error; } else if (t->owner->cred_acquire_cb) { if (t->owner->cred_acquire_cb( &t->cred, t->owner->url, user, GIT_CREDTYPE_USERPASS_PLAINTEXT | GIT_CREDTYPE_SSH_KEY | GIT_CREDTYPE_SSH_CUSTOM, t->owner->cred_acquire_payload) < 0) goto on_error; if (!t->cred) { giterr_set(GITERR_SSH, "Callback failed to initialize SSH credentials"); goto on_error; } } else { giterr_set(GITERR_SSH, "Cannot set up SSH connection without credentials"); goto on_error; } assert(t->cred); if (!user && !git_cred_has_username(t->cred)) { giterr_set_str(GITERR_NET, "Cannot authenticate without a username"); goto on_error; } if (_git_ssh_session_create(&session, s->socket) < 0) goto on_error; if (_git_ssh_authenticate_session(session, user, t->cred) < 0) goto on_error; channel = libssh2_channel_open_session(session); if (!channel) { ssh_error(session, "Failed to open SSH channel"); goto on_error; } libssh2_channel_set_blocking(channel, 1); s->session = session; s->channel = channel; t->current_stream = s; git__free(host); git__free(port); git__free(path); git__free(user); git__free(pass); return 0; on_error: s->session = NULL; s->channel = NULL; t->current_stream = NULL; if (*stream) ssh_stream_free(*stream); git__free(host); git__free(port); git__free(user); git__free(pass); if (session) libssh2_session_free(session); return -1; }
static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; BOOL peerdist = FALSE; int error = -1; unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; size_t i; const git_proxy_options *proxy_opts; /* Prepare URL */ git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url); if (git_buf_oom(&buf)) return -1; /* Convert URL to wide characters */ if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert string to wide form"); goto on_error; } /* Establish request */ s->request = WinHttpOpenRequest( t->connection, s->verb, s->request_uri, NULL, WINHTTP_NO_REFERER, types, t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0); if (!s->request) { giterr_set(GITERR_OS, "failed to open request"); goto on_error; } if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) { giterr_set(GITERR_OS, "failed to set timeouts for WinHTTP"); goto on_error; } proxy_opts = &t->owner->proxy; if (proxy_opts->type == GIT_PROXY_AUTO) { /* Set proxy if necessary */ if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0) goto on_error; } else if (proxy_opts->type == GIT_PROXY_SPECIFIED) { proxy_url = git__strdup(proxy_opts->url); GITERR_CHECK_ALLOC(proxy_url); } if (proxy_url) { git_buf processed_url = GIT_BUF_INIT; WINHTTP_PROXY_INFO proxy_info; wchar_t *proxy_wide; if (!git__prefixcmp(proxy_url, SCHEME_HTTP)) { t->proxy_connection_data.use_ssl = false; } else if (!git__prefixcmp(proxy_url, SCHEME_HTTPS)) { t->proxy_connection_data.use_ssl = true; } else { giterr_set(GITERR_NET, "invalid URL: '%s'", proxy_url); return -1; } gitno_connection_data_free_ptrs(&t->proxy_connection_data); if ((error = gitno_extract_url_parts(&t->proxy_connection_data.host, &t->proxy_connection_data.port, NULL, &t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0) goto on_error; if (t->proxy_connection_data.user && t->proxy_connection_data.pass) { if (t->proxy_cred) { t->proxy_cred->free(t->proxy_cred); } if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0) goto on_error; } if (t->proxy_connection_data.use_ssl) git_buf_PUTS(&processed_url, SCHEME_HTTPS); else git_buf_PUTS(&processed_url, SCHEME_HTTP); git_buf_puts(&processed_url, t->proxy_connection_data.host); if (t->proxy_connection_data.port) git_buf_printf(&processed_url, ":%s", t->proxy_connection_data.port); if (git_buf_oom(&processed_url)) { giterr_set_oom(); error = -1; goto on_error; } /* Convert URL to wide characters */ error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr); git_buf_free(&processed_url); if (error < 0) goto on_error; proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy_info.lpszProxy = proxy_wide; proxy_info.lpszProxyBypass = NULL; if (!WinHttpSetOption(s->request, WINHTTP_OPTION_PROXY, &proxy_info, sizeof(WINHTTP_PROXY_INFO))) { giterr_set(GITERR_OS, "failed to set proxy"); git__free(proxy_wide); goto on_error; } git__free(proxy_wide); if (t->proxy_cred) { if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) { if ((error = apply_userpass_credential_proxy(s->request, t->proxy_cred)) < 0) goto on_error; } } } /* Disable WinHTTP redirects so we can handle them manually. Why, you ask? * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae */ if (!WinHttpSetOption(s->request, WINHTTP_OPTION_DISABLE_FEATURE, &disable_redirects, sizeof(disable_redirects))) { giterr_set(GITERR_OS, "failed to disable redirects"); goto on_error; } /* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP * adds itself. This option may not be supported by the underlying * platform, so we do not error-check it */ WinHttpSetOption(s->request, WINHTTP_OPTION_PEERDIST_EXTENSION_STATE, &peerdist, sizeof(peerdist)); /* Send Pragma: no-cache header */ if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } if (post_verb == s->verb) { /* Send Content-Type and Accept headers -- only necessary on a POST */ git_buf_clear(&buf); if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert content-type to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } git_buf_clear(&buf); if (git_buf_printf(&buf, "Accept: application/x-git-%s-result", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert accept header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } for (i = 0; i < t->owner->custom_headers.count; i++) { if (t->owner->custom_headers.strings[i]) { git_buf_clear(&buf); git_buf_puts(&buf, t->owner->custom_headers.strings[i]); if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert custom header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } } /* If requested, disable certificate validation */ if (t->connection_data.use_ssl) { int flags; if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) goto on_error; } /* If we have a credential on the subtransport, apply it to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && apply_userpass_credential(s->request, t->auth_mechanisms, t->cred) < 0) goto on_error; else if (t->cred && t->cred->credtype == GIT_CREDTYPE_DEFAULT && apply_default_credentials(s->request, t->auth_mechanisms) < 0) goto on_error; /* If no other credentials have been applied and the URL has username and * password, use those */ if (!t->cred && t->connection_data.user && t->connection_data.pass) { if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0) goto on_error; if (apply_userpass_credential(s->request, GIT_WINHTTP_AUTH_BASIC, t->url_cred) < 0) goto on_error; } /* We've done everything up to calling WinHttpSendRequest. */ error = 0; on_error: if (error < 0) winhttp_stream_close(s); git__free(proxy_url); git_buf_free(&buf); return error; }