src/apply.c


Log

Author Commit Date CI Message
Edward Thomson c6e84bce 2020-04-05T09:49:28 apply: use GIT_ASSERT
lhchavez d0656ac8 2020-06-27T12:15:26 Make the tests run cleanly under UndefinedBehaviorSanitizer This change makes the tests run cleanly under `-fsanitize=undefined,nullability` and comprises of: * Avoids some arithmetic with NULL pointers (which UBSan does not like). * Avoids an overflow in a shift, due to an uint8_t being implicitly converted to a signed 32-bit signed integer after being shifted by a 32-bit signed integer. * Avoids a unaligned read in libgit2. * Ignores unaligned reads in the SHA1 library, since it only happens on Intel processors, where it is _still_ undefined behavior, but the semantics are moderately well-understood. Of notable omission is `-fsanitize=integer`, since there are lots of warnings in zlib and the SHA1 library which probably don't make sense to fix and I could not figure out how to silence easily. libgit2 itself also has ~100s of warnings which are mostly innocuous (e.g. use of enum constants that only fit on an `uint32_t`, but there is no way to do that in a simple fashion because the data type chosen for enumerated types is implementation-defined), and investigating whether there are worrying warnings would need reducing the noise significantly.
Edward Thomson 0f35efeb 2020-05-23T10:15:51 git_pool_init: handle failure cases Propagate failures caused by pool initialization errors.
Etienne Samson cd5e33fb 2019-11-06T11:08:23 global: DRY includes of assert.h
Drew DeVault 02af1fcb 2019-09-14T14:03:36 apply: add GIT_APPLY_CHECK This adds an option which will check if a diff is applicable without actually applying it; equivalent to git apply --check.
Edward Thomson c3a7892f 2019-09-09T13:10:24 Merge pull request #5209 from mkostyuk/apply-wrong-patch apply: Fix a patch corruption related to EOFNL handling
Max Kostyukevich de4bc2bd 2019-08-20T03:29:45 apply: git_apply_to_tree fails to apply patches that add new files git_apply_to_tree() cannot be used apply patches with new files. An attempt to apply such a patch fails because git_apply_to_tree() tries to remove a non-existing file from an old index. The solution is to modify git_apply_to_tree() to git_index_remove() when the patch states that the modified files is removed.
Max Kostyukevich 630127e3 2019-08-20T03:08:32 apply: Fix a patch corruption related to EOFNL handling Use of apply's API can lead to an improper patch application and a corruption of the modified file. The issue is caused by mishandling of the end of file changes if there are several hunks to apply. The new line character is added to a line from a wrong hunk. The solution is to modify apply_hunk() to add the newline character at the end of a line from a right hunk.
Patrick Steinhardt 63d8cd18 2019-06-16T11:17:17 apply: remove use of variadic error macro The macro `apply_err` is implemented as a variadic macro, which are not defined by C89. Convert it to a variadic function, instead.
Patrick Steinhardt e54343a4 2019-06-29T09:17:32 fileops: rename to "futils.h" to match function signatures Our file utils functions all have a "futils" prefix, e.g. `git_futils_touch`. One would thus naturally guess that their definitions and implementation would live in files "futils.h" and "futils.c", respectively, but in fact they live in "fileops.h". Rename the files to match expectations.
Erik Aigner b0893282 2019-07-11T12:12:04 patch_parse: ensure valid patch output with EOFNL
Patrick Steinhardt b30dab8f 2019-07-11T12:10:48 apply: refactor to use a switch statement
Edward Thomson 08f39208 2019-06-08T17:46:04 blob: add underscore to `from` functions The majority of functions are named `from_something` (with an underscore) instead of `fromsomething`. Update the blob functions for consistency with the rest of the library.
Edward Thomson c0dd7122 2019-06-06T16:48:04 apply: add an options struct initializer
Edward Thomson 4069f924 2019-02-22T10:56:08 Merge pull request #4901 from pks-t/pks/uniform-map-api High-level map APIs
Erik Aigner 014d4955 2019-02-20T15:30:11 apply: prevent OOB read when parsing source buffer When parsing the patch image from a string, we split the string by newlines to get a line-based view of it. To split, we use `memchr` on the buffer and limit the buffer length by the original length provided by the caller. This works just fine for the first line, but for every subsequent line we need to actually subtract the amount of bytes that we have already read. The above issue can be easily triggered by having a source buffer with at least two lines, where the second line does _not_ end in a newline. Given a string "foo\nb", we have an original length of five bytes. After having extracted the first line, we will point to 'b' and again try to `memchr(p, '\n', 5)`, resulting in an out-of-bounds read of four bytes. Fix the issue by correctly subtracting the amount of bytes already read.
Patrick Steinhardt c50a8ac2 2018-12-01T08:59:24 maps: use high-level function to check existence of keys Some callers were still using the tightly-coupled pattern of `lookup_index` and `valid_index` to verify that an entry exists in a map. Instead, use the more high-level `exists` functions to decouple map users from its implementation.
Patrick Steinhardt 03555830 2019-01-23T10:44:33 strmap: introduce high-level setter for key/value pairs Currently, one would use the function `git_strmap_insert` to insert key/value pairs into a map. This function has historically been a macro, which is why its syntax is kind of weird: instead of returning an error code directly, it instead has to be passed a pointer to where the return value shall be stored. This does not match libgit2's common idiom of directly returning error codes. Introduce a new function `git_strmap_set`, which takes as parameters the map, key and value and directly returns an error code. Convert all callers of `git_strmap_insert` to make use of it.
Patrick Steinhardt 351eeff3 2019-01-23T10:42:46 maps: use uniform lifecycle management functions Currently, the lifecycle functions for maps (allocation, deallocation, resize) are not named in a uniform way and do not have a uniform function signature. Rename the functions to fix that, and stick to libgit2's naming scheme of saying `git_foo_new`. This results in the following new interface for allocation: - `int git_<t>map_new(git_<t>map **out)` to allocate a new map, returning an error code if we ran out of memory - `void git_<t>map_free(git_<t>map *map)` to free a map - `void git_<t>map_clear(git<t>map *map)` to remove all entries from a map This commit also fixes all existing callers.
Edward Thomson ae681d3f 2019-01-21T00:49:07 apply: make update_hunk accept a size_t
Edward Thomson f673e232 2018-12-27T13:47:34 git_error: use new names in internal APIs and usage Move to the `git_error` name in the internal API for error-related functions.
lhchavez 8b599528 2019-01-08T17:26:14 Fix Linux warnings This change fixes -Wmaybe-uninitialized and -Wdeprecated-declarations warnings on Linux builds
Edward Thomson 646a94be 2018-11-18T23:15:56 Merge pull request #4847 from noahp/noahp/null-arg-fixes tests: 🌀 address two null argument instances
Noah Pendleton f127ce35 2018-11-13T08:22:25 tests: address two null argument instances Handle two null argument cases that occur in the unit tests. One is in library code, the other is in test code. Detected by running unit tests with undefined behavior sanitizer: ```bash # build mkdir build && cd build cmake -DBUILD_CLAR=ON -DCMAKE_C_FLAGS="-fsanitize=address \ -fsanitize=undefined -fstack-usage -static-libasan" .. cmake --build . # run with asan ASAN_OPTIONS="allocator_may_return_null=1" ./libgit2_clar ... ............../libgit2/src/apply.c:316:3: runtime error: null pointer \ passed as argument 1, which is declared to never be null ...................../libgit2/tests/apply/fromfile.c:46:3: runtime \ error: null pointer passed as argument 1, which is declared to never be null ```
Edward Thomson f8b9493b 2018-11-05T15:46:08 apply: test re-adding a file after removing it Ensure that we can add a file back after it's been removed. Update the renamed/deleted validation in application to not apply to deltas that are adding files to support this.
Edward Thomson 78580ad3 2018-11-05T15:34:59 apply: test modifying a file after renaming it Ensure that we cannot modify a file after it's been renamed out of the way. If multiple deltas exist for a single path, ensure that we do not attempt to modify a file after it's been renamed out of the way. To support this, we must track the paths that have been removed or renamed; add to a string map when we remove a path and remove from the string map if we recreate a path. Validate that we are not applying to a path that is in this map, unless the delta is a rename, since git supports renaming one file to two different places in two different deltas. Further, test that we cannot apply a modification delta to a path that will be created in the future by a rename (a path that does not yet exist.)
Edward Thomson 47cc5f85 2018-09-29T19:32:51 apply: introduce a hunk callback Introduce a callback to patch application that allows consumers to cancel hunk application.
Edward Thomson af33210b 2018-07-10T16:10:03 apply: introduce a delta callback Introduce a callback to the application options that allow callers to add a per-delta callback. The callback can return an error code to stop patch application, or can return a value to skip the application of a particular delta.
Edward Thomson df4258ad 2018-11-04T13:01:03 apply: handle multiple deltas to the same file git allows a patch file to contain multiple deltas to the same file: although it does not produce files in this format itself, this could be the result of concatenating two different patch files that affected the same file. git apply behaves by applying this next delta to the existing postimage of the file. We should do the same. If we have previously seen a file, and produced a postimage for it, we will load that postimage and apply the current delta to that. If we have not, get the file from the preimage.
Edward Thomson 6fecf4d1 2018-11-04T11:47:46 apply: handle exact renames Deltas containing exact renames are special; they simple indicate that a file was renamed without providing additional metadata (like the filemode). Teach the reader to provide the file mode and use the preimage's filemode in the case that the delta does not provide one.)
Edward Thomson 37b25ac5 2018-07-08T16:12:58 apply: move location to an argument, not the opts Move the location option to an argument, out of the options structure. This allows the options structure to be re-used for functions that don't need to know the location, since it's implicit in their functionality. For example, `git_apply_tree` should not take a location, but is expected to take all the other options.
Edward Thomson 2d27ddc0 2018-07-01T21:35:51 apply: use an indexwriter Place the entire `git_apply` operation inside an indexwriter, so that we lock the index before we begin performing patch application. This ensures that there are no other processes modifying things in the working directory.
Edward Thomson 813f0802 2018-07-01T15:14:36 apply: validate workdir contents match index for BOTH When applying to both the index and the working directory, ensure that the index contents match the working directory. This mirrors the requirement in `git apply --index`. This also means that - along with the prior commit that uses the working directory contents as the checkout baseline - we no longer expect conflicts during checkout. So remove the special-case error handling for checkout conflicts. (Any checkout conflict now would be because the file was actually modified between the start of patch application and the checkout.)
Edward Thomson 0f4b2f02 2018-07-01T15:13:50 reader: optionally validate index matches workdir When using a workdir reader, optionally validate that the index contents match the working directory contents.
Edward Thomson 5b8d5a22 2018-07-01T13:42:53 apply: use preimage as the checkout baseline Use the preimage as the checkout's baseline. This allows us to support applying patches to files that are modified in the working directory (those that differ from the HEAD and index). Without this, files will be reported as (checkout) conflicts. With this, we expect the on-disk data when we began the patch application (the "preimage") to be on-disk during checkout. We could have also simply used the `FORCE` flag to checkout to accomplish a similar mechanism. However, `FORCE` ignores all differences, while providing a preimage ensures that we will only overwrite the file contents that we actually read. Modify the reader interface to provide the OID to support this.
Edward Thomson dddfff77 2018-06-30T17:12:16 apply: convert checkout conflicts to apply failures When there's a checkout conflict during apply, that means that the working directory was modified in a conflicting manner and the postimage cannot be written. During application, convert this to an application failure for consistency across workdir/index/both applications.
Edward Thomson 5b66b667 2018-06-29T12:39:41 apply: when preimage file is missing, return EAPPLYFAIL The preimage file being missing entirely is simply a case of an application failure; return the correct error value for the caller.
Edward Thomson e0224121 2018-06-29T12:09:02 apply: simplify checkout vs index application Separate the concerns of applying via checkout and updating the repository's index. This results in simpler functionality and allows us to not build the temporary collection of paths in the index case.
Edward Thomson 20f8a6db 2018-06-28T17:26:21 apply: remove deleted paths from index We update the index with the new_file side of the delta, but we need to explicitly remove the old_file path in the case where an item was deleted or renamed.
Edward Thomson c3077ea0 2018-06-25T21:24:49 apply: return a specific exit code on failure Return `GIT_EAPPLYFAIL` on patch application failure so that users can determine that patch application failed due to a malformed/conflicting patch by looking at the error code.
Edward Thomson 9c34c996 2018-06-25T17:03:14 apply: handle file additions Don't attempt to read the postimage file during a file addition, simply use an empty buffer as the postimage. Also, test that we can handle file additions.
Edward Thomson 3b5378c5 2018-06-25T16:27:06 apply: handle file deletions If the file was deleted in the postimage, do not attempt to update the target. Instead, ignore it and simply allow it to stay removed in our computed postimage. Also, test that we can handle file deletions.
Edward Thomson f83bbe0a 2018-03-19T19:50:45 apply: introduce `git_apply` Introduce `git_apply`, which will take a `git_diff` and apply it to the working directory (akin to `git apply`), the index (akin to `git apply --cached`), or both (akin to `git apply --index`).
Edward Thomson 664cda6f 2018-03-19T20:10:38 apply: reimplement `git_apply_tree` with readers The generic `git_reader` interface simplifies `git_apply_tree` somewhat. Reimplement `git_apply_tree` with them.
Edward Thomson 02b1083a 2018-01-28T23:25:07 apply: introduce `git_apply_tree` Introduce `git_apply_tree`, which will apply a `git_diff` to a given `git_tree`, allowing an in-memory patch application for a repository.
Patrick Steinhardt ecf4f33a 2018-02-08T11:14:48 Convert usage of `git_buf_free` to new `git_buf_dispose`
Patrick Steinhardt 0c7f49dd 2017-06-30T13:39:01 Make sure to always include "common.h" first Next to including several files, our "common.h" header also declares various macros which are then used throughout the project. As such, we have to make sure to always include this file first in all implementation files. Otherwise, we might encounter problems or even silent behavioural differences due to macros or defines not being defined as they should be. So in fact, our header and implementation files should make sure to always include "common.h" first. This commit does so by establishing a common include pattern. Header files inside of "src" will now always include "common.h" as its first other file, separated by a newline from all the other includes to make it stand out as special. There are two cases for the implementation files. If they do have a matching header file, they will always include this one first, leading to "common.h" being transitively included as first file. If they do not have a matching header file, they instead include "common.h" as first file themselves. This fixes the outlined problems and will become our standard practice for header and source files inside of the "src/" from now on.
Edward Thomson 909d5494 2016-12-29T12:25:15 giterr_set: consistent error messages Error messages should be sentence fragments, and therefore: 1. Should not begin with a capital letter, 2. Should not conclude with punctuation, and 3. Should not end a sentence and begin a new one
Patrick Steinhardt c77a55a9 2016-11-14T10:05:31 common: use PRIuZ for size_t in `giterr_set` calls
Edward Thomson adedac5a 2016-09-02T02:03:45 diff: treat binary patches with no data special When creating and printing diffs, deal with binary deltas that have binary data specially, versus diffs that have a binary file but lack the actual binary data.
Patrick Steinhardt 274a727e 2016-08-05T10:57:42 apply: fix warning when initializing patch images
Edward Thomson 581a4d39 2016-07-14T23:32:35 apply: safety check files that dont end with eol
Edward Thomson 531be3e8 2016-07-14T22:59:37 apply: compare preimage to image Compare the preimage to the image; don't compare the preimage to itself.
Edward Thomson 53571f2f 2015-11-21T15:16:01 vector: more sensible names for `grow_at`/`shrink_at`
Edward Thomson 0267c34c 2015-09-25T10:19:50 patch application: drop unnecessary `patch_image_init`
Edward Thomson b85bd8ce 2015-09-16T11:37:03 patch: use delta's old_file/new_file members No need to replicate the old_file/new_file members, or plumb them strangely up.
Edward Thomson 804d5fe9 2015-09-11T08:37:12 patch: abstract patches into diff'ed and parsed Patches can now come from a variety of sources - either internally generated (from diffing two commits) or as the results of parsing some external data.
Edward Thomson 3149ff6f 2015-06-17T18:13:10 patch application: apply binary patches Handle the application of binary patches. Include tests that produce a binary patch (an in-memory `git_patch` object), then enusre that the patch applies correctly.
Edward Thomson 0004386f 2015-06-17T06:03:01 apply: handle empty patches When a patch is empty, simply copy the source into the destination.
Edward Thomson 7cb904ba 2014-04-01T23:58:59 Introduce git_apply_patch The beginnings of patch application from an existing (diff-created) git_patch object: applies the hunks of a git_patch to a buffer.