summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2024-09-27finalize_object_file(): implement collision checkTaylor Blau3-10/+89
We've had "FIXME!!! Collision check here ?" in finalize_object_file() since aac1794132 (Improve sha1 object file writing., 2005-05-03). That is, when we try to write a file with the same name, we assume the on-disk contents are the same and blindly throw away the new copy. One of the reasons we never implemented this is because the files it moves are all named after the cryptographic hash of their contents (either loose objects, or packs which have their hash in the name these days). So we are unlikely to see such a collision by accident. And even though there are weaknesses in sha1, we assume they are mitigated by our use of sha1dc. So while it's a theoretical concern now, it hasn't been a priority. However, if we start using weaker hashes for pack checksums and names, this will become a practical concern. So in preparation, let's actually implement a byte-for-byte collision check. The new check will cause the write of new differing content to be a failure, rather than a silent noop, and we'll retain the temporary file on disk. If there's no collision present, we'll clean up the temporary file as usual after either rename()-ing or link()-ing it into place. Note that this may cause some extra computation when the files are in fact identical, but this should happen rarely. Loose objects are exempt from this check, and the collision check may be skipped by calling the _flags variant of this function with the FOF_SKIP_COLLISION_CHECK bit set. This is done for a couple of reasons: - We don't treat the hash of the loose object file's contents as a checksum, since the same loose object can be stored using different bytes on disk (e.g., when adjusting core.compression, using a different version of zlib, etc.). This is fundamentally different from cases where finalize_object_file() is operating over a file which uses the hash value as a checksum of the contents. In other words, a pair of identical loose objects can be stored using different bytes on disk, and that should not be treated as a collision. - We already use the path of the loose object as its hash value / object name, so checking for collisions at the content level doesn't add anything. Adding a content-level collision check would have to happen at a higher level than in finalize_object_file(), since (avoiding race conditions) writing an object loose which already exists in the repository will prevent us from even reaching finalize_object_file() via the object freshening code. There is a collision check in index-pack via its `check_collision()` function, but there isn't an analogous function in unpack-objects, which just feeds the result to write_object_file(). So skipping the collision check here does not change for better or worse the hardness of loose object writes. As a small note related to the latter bullet point above, we must teach the tmp-objdir routines to similarly skip the content-level collision checks when calling migrate_one() on a loose object file, which we do by setting the FOF_SKIP_COLLISION_CHECK bit when we are inside of a loose object shard. Co-authored-by: Jeff King <peff@peff.net> Signed-off-by: Jeff King <peff@peff.net> Helped-by: Elijah Newren <newren@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27finalize_object_file(): refactor unlink_or_warn() placementTaylor Blau1-1/+6
As soon as we've tried to link() a temporary object into place, we then unlink() the tempfile immediately, whether we were successful or not. For the success case, this is because we no longer need the old file (it's now linked into place). For the error case, there are two outcomes. Either we got EEXIST, in which case we consider the collision to be a noop. Or we got a system error, in which we case we are just cleaning up after ourselves. Using a single line for all of these cases has some problems: - in the error case, our unlink() may clobber errno, which we use in the error message - for the collision case, there's a FIXME that indicates we should do a collision check. In preparation for implementing that, we'll need to actually hold on to the file. Split these three cases into their own calls to unlink_or_warn(). This is more verbose, but lets us do the right thing in each case. Co-authored-by: Jeff King <peff@peff.net> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27finalize_object_file(): check for name collision before renamingTaylor Blau1-2/+6
We prefer link()/unlink() to rename() for object files, with the idea that we should prefer the data that is already on disk to what is incoming. But we may fall back to rename() if the user has configured us to do so, or if the filesystem seems not to support cross-directory links. This loses the "prefer what is on disk" property. We can mitigate this somewhat by trying to stat() the destination filename before doing the rename. This is racy, since the object could be created between the stat() and rename() calls. But in practice it is expanding the definition of "what is already on disk" to be the point that the function is called. That is enough to deal with any potential attacks where an attacker is trying to collide hashes with what's already in the repository. Co-authored-by: Jeff King <peff@peff.net> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27diffcore-break: fix leaking filespecs when merging broken pairsPatrick Steinhardt6-2/+9
When merging file pairs after they have been broken up we queue a new file pair and discard the broken-up ones. The newly-queued file pair reuses one filespec of the broken up pairs each, where the respective other filespec gets discarded. But we only end up freeing the filespec's data, not the filespec itself, and thus leak memory. Fix these leaks by using `free_filespec()` instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27revision: fix leaking parents when simplifying commitsPatrick Steinhardt7-0/+12
When simplifying commits, e.g. because they are treesame with their parents, we unset the commit's parent pointers but never free them. Plug the resulting memory leaks. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/maintenance: fix leak in `get_schedule_cmd()`Patrick Steinhardt2-47/+81
The `get_schedule_cmd()` function allows us to override the schedule command with a specific test command such that we can verify the underlying logic in a platform-independent way. Its memory management is somewhat wild though, because it basically gives up and assigns an allocated string to the string constant output pointer. While this part is marked with `UNLEAK()` to mask this, we also leak the local string lists. Rework the function such that it has a separate out parameter. If set, we will assign it the final allocated command. Plug the other memory leaks and create a common exit path. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/maintenance: fix leaking config stringPatrick Steinhardt1-2/+2
When parsing the maintenance strategy from config we allocate a config string, but do not free it after parsing it. Plug this leak by instead using `git_config_get_string_tmp()`, which does not allocate any memory. This leak is exposed by t7900, but plugging it alone does not make the test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27promisor-remote: fix leaking partial clone filterPatrick Steinhardt2-0/+3
The partial clone filter of a promisor remote is never free'd, causing memory leaks. Furthermore, in case multiple partial clone filters are defined for the same remote, we'd overwrite previous values without freeing them. Fix these leaks. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27grep: fix leaking grep patternPatrick Steinhardt1-1/+1
When creating a pattern via `create_grep_pat()` we allocate the pattern member of the structure regardless of the token type. But later, when we try to free the structure, we free the pattern member conditionally on the token type and thus leak memory. Plug this leak. The leak is exposed by t7814, but plugging it alone does not make the whole test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27submodule: fix leaking submodule ODB pathsPatrick Steinhardt1-2/+2
In `add_submodule_odb_by_path()` we add a path into a global string list. The list is initialized with `NODUP`, which means that we do not pass ownership of strings to the list. But we use `xstrdup()` when we insert a path, with the consequence that the string will never get free'd. Plug the leak by marking the list as `DUP`. There is only a single callsite where we insert paths anyway, and as explained above that callsite was mishandling the allocation. This leak is exposed by t7814, but plugging it does not make the whole test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27trace2: destroy context stored in thread-local storagePatrick Steinhardt1-1/+9
Each thread may have a specific context in the trace2 subsystem that we set up via thread-local storage. We do not set up a destructor for this data though, which means that the context data will leak. Plug this leak by installing a destructor. This leak is exposed by t7814, but plugging it alone does not make the whole test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/difftool: plug several trivial memory leaksPatrick Steinhardt2-0/+7
There are several leaking data structures in git-difftool(1). Plug them. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/repack: fix leaking configurationPatrick Steinhardt3-15/+45
When repacking, we assemble git-pack-objects(1) arguments both for the "normal" pack and for the cruft pack. This configuration gets populated with a bunch of `OPT_PASSTHRU` options that we end up passing to the child process. These options are allocated, but never free'd. Create a new `pack_objects_args_release()` function that releases the memory for us and call it for both sets of options. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27diffcore-order: fix leaking buffer when parsing orderfilesPatrick Steinhardt3-12/+9
In `prepare_order()` we parse an orderfile and assign it to a global array. In order to save on some allocations, we replace newlines with NUL characters and then assign pointers into the allocated buffer to that array. This can cause the buffer to be completely unreferenced though in some cases, e.g. because the order file is empty or because we had to use `xmemdupz()` to copy the lines instead of NUL-terminating them. Refactor the code to always `xmemdupz()` the strings. This is a bit simpler, and it is rather unlikely that saving a handful of allocations really matters. This allows us to release the string buffer and thus plug the memory leak. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27parse-options: free previous value of `OPTION_FILENAME`Patrick Steinhardt1-8/+14
The `OPTION_FILENAME` option always assigns either an allocated string or `NULL` to the value. In case it is passed multiple times it does not know to free the previous value though, which causes a memory leak. Refactor the function to always free the previous value. None of the sites where this option is used pass a string constant, so this change is safe. While at it, fix the argument of `fix_filename()` to be a string constant. The only reason why it's not is because we use it as an in-out-parameter, where the input is a constant and the output is not. This is weird and unnecessary, as we can just return the result instead of using the parameter for this. This leak is being hit in t7621, but plugging it alone does not make the test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27diff: fix leaking orderfile optionPatrick Steinhardt3-5/+7
The `orderfile` diff option is being assigned via `OPT_FILENAME()`, which assigns an allocated string to the variable. We never free it though, causing a memory leak. Change the type of the string to `char *` and free it to plug the leak. This also requires us to use `xstrdup()` to assign the global config to it in case it is set. This leak is being hit in t7621, but plugging it alone does not make the test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/pull: fix leaking "ff" optionPatrick Steinhardt2-4/+8
The `opt_ff` field gets populated either via `OPT_PASSTHRU` via `config_get_ff()` or when `--rebase` is passed. So we sometimes end up overriding the value in `opt_ff` with another value, but we do not free the old value, causing a memory leak. Adapt the type of the variable to be `char *` and consistently assign allocated strings to it such that we can easily free it when it is being overridden. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27dir: fix off by one errors for ignored and untracked entriesPatrick Steinhardt4-4/+5
In `treat_directory()` we perform some logic to handle ignored and untracked entries. When populating a directory with entries we first save the current number of ignored/untracked entries and then populate new entries at the end of our arrays that keep track of those entries. When we figure out that all entries have been ignored/are untracked we then remove this tail of entries from those vectors again. But there is an off by one error in both paths that causes us to not free the first ignored and untracked entries, respectively. Fix these off-by-one errors to plug the resulting leak. While at it, massage the code a bit to match our modern code style. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/submodule--helper: fix leaking remote ref on errorsPatrick Steinhardt2-4/+10
When `update_submodule()` fails we return with `die_message()`, which only causes us to print the same message as `die()` would without actually causing the process to die. We don't free memory in that case and thus leak memory. Fix the leak by freeing the remote ref. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27t/helper: fix leaking subrepo in nested submodule config helperPatrick Steinhardt2-1/+2
In the "submodule-nested-repo-config" helper we create a submodule repository and print its configuration. We do not clear the repo, causing a memory leak. Plug it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/submodule--helper: fix leaking error bufferPatrick Steinhardt2-0/+4
Fix leaking error buffer when `compute_alternate_path()` fails. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/submodule--helper: clear child process when not running itPatrick Steinhardt2-3/+8
In `runcommand_in_submodule_cb()` we may end up not executing the child command when `argv` is empty. But we still populate the command with environment variables and other things, which needs cleanup. This leads to a memory leak because we do not call `finish_command()`. Fix this by clearing the child process when we don't execute it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27submodule: fix leaking update strategyPatrick Steinhardt5-3/+12
We're not freeing the submodule update strategy command. Provide a helper function that does this for us and call it in `update_data_release()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27git: fix leaking argv when handling builtinsPatrick Steinhardt2-3/+20
In `handle_builtin()` we may end up creating an ad-hoc argv array in case we see that the command line contains the "--help" parameter. In this case we observe two memory leaks though: - We leak the `struct strvec` itself because we directly exit after calling `run_builtin()`, without bothering about any cleanups. - Even if we free'd that vector we'd end up leaking some of its strings because `run_builtin()` will modify the array. Plug both of these leaks. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/help: fix leaking `html_path` when reading config multiple timesPatrick Steinhardt1-1/+2
The `html_path` variable gets populated via `git_help_config()`, which puts an allocated string into it if its value has been configured. We do not clear the old value though, which causes a memory leak in case the config exists multiple times. Plug this leak. The leak is exposed by t0012, but plugging it alone is not sufficient to make the test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-27builtin/help: fix dangling reference to `html_path`Patrick Steinhardt1-6/+7
In `get_html_page_path()` we may end up assigning the return value of `system_path()` to the global `html_path` variable. But as we also assign the returned value to `to_free`, we will deallocate its memory upon returning from the function. Consequently, `html_path` will now point to deallocated memory. Fix this issue by instead assigning the value to a separate local variable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-26howto-maintain-git: discarding inactive topicsJunio C Hamano1-1/+16
When a patch series happened to look interesting to the maintainer but is not ready for 'next', it is applied on a topic branch and merged to the 'seen' branch to keep an eye on it. In an ideal world, the participants give reviews and the original author responds to the reviews, and such iterations may produce newer versions of the patch series, and at some point, a concensus is formed that the latest round is good enough for 'next'. Then the topic is merged to 'next' for inclusion in a future release. In a much less ideal world we live in, however, a topic sometimes get stalled. The original author may not respond to hanging review comments, may promise an update will be sent but does not manage to do so, nobody talks about the topic on the list and nobody builds upon it, etc. Following the recent trend to document and give more transparency to the decision making process, let's set a deadline to keep a topic still alive, and actively discard those that are inactive for a long period of time. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25Git 2.47-rc0v2.47.0-rc0Junio C Hamano2-1/+8
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25Merge branch 'jk/sendemail-mailmap-doc'Junio C Hamano2-0/+21
Docfix. * jk/sendemail-mailmap-doc: send-email: document --mailmap and associated configuration
2024-09-25Merge branch 'rs/diff-exit-code-binary'Junio C Hamano2-0/+9
"git diff --exit-code" ignored modified binary files, which has been corrected. * rs/diff-exit-code-binary: diff: report modified binary files as changes in builtin_diff()
2024-09-25Merge branch 'cb/ci-freebsd-13-4'Junio C Hamano1-1/+1
CI updates. * cb/ci-freebsd-13-4: ci: update FreeBSD image to 13.4
2024-09-25Merge branch 'ak/doc-sparse-co-typofix'Junio C Hamano1-1/+1
Docfix. * ak/doc-sparse-co-typofix: Documentation/technical: fix a typo
2024-09-25Merge branch 'ak/typofix-builtins'Junio C Hamano4-4/+4
Typofix. * ak/typofix-builtins: builtin: fix typos
2024-09-25The 21st batchJunio C Hamano1-0/+9
This pretty much should match what we would have in the upcoming preview of 2.47. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25Merge branch 'jc/cmake-unit-test-updates'Junio C Hamano1-14/+11
CMake adjustments for recent changes around unit tests. * jc/cmake-unit-test-updates: cmake: generalize the handling of the `UNIT_TEST_OBJS` list cmake: stop looking for `REFTABLE_TEST_OBJS` in the Makefile cmake: rename clar-related variables to avoid confusion
2024-09-25Merge branch 'ps/ci-gitlab-upgrade'Junio C Hamano1-0/+2
CI updates. * ps/ci-gitlab-upgrade: gitlab-ci: upgrade machine type of Linux runners
2024-09-25Merge branch 'ak/refs-symref-referent-typofix'Junio C Hamano1-1/+1
Typofix. * ak/refs-symref-referent-typofix: ref-filter: fix a typo
2024-09-25Merge branch 'ak/typofix-2.46-maint'Junio C Hamano19-24/+24
Typofix. * ak/typofix-2.46-maint: upload-pack: fix a typo sideband: fix a typo setup: fix a typo run-command: fix a typo revision: fix a typo refs: fix typos rebase: fix a typo read-cache-ll: fix a typo pretty: fix a typo object-file: fix a typo merge-ort: fix typos merge-ll: fix a typo http: fix a typo gpg-interface: fix a typo git-p4: fix typos git-instaweb: fix a typo fsmonitor-settings: fix a typo diffcore-rename: fix typos config.mak.dev: fix a typo
2024-09-25Merge branch 'ps/reftable-exclude'Junio C Hamano16-201/+594
The reftable backend learned to more efficiently handle exclude patterns while enumerating the refs. * ps/reftable-exclude: refs/reftable: wire up support for exclude patterns reftable/reader: make table iterator reseekable t/unit-tests: introduce reftable library Makefile: stop listing test library objects twice builtin/receive-pack: fix exclude patterns when announcing refs refs: properly apply exclude patterns to namespaced refs
2024-09-25Merge branch 'ps/apply-leakfix'Junio C Hamano6-251/+206
"git apply" had custom buffer management code that predated before use of strbuf got widespread, which has been updated to use strbuf, which also plugged some memory leaks. * ps/apply-leakfix: apply: refactor `struct image` to use a `struct strbuf` apply: rename members that track line count and allocation length apply: refactor code to drop `line_allocated` apply: introduce macro and function to init images apply: rename functions operating on `struct image` apply: reorder functions to move image-related things together
2024-09-25http-push: clean up local_refs at exitJeff King2-1/+3
We allocate a list of ref structs from get_local_heads() but never clean it up. We should do so before exiting to avoid complaints from the leak-checker. Note that we have to initialize it to NULL, because there's one code path that can jump to the cleanup label before we assign to it. Fixing this lets us mark t5540 as leak-free. Curiously building with SANITIZE=leak and gcc does not seem to find this problem, but switching to clang does. It seems like a fairly obvious leak, though. I was curious that the matching remote_refs did not have the same leak. But that is because we store the list in a global variable, so it's still reachable after we exit. Arguably we could treat it the same as future-proofing, but I didn't bother (now that the script is marked leak-free, anybody moving it to a stack variable will notice). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: clean up loose request when falling back to packedJeff King1-1/+2
In http-push's finish_request(), if we fail a loose object request we may fall back to trying a packed request. But if we do so, we leave the http_loose_object_request in place, leaking it. We can fix this by always cleaning it up. Note that the obj_req pointer here (which we'll set to NULL) is a copy of the request->userData pointer, which will now point to freed memory. But that's OK. We'll either release the parent request struct entirely, or we'll convert it into a packed request, which will overwrite userData itself. This leak is found by t5540, but it's not quite leak-free yet. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: clean up objects listJeff King1-1/+5
In http-push's get_delta(), we generate a list of pending objects by recursively processing trees and blobs, adding them to a linked list. And then we iterate over the list, adding a new request for each element. But since we iterate using the list head pointer, at the end it is NULL and all of the actual list structs have been leaked. We can fix this either by using a separate iterator and then calling object_list_free(), or by just freeing as we go. I picked the latter, just because it means we continue to shrink the list as we go, though I'm not sure it matters in practice (we call add_send_request() in the loop, but I don't think it ever looks at the global objects list itself). This fixes several leaks noticed in t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: free xml_ctx.cdata after useJeff King1-0/+2
When we ask libexpat to parse XML data, we sometimes set xml_cdata as a CharacterDataHandler callback. This fills in an allocated string in the xml_ctx struct which we never free, causing a leak. I won't pretend to understand the purpose of the field, but it looks like it is used by other callbacks during the parse. At any rate, we never look at it again after XML_Parse() returns, so we should be OK to free() it then. This fixes several leaks triggered by t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: free remote_ls_ctx.dentry_nameJeff King1-0/+1
The remote_ls_ctx struct has dentry_name string, which is filled in with a heap allocation in the handle_remote_ls_ctx() XML callback. After the XML parse is done in remote_ls(), we should free the string to avoid a leak. This fixes several leaks found by running t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: free transfer_request strbufJeff King1-1/+4
When we issue a PUT, we initialize and fill a strbuf embedded in the transfer_request struct. But we never release this buffer, causing a leak. We can fix this by adding a strbuf_release() call to release_request(). If we stopped there, then non-PUT requests would try to release a zero-initialized strbuf. This works OK in practice, but we should try to follow the strbuf API more closely. So instead, we'll always initialize the strbuf when we create the transfer_request struct. That in turn means switching the strbuf_init() call in start_put() to a simple strbuf_grow(). This leak is triggered in t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: free transfer_request dest fieldJeff King1-7/+3
When we issue a PUT request, we store the destination in the "dest" field by detaching from a strbuf. But we never free the result, causing a leak. We can address this in the release_request() function. But note that we also need to initialize it to NULL, as most other request types do not set it at all. Curiously there are _two_ functions to initialize a transfer_request struct. Adding the initialization only to add_fetch_request() seems to be enough for t5540, but I won't pretend to understand why. Rather than just adding "request->dest = NULL" in both spots, let's zero the whole struct. That addresses this problem, as well as any future ones (and it can't possibly hurt, as by definition we'd be hitting uninitialized memory previously). This fixes several leaks noticed by t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: free curl header listsJeff King1-0/+5
To pass headers to curl, we have to allocate a curl_slist linked list and then feed it to curl_easy_setopt(). But the header list is not copied by curl, and must remain valid until we are finished with the request. A few spots in http-push get this right, freeing the list after finishing the request, but many do not. In most cases the fix is simple: we set up the curl slot, start it, and then use run_active_slot() to take it to completion. After that, we don't need the headers anymore and can call curl_slist_free_all(). But one case is trickier: when we do a MOVE request, we start the request but don't immediately finish it. It's possible we could change this to be more like the other requests, but I didn't want to get into risky refactoring of this code. So we need to stick the header list into the request struct and remember to free it later. Curiously, the struct already has a headers field for this purpose! It goes all the way back to 58e60dd203 (Add support for pushing to a remote repository using HTTP/DAV, 2005-11-02), but it doesn't look like it was ever used. We can make use of it just by assigning our headers to it, and there is already code in finish_request() to clean it up. This fixes several leaks triggered by t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: free repo->url stringJeff King1-0/+1
Our repo->url string comes from str_end_url_with_slash(), which always allocates its output buffer. We should free it before exiting to avoid triggering the leak-checker. This can be seen by leak-checking t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25http-push: clear refspecs before exitingJeff King1-0/+2
We parse the command-line arguments into a refspec struct, but we never free them. We should do so before exiting to avoid triggering the leak-checker. This triggers in t5540 many times (basically every invocation of http-push). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>