diff --git a/Documentation/RelNotes/2.56.0.adoc b/Documentation/RelNotes/2.56.0.adoc index 331f851521f574..d33dd57996a486 100644 --- a/Documentation/RelNotes/2.56.0.adoc +++ b/Documentation/RelNotes/2.56.0.adoc @@ -117,6 +117,10 @@ UI, Workflows & Features is now terminated with a newline so that Perl avoids appending its internal source location data. + * The '--shallow-file' option of 'git' command requires a value, but the + code did not check the presence of a value and instead segfaulted + without one, which has been corrected. + Performance, Internal Implementation, Development Support etc. -------------------------------------------------------------- @@ -407,6 +411,14 @@ Performance, Internal Implementation, Development Support etc. early when one side's exclusive commits in the queue are exhausted, yielding significant speedups for queries with one-sided histories. + * A handful of code paths have been corrected to check return values + from functions like curl_easy_duphandle(), deflateInit(), lseek(), + dup(), and strbuf_getline_lf(), resolving several Coverity warnings + about unchecked returns. + + * The setting of a now-unused member '.pretty_given' in the sequencer + machinery has been removed. + Fixes since v2.55 ----------------- @@ -638,3 +650,22 @@ Fixes since v2.55 replace outdated terminology, define key terms upfront, and document how comment lines in the input are treated. (merge 4515c86fd9 kh/doc-trailers later to maint). + + * The 'pack-objects' and delta-encoding code paths have been updated to + use 'size_t' instead of 'unsigned long' for object sizes and offset + limits, avoiding potential truncation issues on 64-bit Windows. + (merge d50ac11724 js/pack-objects-delta-size-t later to maint). + + * A client requesting the promisor-remote capability without a value + caused a null pointer dereference, which has been corrected by + rejecting a request without an argument. + (merge dd6b35ff71 en/serve-promisor-remote-fix later to maint). + + * Various tests in 't7900-maintenance.sh' have been updated to use a + throwaway repository, and auto-detaching of maintenance tasks is now + disabled for these tests to fix flaky races with concurrent background + maintenance jobs. + (merge 2775d8bcd1 ps/t7900-deflake-maintenance later to maint). + + * The help text for the '-l' option of 'git diff' has been updated. + (merge 764243bdf4 en/diff-l-opt-help later to maint). diff --git a/archive-zip.c b/archive-zip.c index 1a948c2f83c919..6f73ca6d588e83 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -206,7 +206,7 @@ static void *zlib_deflate_raw(void *data, unsigned long size, unsigned long *compressed_size) { git_zstream stream; - unsigned long maxsize; + size_t maxsize; void *buffer; int result; diff --git a/bisect.c b/bisect.c index d426fcd5a909e2..9cbb3dc677cc47 100644 --- a/bisect.c +++ b/bisect.c @@ -1020,10 +1020,12 @@ void read_bisect_terms(char **read_bad, char **read_good) die_errno(_("could not read file '%s'"), filename); } } else { - strbuf_getline_lf(&str, fp); + if (strbuf_getline_lf(&str, fp) == EOF) + die(_("could not read bad term from file '%s'"), filename); free(*read_bad); *read_bad = strbuf_detach(&str, NULL); - strbuf_getline_lf(&str, fp); + if (strbuf_getline_lf(&str, fp) == EOF) + die(_("could not read good term from file '%s'"), filename); free(*read_good); *read_good = strbuf_detach(&str, NULL); } diff --git a/builtin/bisect.c b/builtin/bisect.c index 93420ac0ea2a21..1cfb8a794b36ec 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -566,7 +566,7 @@ static int bisect_next_check(const struct bisect_terms *terms, return decide_next(terms, current_term, !state.nr_good, !state.nr_bad); } -static int get_terms(struct bisect_terms *terms) +static int get_terms(struct bisect_terms *terms, int file_missing_is_ok) { struct strbuf str = STRBUF_INIT; FILE *fp = NULL; @@ -574,14 +574,21 @@ static int get_terms(struct bisect_terms *terms) fp = fopen(git_path_bisect_terms(), "r"); if (!fp) { - res = -1; + res = file_missing_is_ok ? 0 : -1; goto finish; } free_terms(terms); - strbuf_getline_lf(&str, fp); + if (strbuf_getline_lf(&str, fp) == EOF) { + res = -1; + goto finish; + } terms->term_bad = strbuf_detach(&str, NULL); - strbuf_getline_lf(&str, fp); + if (strbuf_getline_lf(&str, fp) == EOF) { + res = -1; + FREE_AND_NULL(terms->term_bad); + goto finish; + } terms->term_good = strbuf_detach(&str, NULL); finish: @@ -593,7 +600,7 @@ static int get_terms(struct bisect_terms *terms) static int bisect_terms(struct bisect_terms *terms, const char *option) { - if (get_terms(terms)) + if (get_terms(terms, 0)) return error(_("no terms defined")); if (!option) { @@ -1157,7 +1164,8 @@ static int process_replay_line(struct bisect_terms *terms, struct strbuf *line) rev = word_end + strspn(word_end, " \t"); *word_end = '\0'; /* NUL-terminate the word */ - get_terms(terms); + if (get_terms(terms, 1)) + return error(_("no terms defined")); if (check_and_set_terms(terms, p)) return -1; @@ -1430,7 +1438,14 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv) fflush(stdout); saved_stdout = dup(1); - dup2(temporary_stdout_fd, 1); + if (saved_stdout < 0 || + dup2(temporary_stdout_fd, 1) < 0) { + res = error_errno(_("could not duplicate stdout")); + if (saved_stdout >= 0) + close(saved_stdout); + close(temporary_stdout_fd); + break; + } res = bisect_state(terms, 1, &new_state); @@ -1510,7 +1525,8 @@ static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *pref if (argc) return error(_("'%s' requires 0 arguments"), "git bisect next"); - get_terms(&terms); + if (get_terms(&terms, 1)) + return error(_("no terms defined")); res = bisect_next(&terms, prefix); free_terms(&terms); return res; @@ -1544,7 +1560,8 @@ static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUS struct bisect_terms terms = { 0 }; set_terms(&terms, "bad", "good"); - get_terms(&terms); + if (get_terms(&terms, 1)) + return error(_("no terms defined")); res = bisect_skip(&terms, argc, argv); free_terms(&terms); return res; @@ -1556,7 +1573,8 @@ static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix int res; struct bisect_terms terms = { 0 }; - get_terms(&terms); + if (get_terms(&terms, 1)) + return error(_("no terms defined")); res = bisect_visualize(&terms, argc, argv); free_terms(&terms); return res; @@ -1570,7 +1588,8 @@ static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE if (!argc) return error(_("'%s' failed: no command provided."), "git bisect run"); - get_terms(&terms); + if (get_terms(&terms, 1)) + return error(_("no terms defined")); res = bisect_run(&terms, argc, argv); free_terms(&terms); return res; @@ -1609,7 +1628,8 @@ int cmd_bisect(int argc, usage_with_options(git_bisect_usage, options); set_terms(&terms, "bad", "good"); - get_terms(&terms); + if (get_terms(&terms, 1)) + return error(_("no terms defined")); if (check_and_set_terms(&terms, argv[0]) || !one_of(argv[0], terms.term_good, terms.term_bad, NULL)) usage_msg_optf(_("unknown command: '%s'"), git_bisect_usage, diff --git a/builtin/config.c b/builtin/config.c index 0882899c3fbd2a..2554322317163c 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -1313,7 +1313,10 @@ static int show_editor(struct config_location_options *opts) else if (errno != EEXIST) die_errno(_("cannot create configuration file %s"), config_file); } - launch_editor(config_file, NULL, NULL); + if (launch_editor(config_file, NULL, NULL)) { + free(config_file); + return -1; + } free(config_file); return 0; diff --git a/builtin/fast-import.c b/builtin/fast-import.c index dfefbc64db2d05..fbd919982c956a 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -980,7 +980,7 @@ static int store_object( struct object_entry *e; unsigned char hdr[96]; struct object_id oid; - unsigned long hdrlen, deltalen; + unsigned long hdrlen, deltalen = 0; struct git_hash_ctx c; git_zstream s; struct repo_config_values *cfg = repo_config_values(the_repository); @@ -1016,11 +1016,13 @@ static int store_object( if (last && last->data.len && last->data.buf && last->depth < max_depth && dat->len > the_hash_algo->rawsz) { + size_t deltalen_st; delta_count_attempts_by_type[type]++; delta = diff_delta(last->data.buf, last->data.len, dat->buf, dat->len, - &deltalen, dat->len - the_hash_algo->rawsz); + &deltalen_st, dat->len - the_hash_algo->rawsz); + deltalen = cast_size_t_to_ulong(deltalen_st); } else delta = NULL; diff --git a/builtin/last-modified.c b/builtin/last-modified.c index 5478182f2e95c2..3846244dfc0cc1 100644 --- a/builtin/last-modified.c +++ b/builtin/last-modified.c @@ -290,7 +290,8 @@ static void process_parent(struct last_modified *lm, { struct bitmap *active_p; - repo_parse_commit(lm->rev.repo, parent); + if (repo_parse_commit(lm->rev.repo, parent)) + return; active_p = active_paths_for(lm, parent); /* @@ -414,12 +415,14 @@ static int last_modified_run(struct last_modified *lm) * Otherwise, make sure that 'c' isn't reachable from anything * in the '--not' queue. */ - repo_parse_commit(lm->rev.repo, c); + if (repo_parse_commit(lm->rev.repo, c)) + goto cleanup; while ((n = prio_queue_get(¬_queue))) { struct commit_list *np; - repo_parse_commit(lm->rev.repo, n); + if (repo_parse_commit(lm->rev.repo, n)) + continue; for (np = n->parents; np; np = np->next) { if (!(np->item->object.flags & PARENT2)) { diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 10d00ca7922260..1d9dc3145432ea 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -261,8 +261,8 @@ static int exclude_promisor_objects_best_effort; static int use_delta_islands; -static unsigned long delta_cache_size = 0; -static unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE; +static size_t delta_cache_size = 0; +static size_t max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE; static unsigned long cache_max_small_delta_size = 1000; static unsigned long window_memory_limit = 0; @@ -354,7 +354,8 @@ static void index_commit_for_bitmap(struct commit *commit) static void *get_delta(struct object_entry *entry) { - unsigned long size, base_size, delta_size; + unsigned long size, base_size; + size_t delta_size; void *buf, *base_buf, *delta_buf; enum object_type type; size_t size_st = 0, base_size_st = 0; @@ -488,7 +489,7 @@ static void copy_pack_data(struct hashfile *f, off_t len) { unsigned char *in; - unsigned long avail; + size_t avail; while (len) { in = use_pack(p, w_curs, offset, &avail); @@ -2259,8 +2260,7 @@ static void check_object(struct object_entry *entry, uint32_t object_index) int have_base = 0; struct object_id base_ref; struct object_entry *base_entry; - unsigned long used, used_0; - unsigned long avail; + size_t used, used_0, avail; off_t ofs; unsigned char *buf, c; enum object_type type; @@ -2688,8 +2688,8 @@ struct unpacked { unsigned depth; }; -static int delta_cacheable(unsigned long src_size, unsigned long trg_size, - unsigned long delta_size) +static int delta_cacheable(size_t src_size, size_t trg_size, + size_t delta_size) { if (max_delta_cache_size && delta_cache_size + delta_size > max_delta_cache_size) return 0; @@ -2772,8 +2772,7 @@ size_t oe_get_size_slow(struct packing_data *pack, struct pack_window *w_curs; unsigned char *buf; enum object_type type; - unsigned long used, avail; - size_t size; + size_t used, avail, size; if (e->type_ != OBJ_OFS_DELTA && e->type_ != OBJ_REF_DELTA) { size_t sz; @@ -2804,11 +2803,12 @@ size_t oe_get_size_slow(struct packing_data *pack, } static int try_delta(struct unpacked *trg, struct unpacked *src, - unsigned max_depth, unsigned long *mem_usage) + unsigned max_depth, size_t *mem_usage) { struct object_entry *trg_entry = trg->entry; struct object_entry *src_entry = src->entry; - unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; + unsigned long trg_size, src_size, sizediff, max_size, sz; + size_t delta_size; unsigned ref_depth; enum object_type type; void *delta_buf; @@ -2972,9 +2972,9 @@ static unsigned int check_delta_limit(struct object_entry *me, unsigned int n) return m; } -static unsigned long free_unpacked(struct unpacked *n) +static size_t free_unpacked(struct unpacked *n) { - unsigned long freed_mem = sizeof_delta_index(n->index); + size_t freed_mem = sizeof_delta_index(n->index); free_delta_index(n->index); n->index = NULL; if (n->data) { @@ -2991,7 +2991,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size, { uint32_t i, idx = 0, count = 0; struct unpacked *array; - unsigned long mem_usage = 0; + size_t mem_usage = 0; CALLOC_ARRAY(array, window); @@ -3701,7 +3701,7 @@ static int git_pack_config(const char *k, const char *v, return 0; } if (!strcmp(k, "pack.deltacachesize")) { - max_delta_cache_size = git_config_int(k, v, ctx->kvi); + max_delta_cache_size = git_config_size_t(k, v, ctx->kvi); return 0; } if (!strcmp(k, "pack.deltacachelimit")) { diff --git a/compat/pread.c b/compat/pread.c index 484e6d4c716ef6..ac7d058cb895db 100644 --- a/compat/pread.c +++ b/compat/pread.c @@ -7,6 +7,8 @@ ssize_t git_pread(int fd, void *buf, size_t count, off_t offset) ssize_t rc; current_offset = lseek(fd, 0, SEEK_CUR); + if (current_offset < 0) + return -1; if (lseek(fd, offset, SEEK_SET) < 0) return -1; diff --git a/config.c b/config.c index 1bdd702e7a3969..d9019e7e6c34b0 100644 --- a/config.c +++ b/config.c @@ -1271,6 +1271,15 @@ ssize_t git_config_ssize_t(const char *name, const char *value, return ret; } +size_t git_config_size_t(const char *name, const char *value, + const struct key_value_info *kvi) +{ + size_t ret; + if (!git_parse_size_t(value, &ret)) + die_bad_number(name, value, kvi); + return ret; +} + double git_config_double(const char *name, const char *value, const struct key_value_info *kvi) { diff --git a/config.h b/config.h index 31fe3e29611e11..b66dd08007c97a 100644 --- a/config.h +++ b/config.h @@ -282,6 +282,9 @@ unsigned long git_config_ulong(const char *, const char *, ssize_t git_config_ssize_t(const char *, const char *, const struct key_value_info *); +size_t git_config_size_t(const char *, const char *, + const struct key_value_info *); + /** * Identically to `git_config_double`, but for double-precision floating point * values. diff --git a/delta.h b/delta.h index eb5c6d2fdb9c51..42a211905dd2b7 100644 --- a/delta.h +++ b/delta.h @@ -14,7 +14,7 @@ struct delta_index; * using free_delta_index(). */ struct delta_index * -create_delta_index(const void *buf, unsigned long bufsize); +create_delta_index(const void *buf, size_t bufsize); /* * free_delta_index: free the index created by create_delta_index() @@ -28,7 +28,7 @@ void free_delta_index(struct delta_index *index); * * Given pointer must be what create_delta_index() returned, or NULL. */ -unsigned long sizeof_delta_index(struct delta_index *index); +size_t sizeof_delta_index(struct delta_index *index); /* * create_delta: create a delta from given index for the given buffer @@ -42,8 +42,8 @@ unsigned long sizeof_delta_index(struct delta_index *index); */ void * create_delta(const struct delta_index *index, - const void *buf, unsigned long bufsize, - unsigned long *delta_size, unsigned long max_delta_size); + const void *buf, size_t bufsize, + size_t *delta_size, size_t max_delta_size); /* * diff_delta: create a delta from source buffer to target buffer @@ -54,9 +54,9 @@ create_delta(const struct delta_index *index, * updated with its size. The returned buffer must be freed by the caller. */ static inline void * -diff_delta(const void *src_buf, unsigned long src_bufsize, - const void *trg_buf, unsigned long trg_bufsize, - unsigned long *delta_size, unsigned long max_delta_size) +diff_delta(const void *src_buf, size_t src_bufsize, + const void *trg_buf, size_t trg_bufsize, + size_t *delta_size, size_t max_delta_size) { struct delta_index *index = create_delta_index(src_buf, src_bufsize); if (index) { diff --git a/diff-delta.c b/diff-delta.c index 43c339f01061ca..7cbedeb5071bcc 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -125,14 +125,14 @@ struct unpacked_index_entry { }; struct delta_index { - unsigned long memsize; + size_t memsize; const void *src_buf; - unsigned long src_size; + size_t src_size; unsigned int hash_mask; struct index_entry *hash[FLEX_ARRAY]; }; -struct delta_index * create_delta_index(const void *buf, unsigned long bufsize) +struct delta_index * create_delta_index(const void *buf, size_t bufsize) { unsigned int i, hsize, hmask, entries, prev_val, *hash_count; const unsigned char *data, *buffer = buf; @@ -140,7 +140,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize) struct unpacked_index_entry *entry, **hash; struct index_entry *packed_entry, **packed_hash; void *mem; - unsigned long memsize; + size_t memsize; if (!buf || !bufsize) return NULL; @@ -302,7 +302,7 @@ void free_delta_index(struct delta_index *index) free(index); } -unsigned long sizeof_delta_index(struct delta_index *index) +size_t sizeof_delta_index(struct delta_index *index) { if (index) return index->memsize; @@ -318,8 +318,8 @@ unsigned long sizeof_delta_index(struct delta_index *index) void * create_delta(const struct delta_index *index, - const void *trg_buf, unsigned long trg_size, - unsigned long *delta_size, unsigned long max_size) + const void *trg_buf, size_t trg_size, + size_t *delta_size, size_t max_size) { unsigned int i, val; off_t outpos, moff; diff --git a/diff.c b/diff.c index cfe515af4e1759..414532d09f5ba3 100644 --- a/diff.c +++ b/diff.c @@ -3586,7 +3586,7 @@ static unsigned char *deflate_it(char *data, unsigned long size, unsigned long *result_size) { - int bound; + size_t bound; unsigned char *deflated; git_zstream stream; struct repo_config_values *cfg = repo_config_values(the_repository); @@ -3624,9 +3624,11 @@ static void emit_binary_diff_body(struct diff_options *o, delta = NULL; deflated = deflate_it(two->ptr, two->size, &deflate_size); if (one->size && two->size) { + size_t delta_size_st = 0; delta = diff_delta(one->ptr, one->size, two->ptr, two->size, - &delta_size, deflate_size); + &delta_size_st, deflate_size); + delta_size = cast_size_t_to_ulong(delta_size_st); if (delta) { void *to_free = delta; orig_size = delta_size; @@ -6163,7 +6165,7 @@ struct option *add_diff_options(const struct option *opts, N_("continue listing the history of a file beyond renames"), PARSE_OPT_NOARG, diff_opt_follow), OPT_INTEGER('l', NULL, &options->rename_limit, - N_("prevent rename/copy detection if the number of rename/copy targets exceeds given limit")), + N_("limit to cheap rename/copy detection if the number of rename/copy targets exceeds this value")), OPT_GROUP(N_("Diff algorithm options")), OPT_CALLBACK_F(0, "minimal", options, NULL, diff --git a/git-zlib.c b/git-zlib.c index d21adb3bf5b15e..1c94f90497ee47 100644 --- a/git-zlib.c +++ b/git-zlib.c @@ -33,7 +33,7 @@ static const char *zerr_to_string(int status) /* uLong is 32-bit on Windows, even on 64-bit systems */ #define ULONG_MAX_VALUE maximum_unsigned_value_of_type(uLong) -static inline uInt zlib_buf_cap(unsigned long len) +static inline uInt zlib_buf_cap(size_t len) { return (ZLIB_BUF_MAX < len) ? ZLIB_BUF_MAX : len; } @@ -167,9 +167,21 @@ int git_inflate(git_zstream *strm, int flush) return status; } -unsigned long git_deflate_bound(git_zstream *strm, unsigned long size) +size_t git_deflate_bound(git_zstream *strm, size_t size) { - return deflateBound(&strm->z, size); +#if SIZE_MAX > ULONG_MAX + if (size > maximum_unsigned_value_of_type(uLong)) + /* + * deflateBound() takes uLong, which is 32-bit on + * Windows. For inputs above that range, return zlib's + * stored-block formula (the conservative path it would + * itself use for an unknown stream state) plus the + * worst-case wrapper overhead. + */ + return size + (size >> 5) + (size >> 7) + (size >> 11) + + 7 + 18; +#endif + return deflateBound(&strm->z, (uLong)size); } void git_deflate_init(git_zstream *strm, int level) diff --git a/git-zlib.h b/git-zlib.h index 44380e8ad38305..9248d11ca9622c 100644 --- a/git-zlib.h +++ b/git-zlib.h @@ -5,8 +5,8 @@ typedef struct git_zstream { struct z_stream_s z; - unsigned long avail_in; - unsigned long avail_out; + size_t avail_in; + size_t avail_out; size_t total_in; size_t total_out; unsigned char *next_in; @@ -25,6 +25,6 @@ void git_deflate_end(git_zstream *); int git_deflate_abort(git_zstream *); int git_deflate_end_gently(git_zstream *); int git_deflate(git_zstream *, int flush); -unsigned long git_deflate_bound(git_zstream *, unsigned long); +size_t git_deflate_bound(git_zstream *, size_t); #endif /* GIT_ZLIB_H */ diff --git a/git.c b/git.c index e5f1811b6bb762..96df15b5cde1ed 100644 --- a/git.c +++ b/git.c @@ -304,11 +304,15 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--shallow-file")) { - (*argv)++; - (*argc)--; - setenv(GIT_SHALLOW_FILE_ENVIRONMENT, (*argv)[0], 1); + if (*argc < 2) { + fprintf(stderr, _("no file given for '%s' option\n" ), "--shallow-file"); + usage(git_usage_string); + } + setenv(GIT_SHALLOW_FILE_ENVIRONMENT, (*argv)[1], 1); if (envchanged) *envchanged = 1; + (*argv)++; + (*argc)--; } else if (!strcmp(cmd, "-C")) { if (*argc < 2) { fprintf(stderr, _("no directory given for '%s' option\n" ), "-C"); diff --git a/http-push.c b/http-push.c index 786a2e9c0d0546..b8f3faaed95a31 100644 --- a/http-push.c +++ b/http-push.c @@ -367,7 +367,7 @@ static void start_put(struct transfer_request *request) void *unpacked; size_t len; int hdrlen; - ssize_t size; + size_t size; git_zstream stream; struct repo_config_values *cfg = repo_config_values(the_repository); diff --git a/http.c b/http.c index a0d399b2745ae6..c8fcfd7693e897 100644 --- a/http.c +++ b/http.c @@ -1608,6 +1608,8 @@ struct active_request_slot *get_active_slot(void) if (!slot->curl) { slot->curl = curl_easy_duphandle(curl_default); + if (!slot->curl) + die("curl_easy_duphandle failed"); curl_session_count++; } diff --git a/oss-fuzz/fuzz-pack-headers.c b/oss-fuzz/fuzz-pack-headers.c index ef61ab577c5098..e44afe0b8d232b 100644 --- a/oss-fuzz/fuzz-pack-headers.c +++ b/oss-fuzz/fuzz-pack-headers.c @@ -9,7 +9,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) size_t len; unpack_object_header_buffer((const unsigned char *)data, - (unsigned long)size, &type, &len); + size, &type, &len); return 0; } diff --git a/pack-check.c b/pack-check.c index 1b5e26847d0b2a..c7275f4b9282f5 100644 --- a/pack-check.c +++ b/pack-check.c @@ -34,7 +34,7 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, uint32_t data_crc = crc32(0, NULL, 0); do { - unsigned long avail; + size_t avail; void *data = use_pack(p, w_curs, offset, &avail); if (avail > len) avail = len; @@ -71,7 +71,7 @@ static int verify_packfile(struct repository *r, git_hash_init(&ctx, r->hash_algo); do { - unsigned long remaining; + size_t remaining; unsigned char *in = use_pack(p, w_curs, offset, &remaining); offset += remaining; if (!pack_sig_ofs) diff --git a/packfile.c b/packfile.c index 70254573a3f4dc..7dc451bade983a 100644 --- a/packfile.c +++ b/packfile.c @@ -620,7 +620,7 @@ static int in_window(struct repository *r, struct pack_window *win, unsigned char *use_pack(struct packed_git *p, struct pack_window **w_cursor, off_t offset, - unsigned long *left) + size_t *left) { struct pack_window *win = *w_cursor; @@ -866,12 +866,11 @@ struct packfile_list_entry *packfile_store_get_packs(struct odb_source_packed *s return store->packs.head; } -unsigned long unpack_object_header_buffer(const unsigned char *buf, - unsigned long len, enum object_type *type, size_t *sizep) +size_t unpack_object_header_buffer(const unsigned char *buf, size_t len, + enum object_type *type, size_t *sizep) { unsigned shift; - size_t size, c; - unsigned long used = 0; + size_t size, c, used = 0; c = buf[used++]; *type = (c >> 4) & 7; @@ -960,8 +959,7 @@ int unpack_object_header(struct packed_git *p, size_t *sizep) { unsigned char *base; - unsigned long left; - unsigned long used; + size_t left, used; enum object_type type; /* use_pack() assures us we have [base, base + 20) available diff --git a/packfile.h b/packfile.h index f913cb3d0c589c..c1e387d6350b42 100644 --- a/packfile.h +++ b/packfile.h @@ -240,7 +240,8 @@ uint32_t get_pack_fanout(struct packed_git *p, uint32_t value); struct object_database; -unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *); +unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, + size_t *); void close_pack_windows(struct packed_git *); void close_pack(struct packed_git *); void unuse_pack(struct pack_window **); @@ -299,7 +300,8 @@ int packfile_fill_entry(struct packed_git *p, int is_pack_valid(struct packed_git *); void *unpack_entry(struct repository *r, struct packed_git *, off_t, enum object_type *, size_t *); -unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, size_t *sizep); +size_t unpack_object_header_buffer(const unsigned char *buf, size_t len, + enum object_type *type, size_t *sizep); size_t get_size_from_delta(struct packed_git *, struct pack_window **, off_t); int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, size_t *); off_t get_delta_base(struct packed_git *p, struct pack_window **w_curs, diff --git a/parse.c b/parse.c index d77f28046a0916..266bbd539be8dc 100644 --- a/parse.c +++ b/parse.c @@ -134,6 +134,15 @@ int git_parse_ssize_t(const char *value, ssize_t *ret) return 1; } +int git_parse_size_t(const char *value, size_t *ret) +{ + uintmax_t tmp; + if (!git_parse_unsigned(value, &tmp, maximum_signed_value_of_type(size_t))) + return 0; + *ret = tmp; + return 1; +} + int git_parse_double(const char *value, double *ret) { char *end; diff --git a/parse.h b/parse.h index a6dd37c4cba273..db742f35fb0e8e 100644 --- a/parse.h +++ b/parse.h @@ -4,6 +4,7 @@ int git_parse_signed(const char *value, intmax_t *ret, intmax_t max); int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max); int git_parse_ssize_t(const char *, ssize_t *); +int git_parse_size_t(const char *, size_t *); int git_parse_ulong(const char *, unsigned long *); int git_parse_uint(const char *value, unsigned int *ret); int git_parse_int(const char *value, int *ret); diff --git a/reftable/block.c b/reftable/block.c index 1fa81405d2680f..de5af03c3b7bb3 100644 --- a/reftable/block.c +++ b/reftable/block.c @@ -87,7 +87,10 @@ int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *block, REFTABLE_CALLOC_ARRAY(bw->zstream, 1); if (!bw->zstream) return REFTABLE_OUT_OF_MEMORY_ERROR; - deflateInit(bw->zstream, 9); + if (deflateInit(bw->zstream, 9) != Z_OK) { + REFTABLE_FREE_AND_NULL(bw->zstream); + return REFTABLE_ZLIB_ERROR; + } } return 0; diff --git a/reftable/writer.c b/reftable/writer.c index d969a6a0210e8b..073b9bbd8924ef 100644 --- a/reftable/writer.c +++ b/reftable/writer.c @@ -150,6 +150,7 @@ int reftable_writer_new(struct reftable_writer **out, { struct reftable_write_options opts = {0}; struct reftable_writer *wp; + int err; if (_opts) opts = *_opts; @@ -177,7 +178,12 @@ int reftable_writer_new(struct reftable_writer **out, wp->opts = opts; wp->hash_id = hash_id; wp->flush = flush_func; - writer_reinit_block_writer(wp, REFTABLE_BLOCK_TYPE_REF); + err = writer_reinit_block_writer(wp, REFTABLE_BLOCK_TYPE_REF); + if (err < 0) { + reftable_free(wp->block); + reftable_free(wp); + return err; + } *out = wp; diff --git a/sequencer.c b/sequencer.c index b85422603c56cf..65afd100d98e61 100644 --- a/sequencer.c +++ b/sequencer.c @@ -6278,7 +6278,6 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, revs.sort_order = REV_SORT_IN_GRAPH_ORDER; revs.topo_order = 1; - revs.pretty_given = 1; repo_config_get_string(the_repository, "rebase.instructionFormat", &format); if (!format || !*format) { free(format); diff --git a/serve.c b/serve.c index 2ce513cf2d5892..1b4369fb683965 100644 --- a/serve.c +++ b/serve.c @@ -46,6 +46,9 @@ static int promisor_remote_advertise(struct repository *r, static void promisor_remote_receive(struct repository *r, const char *remotes) { + if (!remotes) + die("promisor-remote capability requires an argument"); + mark_promisor_remotes_as_accepted(r, remotes); } diff --git a/t/helper/test-delta.c b/t/helper/test-delta.c index 8223a60229229e..d807afef751b48 100644 --- a/t/helper/test-delta.c +++ b/t/helper/test-delta.c @@ -32,7 +32,7 @@ int cmd__delta(int argc, const char **argv) die_errno("unable to read '%s'", argv[3]); if (argv[1][1] == 'd') { - unsigned long delta_size; + size_t delta_size; out_buf = diff_delta(from.buf, from.len, data.buf, data.len, &delta_size, 0); diff --git a/t/helper/test-pack-deltas.c b/t/helper/test-pack-deltas.c index 840797cf0dbabb..959705fecaf144 100644 --- a/t/helper/test-pack-deltas.c +++ b/t/helper/test-pack-deltas.c @@ -22,7 +22,7 @@ static unsigned long do_compress(void **pptr, unsigned long size) { git_zstream stream; void *in, *out; - unsigned long maxsize; + size_t maxsize; git_deflate_init(&stream, 1); maxsize = git_deflate_bound(&stream, size); @@ -49,7 +49,7 @@ static void write_ref_delta(struct hashfile *f, { unsigned char header[MAX_PACK_OBJECT_HEADER]; unsigned long delta_size, compressed_size, hdrlen; - size_t size, base_size; + size_t size, base_size, delta_size_st = 0; enum object_type type; void *base_buf, *delta_buf; void *buf = odb_read_object(the_repository->objects, @@ -65,7 +65,8 @@ static void write_ref_delta(struct hashfile *f, die("unable to read %s", oid_to_hex(base)); delta_buf = diff_delta(base_buf, base_size, - buf, size, &delta_size, 0); + buf, size, &delta_size_st, 0); + delta_size = cast_size_t_to_ulong(delta_size_st); compressed_size = do_compress(&delta_buf, delta_size); diff --git a/t/t0041-usage.sh b/t/t0041-usage.sh index 51af7cc0300efb..2a9c5eafcac2a6 100755 --- a/t/t0041-usage.sh +++ b/t/t0041-usage.sh @@ -107,4 +107,11 @@ test_expect_success 'for-each-ref usage error' ' test_grep "usage" actual.err ' +test_expect_success 'git --shallow-file without a value' ' + test_must_fail git --shallow-file >actual 2>actual.err && + test_line_count = 0 actual && + test_grep "no file given for " actual.err && + test_grep "usage" actual.err +' + test_done diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh index f57e36a88d3cfb..30f6c41af00397 100755 --- a/t/t5701-git-serve.sh +++ b/t/t5701-git-serve.sh @@ -71,6 +71,17 @@ test_expect_success 'request invalid capability' ' test_grep "unknown capability" err ' +test_expect_success 'promisor-remote capability requires an argument' ' + test-tool pkt-line pack >in <<-EOF && + command=ls-refs + object-format=$(test_oid algo) + promisor-remote + 0000 + EOF + test_must_fail test-tool serve-v2 --stateless-rpc 2>err in <<-EOF && agent=git/test diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 4238569b688a4c..5fbb16f0f0e59c 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -7,9 +7,6 @@ test_description='git maintenance builtin' GIT_TEST_COMMIT_GRAPH=0 GIT_TEST_MULTI_PACK_INDEX=0 -# Ensure that auto-maintenance detaches as usual. -sane_unset GIT_TEST_MAINT_AUTO_DETACH - test_lazy_prereq XMLLINT ' xmllint --version ' @@ -67,41 +64,60 @@ test_expect_success 'run [--auto|--quiet] with gc strategy' ' ' test_expect_success 'maintenance.auto config option' ' - GIT_TRACE2_EVENT="$(pwd)/default" git commit --quiet --allow-empty -m 1 && - test_subcommand git maintenance run --auto --quiet --detach in because we want to use it after * fastexport is done with it. */ fastexport->out = dup(helper->in); + if (fastexport->out < 0) + return error_errno(_("could not dup helper output fd")); strvec_push(&fastexport->args, "fast-export"); strvec_push(&fastexport->args, "--use-done-feature"); strvec_push(&fastexport->args, data->signed_tags ? @@ -1194,7 +1196,9 @@ static int push_refs_with_export(struct transport *transport, if (data->export_marks) { strbuf_addf(&buf, "%s.tmp", data->export_marks); - rename(buf.buf, data->export_marks); + if (rename(buf.buf, data->export_marks)) + warning_errno(_("could not rename '%s' to '%s'"), + buf.buf, data->export_marks); strbuf_release(&buf); }