1. 06 Jan, 2017 2 commits
    • smart_pkt: treat empty packet lines as error · 84d30d56
      The Git protocol does not specify what should happen in the case
      of an empty packet line (that is a packet line "0004"). We
      currently indicate success, but do not return a packet in the
      case where we hit an empty line. The smart protocol was not
      prepared to handle such packets in all cases, though, resulting
      in a `NULL` pointer dereference.
      
      Fix the issue by returning an error instead. As such kind of
      packets is not even specified by upstream, this is the right
      thing to do.
      Patrick Steinhardt committed
    • smart_pkt: verify packet length exceeds PKT_LEN_SIZE · 4ac39c76
      Each packet line in the Git protocol is prefixed by a four-byte
      length of how much data will follow, which we parse in
      `git_pkt_parse_line`. The transmitted length can either be equal
      to zero in case of a flush packet or has to be at least of length
      four, as it also includes the encoded length itself. Not
      checking this may result in a buffer overflow as we directly pass
      the length to functions which accept a `size_t` length as
      parameter.
      
      Fix the issue by verifying that non-flush packets have at least a
      length of `PKT_LEN_SIZE`.
      Patrick Steinhardt committed
  2. 17 Dec, 2016 1 commit
  3. 16 Dec, 2016 2 commits
  4. 19 Nov, 2016 1 commit
  5. 03 Nov, 2016 5 commits
  6. 02 Oct, 2016 5 commits
  7. 01 Oct, 2016 24 commits
    • array: fix search for empty arrays · adfece0d
      When the array is empty `cmp` never gets set by the comparison
      function. Initialize it so we return ENOTFOUND in those cases.
      Carlos Martín Nieto committed
    • odb: only provide the empty tree · 5a9d850e
      Only provide the empty tree internally, which matches git's behavior.
      If we provide the empty blob then any users trying to write it with
      libgit2 would omit it from actually landing in the odb, which appear
      to git proper as a broken repository (missing that object).
      Edward Thomson committed
    • cmake: add curl library path · edf420f3
      The `PKG_CHECK_MODULES` function searches a pkg-config module and
      then proceeds to set various variables containing information on
      how to link to the library. In contrast to the `FIND_PACKAGE`
      function, the library path set by `PKG_CHECK_MODULES` will not
      necessarily contain linking instructions with a complete path to
      the library, though. So when a library is not installed in a
      standard location, the linker might later fail due to being
      unable to locate it.
      
      While we already honor this when configuring libssh2 by adding
      `LIBSSH2_LIBRARY_DIRS` to the link directories, we fail to do so
      for libcurl, preventing us to build libgit2 on e.g. FreeBSD. Fix
      the issue by adding the curl library directory to the linker
      search path.
      Patrick Steinhardt committed
    • git_checkout_tree options fix · e499b13c
      According to the reference the git_checkout_tree and git_checkout_head
      functions should accept NULL in the opts field
      
      This was broken since the opts field was dereferenced and thus lead to a
      crash.
      Stefan Huber committed
    • transports: http: reset `connected` flag when re-connecting transport · 12b73ff3
      When calling `http_connect` on a subtransport whose stream is already
      connected, we first close the stream in case no keep-alive is in use.
      When doing so, we do not reset the transport's connection state,
      though. Usually, this will do no harm in case the subsequent connect
      will succeed. But when the connection fails we are left with a
      substransport which is tagged as connected but which has no valid
      stream attached.
      
      Fix the issue by resetting the subtransport's connected-state when
      closing its stream in `http_connect`.
      Patrick Steinhardt committed
    • ignore: allow unignoring basenames in subdirectories · 0dea4299
      The .gitignore file allows for patterns which unignore previous
      ignore patterns. When unignoring a previous pattern, there are
      basically three cases how this is matched when no globbing is
      used:
      
      1. when a previous file has been ignored, it can be unignored by
         using its exact name, e.g.
      
         foo/bar
         !foo/bar
      
      2. when a file in a subdirectory has been ignored, it can be
         unignored by using its basename, e.g.
      
         foo/bar
         !bar
      
      3. when all files with a basename are ignored, a specific file
         can be unignored again by specifying its path in a
         subdirectory, e.g.
      
         bar
         !foo/bar
      
      The first problem in libgit2 is that we did not correctly treat
      the second case. While we verified that the negative pattern
      matches the tail of the positive one, we did not verify if it
      only matches the basename of the positive pattern. So e.g. we
      would have also negated a pattern like
      
          foo/fruz_bar
          !bar
      
      Furthermore, we did not check for the third case, where a
      basename is being unignored in a certain subdirectory again.
      
      Both issues are fixed with this commit.
      Patrick Steinhardt committed
    • stransport: do not use `git_stream_free` on uninitialized stransport · 8f342c6d
      When failing to initialize a new stransport stream, we try to
      release already allocated memory by calling out to
      `git_stream_free`, which in turn called out to the stream's
      `free` function pointer. As we only initialize the function
      pointer later on, this leads to a `NULL` pointer exception.
      
      Furthermore, plug another memory leak when failing to create the
      SSL context.
      Patrick Steinhardt committed
    • SecureTransport: handle NULL trust on success · b64722fd
      The `SSLCopyPeerTrust` call can succeed but fail to return a trust
      object if it can't load the certificate chain and thus cannot check the
      validity of a certificate. This can lead to us calling `CFRelease` on a
      `NULL` trust object, causing a crash.
      
      Handle this by returning ECERTIFICATE.
      Carlos Martín Nieto committed
    • sysdir: use the standard `init` pattern · 1fafead5
      Don't try to determine when sysdirs are uninitialized.  Instead, simply
      initialize them all at `git_libgit2_init` time and never try to
      reinitialize, except when consumers explicitly call `git_sysdir_set`.
      
      Looking at the buffer length is especially problematic, since there may
      no appropriate path for that value.  (For example, the Windows-specific
      programdata directory has no value on non-Windows machines.)
      
      Previously we would continually trying to re-lookup these values,
      which could get racy if two different threads are each calling
      `git_sysdir_get` and trying to lookup / clear the value simultaneously.
      Edward Thomson committed
    • refspec: do not set empty rhs for fetch refspecs · 85addddf
      According to git-fetch(1), "[t]he colon can be omitted when <dst>
      is empty." So according to git, the refspec "refs/heads/master"
      is the same as the refspec "refs/heads/master:" when fetching
      changes. When trying to fetch from a remote with a trailing
      colon with libgit2, though, the fetch actually fails while it
      works when the trailing colon is left out. So obviously, libgit2
      does _not_ treat these two refspec formats the same for fetches.
      
      The problem results from parsing refspecs, where the resulting
      refspec has its destination set to an empty string in the case of
      a trailing colon and to a `NULL` pointer in the case of no
      trailing colon. When passing this to our DWIM machinery, the
      empty string gets translated to "refs/heads/", which is simply
      wrong.
      
      Fix the problem by having the parsing machinery treat both cases
      the same for fetch refspecs.
      Patrick Steinhardt committed
    • repository: don't cast to `int` for no reason · d711165d
      And give it a default so that some compilers don't (unnecessarily)
      complain.
      Edward Thomson committed
    • remote: Handle missing config values when deleting a remote · 9894c7dd
      Somehow I ended up with the following in my ~/.gitconfig:
      [branch "master"]
      remote = origin
      merge = master
      rebase = true
      
      I assume something went crazy while I was running the git.git tests
      some time ago, and that I never noticed until now.
      
      This is not a good configuration, but it shouldn't cause problems. But
      it does. Specifically, if you have this in your config, and you
      perform the following set of actions:
      
      create a remote
      fetch from that remote
      create a branch off of the remote master branch called "master"
      delete the branch
      delete the remote
      
      The remote delete fails with the message "Could not find key
      'branch.master.rebase' to delete". This is because it's iterating over
      the config entries (including the ones in the global config) and
      believes that there is a master branch which must therefore have these
      config keys.
      
      https://github.com/libgit2/libgit2/issues/3856
      David Turner committed
    • blame: do not decrement commit refcount in make_origin · 49188d2b
      When we create a blame origin, we try to look up the blob that is
      to be blamed at a certain revision. When this lookup fails, e.g.
      because the file did not exist at that certain revision, we fail
      to create the blame origin and return `NULL`. The blame origin
      that we have just allocated is thereby free'd with
      `origin_decref`.
      
      The `origin_decref` function does not only decrement reference
      counts for the blame origin, though, but also for its commit and
      blob. When this is done in the error case, we will cause an
      uneven reference count for these objects. This may result in
      hard-to-debug failures at seemingly unrelated code paths, where
      we try to access these objects when they in fact have already
      been free'd.
      
      Fix the issue by refactoring `make_origin` such that we only
      allocate the object after the only function that may fail so that
      we do not have to call `origin_decref` at all. Also fix the
      `pass_blame` function, which indirectly calls `make_origin`, to
      free the commit when `make_origin` failed.
      Patrick Steinhardt committed
    • Fix repository discovery with ceiling_dirs at current directory · a200dc9e
      git only checks ceiling directories when its search ascends to a parent
      directory.  A ceiling directory matching the starting directory will not
      prevent git from finding a repository in the starting directory or a
      parent directory.  libgit2 handled the former case correctly, but
      differed from git in the latter case: given a ceiling directory matching
      the starting directory, but no repository at the starting directory,
      libgit2 would stop the search at that point rather than finding a
      repository in a parent directory.
      
      Test case using git command-line tools:
      
      /tmp$ git init x
      Initialized empty Git repository in /tmp/x/.git/
      /tmp$ cd x/
      /tmp/x$ mkdir subdir
      /tmp/x$ cd subdir/
      /tmp/x/subdir$ GIT_CEILING_DIRECTORIES=/tmp/x git rev-parse --git-dir
      fatal: Not a git repository (or any of the parent directories): .git
      /tmp/x/subdir$ GIT_CEILING_DIRECTORIES=/tmp/x/subdir git rev-parse --git-dir
      /tmp/x/.git
      
      Fix the testsuite to test this case (in one case fixing a test that
      depended on the current behavior), and then fix find_repo to handle this
      case correctly.
      
      In the process, simplify and document the logic in find_repo():
      - Separate the concepts of "currently checking a .git directory" and
        "number of iterations left before going further counts as a search"
        into two separate variables, in_dot_git and min_iterations.
      - Move the logic to handle in_dot_git and append /.git to the top of the
        loop.
      - Only search ceiling_dirs and find ceiling_offset after running out of
        min_iterations; since ceiling_offset only tracks the longest matching
        ceiling directory, if ceiling_dirs contained both the current
        directory and a parent directory, this change makes find_repo stop the
        search at the parent directory.
      Josh Triplett committed
    • cmake: do not use -fPIC for MSYS2 · c7a03369
      The MSYS2 build system automatically compiles all code with position-independent
      code. When we manually add the -fPIC flag to the compiler flags, MSYS2 will
      loudly complain about PIC being the default and thus not required.
      
      Fix the annoyance by stripping -fPIC in MSYS2 enviroments like it is already
      done for MinGW.
      Patrick Steinhardt committed
    • README: disambiguate what to distribute source of · 90ec1605
      Indicate that if you make changes to libgit2 that you must distribute
      the source _to libgit2_, not the source _of your program_.
      Edward Thomson committed
    • win32: rename pthread.{c,h} to thread.{c,h} · 5d03db81
      The old pthread-file did re-implement the pthreads API with exact symbol
      matching. As the thread-abstraction has now been split up between Unix- and
      Windows-specific files within the `git_` namespace to avoid symbol-clashes
      between libgit2 and pthreads, the rewritten wrappers have nothing to do with
      pthreads anymore.
      
      Rename the Windows-specific pthread-files to honor this change.
      Patrick Steinhardt committed