1. 12 Apr, 2022 1 commit
  2. 05 Feb, 2022 1 commit
  3. 18 Jan, 2022 1 commit
  4. 14 Jan, 2022 1 commit
  5. 05 Jan, 2022 1 commit
  6. 22 Nov, 2021 2 commits
  7. 19 Nov, 2021 1 commit
  8. 11 Nov, 2021 1 commit
  9. 09 Nov, 2021 1 commit
  10. 28 Oct, 2021 1 commit
  11. 17 Oct, 2021 1 commit
    • str: introduce `git_str` for internal, `git_buf` is external · f0e693b1
      libgit2 has two distinct requirements that were previously solved by
      `git_buf`.  We require:
      
      1. A general purpose string class that provides a number of utility APIs
         for manipulating data (eg, concatenating, truncating, etc).
      2. A structure that we can use to return strings to callers that they
         can take ownership of.
      
      By using a single class (`git_buf`) for both of these purposes, we have
      confused the API to the point that refactorings are difficult and
      reasoning about correctness is also difficult.
      
      Move the utility class `git_buf` to be called `git_str`: this represents
      its general purpose, as an internal string buffer class.  The name also
      is an homage to Junio Hamano ("gitstr").
      
      The public API remains `git_buf`, and has a much smaller footprint.  It
      is generally only used as an "out" param with strict requirements that
      follow the documentation.  (Exceptions exist for some legacy APIs to
      avoid breaking callers unnecessarily.)
      
      Utility functions exist to convert a user-specified `git_buf` to a
      `git_str` so that we can call internal functions, then converting it
      back again.
      Edward Thomson committed
  12. 02 Oct, 2021 1 commit
  13. 01 Oct, 2021 1 commit
  14. 27 Sep, 2021 1 commit
  15. 04 Sep, 2021 1 commit
    • common: support custom repository extensions · a24e656a
      Allow users to specify additional repository extensions that they want
      to support.  For example, callers can specify that they support
      `preciousObjects` and then may open repositories that support
      `extensions.preciousObjects`.
      
      Similarly, callers may opt out of supporting extensions that the library
      itself supports.
      Edward Thomson committed
  16. 02 Sep, 2021 1 commit
    • util: introduce `git__strlcmp` · 1196de4f
      Introduce a utility function that compares a NUL terminated string to a
      possibly not-NUL terminated string with length.  This is similar to
      `strncmp` but with an added check to ensure that the lengths match (not
      just the `size` portion of the two strings).
      Edward Thomson committed
  17. 26 Aug, 2021 1 commit
  18. 25 Aug, 2021 1 commit
  19. 09 Aug, 2021 2 commits
  20. 07 Jul, 2021 1 commit
  21. 11 May, 2021 1 commit
  22. 14 Apr, 2021 1 commit
  23. 05 Jan, 2021 1 commit
  24. 19 Dec, 2020 1 commit
  25. 27 Nov, 2020 1 commit
  26. 11 Oct, 2020 1 commit
  27. 05 Jun, 2020 1 commit
  28. 11 May, 2020 3 commits
    • assert: allow non-int returning functions to assert · cbae1c21
      Include GIT_ASSERT_WITH_RETVAL and GIT_ASSERT_ARG_WITH_RETVAL so that
      functions that do not return int (or more precisely, where `-1` would
      not be an error code) can assert.
      
      This allows functions that return, eg, NULL on an error code to do that
      by passing the return value (in this example, `NULL`) as a second
      parameter to the GIT_ASSERT_WITH_RETVAL functions.
      Edward Thomson committed
    • assert: optionally fall-back to assert(3) · a95096ba
      Fall back to the system assert(3) in debug builds, which may aide
      in debugging.
      
      "Safe" assertions can be enabled in debug builds by setting
      GIT_ASSERT_HARD=0.  Similarly, hard assertions can be enabled in
      release builds by setting GIT_ASSERT_HARD to nonzero.
      Edward Thomson committed
    • Introduce GIT_ASSERT macros · abe2efe1
      Provide macros to replace usages of `assert`.  A true `assert` is
      punishing as a library.  Instead we should do our best to not crash.
      
      GIT_ASSERT_ARG(x) will now assert that the given argument complies to
      some format and sets an error message and returns `-1` if it does not.
      
      GIT_ASSERT(x) is for internal usage, and available as an internal
      consistency check.  It will set an error message and return `-1` in the
      event of failure.
      Edward Thomson committed
  29. 10 Mar, 2020 1 commit
  30. 10 Jan, 2020 1 commit
    • win32: fix relative symlinks pointing into dirs · 7d55bee6
      On Windows platforms, we need some logic to emulate symlink(3P) defined
      by POSIX. As unprivileged symlinks on Windows are a rather new feature,
      our current implementation is comparatively new and still has some
      rough edges in special cases.
      
      One such case is relative symlinks. While relative symlinks to files in
      the same directory work as expected, libgit2 currently fails to create
      reltaive symlinks pointing into other directories. This is due to the
      fact that we forgot to translate the Unix-style target path to
      Windows-style. Most importantly, we are currently not converting
      directory separators from "/" to "\".
      
      Fix the issue by calling `git_win32_path_canonicalize` on the target.
      Add a test that verifies our ability to create such relative links
      across directories.
      Patrick Steinhardt committed
  31. 25 Nov, 2019 1 commit
  32. 21 Sep, 2019 4 commits
    • posix: remove superseded POSIX regex wrappers · f585b129
      The old POSIX regex wrappers have been superseded by our own regexp API
      that provides a higher-level abstraction. Remove the POSIX wrappers in
      favor of the new one.
      Patrick Steinhardt committed
    • regexp: implement new regular expression API · d77378eb
      We currently support a set of different regular expression backends with
      PCRE, PCRE2, regcomp(3P) and regcomp_l(3). The current implementation of
      this is done via a simple POSIX wrapper that either directly uses
      supplied functions or that is a very small wrapper.
      
      To support PCRE and PCRE2, we use their provided <pcreposix.h> and
      <pcre2posix.h> wrappers. These wrappers are implemented in such a way
      that the accompanying libraries pcre-posix and pcre2-posix provide the
      same symbols as the libc ones, namely regcomp(3P) et al. This works out
      on some systems just fine, most importantly on glibc-based ones, where
      the regular expression functions are implemented as weak aliases and
      thus get overridden by linking in the pcre{,2}-posix library. On other
      systems we depend on the linking order of libc and pcre library, and as
      libc always comes first we will end up with the functions of the libc
      implementation. As a result, we may use the structures `regex_t` and
      `regmatch_t` declared by <pcre{,2}posix.h>, but use functions defined by
      the libc, leading to segfaults.
      
      The issue is not easily solvable. Somed distributions like Debian have
      resolved this by patching PCRE and PCRE2 to carry custom prefixes to all
      the POSIX function wrappers. But this is not supported by upstream and
      thus inherently unportable between distributions. We could instead try
      to modify linking order, but this starts becoming fragile and will not
      work e.g. when libgit2 is loaded via dlopen(3P) or similar ways. In the
      end, this means that we simply cannot use the POSIX wrappers provided by
      the PCRE libraries at all.
      
      Thus, this commit introduces a new regular expression API. The new API
      is on a tad higher level than the previous POSIX abstraction layer, as
      it tries to abstract away any non-portable flags like e.g. REG_EXTENDED,
      which has no equivalents in all of our supported backends. As there are
      no users of POSIX regular expressions that do _not_ reguest REG_EXTENDED
      this is fine to be abstracted away, though. Due to the API being
      higher-level than before, it should generally be a tad easier to use
      than the previous one.
      
      Note: ideally, the new API would've been called `git_regex_foobar` with
      a file "regex.h" and "regex.c". Unfortunately, this is currently
      impossible to implement due to naming clashes between the then-existing
      "regex.h" and <regex.h> provided by the libc. As we add the source
      directory of libgit2 to the header search path, an include of <regex.h>
      would always find our own "regex.h". Thus, we have to take the bitter
      pill of adding one more character to all the functions to disambiguate
      the includes.
      
      To improve guarantees around cross-backend compatibility, this commit
      also brings along an improved regular expression test suite
      core::regexp.
      Patrick Steinhardt committed
    • buffer: fix printing into out-of-memory buffer · 174b7a32
      Before printing into a `git_buf` structure, we always call `ENSURE_SIZE`
      first. This macro will reallocate the buffer as-needed depending on
      whether the current amount of allocated bytes is sufficient or not. If
      `asize` is big enough, then it will just do nothing, otherwise it will
      call out to `git_buf_try_grow`. But in fact, it is insufficient to only
      check `asize`.
      
      When we fail to allocate any more bytes e.g. via `git_buf_try_grow`,
      then we set the buffer's pointer to `git_buf__oom`. Note that we touch
      neither `asize` nor `size`. So if we just check `asize > targetsize`,
      then we will happily let the caller of `ENSURE_SIZE` proceed with an
      out-of-memory buffer. As a result, we will print all bytes into the
      out-of-memory buffer instead, resulting in an out-of-bounds write.
      
      Fix the issue by having `ENSURE_SIZE` verify that the buffer is not
      marked as OOM. Add a test to verify that we're not writing into the OOM
      buffer.
      Patrick Steinhardt committed
    • buffer: fix infinite loop when growing buffers · 208f1d7a
      When growing buffers, we repeatedly multiply the currently allocated
      number of bytes by 1.5 until it exceeds the requested number of bytes.
      This has two major problems:
      
          1. If the current number of bytes is tiny and one wishes to resize
             to a comparatively huge number of bytes, then we may need to loop
             thousands of times.
      
          2. If resizing to a value close to `SIZE_MAX` (which would fail
             anyway), then we probably hit an infinite loop as multiplying the
             current amount of bytes will repeatedly result in integer
             overflows.
      
      When reallocating buffers, one typically chooses values close to 1.5 to
      enable re-use of resulting memory holes in later reallocations. But
      because of this, it really only makes sense to use a factor of 1.5
      _once_, but not looping until we finally are able to fit it. Thus, we
      can completely avoid the loop and just opt for the much simpler
      algorithm of multiplying with 1.5 once and, if the result doesn't fit,
      just use the target size. This avoids both problems of looping
      extensively and hitting overflows.
      
      This commit also adds a test that would've previously resulted in an
      infinite loop.
      Patrick Steinhardt committed
  33. 23 Aug, 2019 1 commit
    • util: do not perform allocations in insertsort · 8cbef12d
      Our hand-rolled fallback sorting function `git__insertsort_r` does an
      in-place sort of the given array. As elements may not necessarily be
      pointers, it needs a way of swapping two values of arbitrary size, which
      is currently implemented by allocating a temporary buffer of the
      element's size. This is problematic, though, as the emulated `qsort`
      interface doesn't provide any return values and thus cannot signal an
      error if allocation of that temporary buffer has failed.
      
      Convert the function to swap via a temporary buffer allocated on the
      stack. Like this, it can `memcpy` contents of both elements in small
      batches without requiring a heap allocation. The buffer size has been
      chosen such that in most cases, a single iteration of copying will
      suffice. Most importantly, it can fully contain `git_oid` structures and
      pointers.
      
      Add a bunch of tests for the `git__qsort_r` interface to verify nothing
      breaks. Furthermore, this removes the declaration of `git__insertsort_r`
      and makes it static as it is not used anywhere else.
      Patrick Steinhardt committed