Hello community,

here is the log from the commit of package libgit2 for openSUSE:Leap:15.2 
checked in at 2020-03-01 08:51:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/libgit2 (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.libgit2.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libgit2"

Sun Mar  1 08:51:11 2020 rev:25 rq:779603 version:0.28.4

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/libgit2/libgit2.changes        2020-01-30 
14:47:40.814815658 +0100
+++ /work/SRC/openSUSE:Leap:15.2/.libgit2.new.26092/libgit2.changes     
2020-03-01 08:51:29.277286865 +0100
@@ -1,0 +2,62 @@
+Wed Dec 11 15:58:48 UTC 2019 - Andreas Stieger <[email protected]>
+
+- libgit2 0.28.4:
+  * CVE-2019-1348: the fast-import stream command "feature
+    export-marks=path" allows writing to arbitrary file paths. As
+    libgit2 does not offer any interface for fast-import, it is not
+    susceptible to this vulnerability. (boo#1158785)
+  * CVE-2019-1349: by using NTFS 8.3 short names, backslashes or
+    alternate filesystreams, it is possible to cause submodules to
+    be written into pre-existing directories during a recursive
+    clone using git. As libgit2 rejects cloning into non-empty
+    directories by default, it is not susceptible to this
+    vulnerability. (boo#1158787)
+  * CVE-2019-1350: recursive clones may lead to arbitrary remote
+    code executing due to improper quoting of command line
+    arguments. As libgit2 uses libssh2, which does not require us
+    to perform command line parsing, it is not susceptible to this
+    vulnerability. (boo#1158788)
+  * CVE-2019-1351: Windows provides the ability to substitute
+    drive letters with arbitrary letters, including multi-byte
+    Unicode letters. To fix any potential issues arising from
+    interpreting such paths as relative paths, we have extended
+    detection of DOS drive prefixes to accomodate for such cases.
+    (boo#1158790)
+  * CVE-2019-1352: by using NTFS-style alternative file streams for
+    the ".git" directory, it is possible to overwrite parts of the
+    repository. While this has been fixed in the past for Windows,
+    the same vulnerability may also exist on other systems that
+    write to NTFS filesystems. We now reject any paths starting
+    with ".git:" on all systems. (boo#1158790)
+  * CVE-2019-1353: by using NTFS-style 8.3 short names, it was
+    possible to write to the ".git" directory and thus overwrite
+    parts of the repository, leading to possible remote code
+    execution. While this problem was already fixed in the past for
+    Windows, other systems accessing NTFS filesystems are
+    vulnerable to this issue too. We now enable NTFS protecions by
+    default on all systems to fix this attack vector. (boo#1158791)
+  * CVE-2019-1354: on Windows, backslashes are not a valid part of
+    a filename but are instead interpreted as directory separators.
+    As other platforms allowed to use such paths, it was possible
+    to write such invalid entries into a Git repository and was
+    thus an attack vector to write into the ".git" dierctory. We
+    now reject any entries starting with ".git" on all systems.
+    (boo#1158792)
+  * CVE-2019-1387: it is possible to let a submodule's git
+    directory point into a sibling's submodule directory, which may
+    result in overwriting parts of the Git repository and thus lead
+    to arbitrary command execution. As libgit2 doesn't provide any
+    way to do submodule clones natively, it is not susceptible to
+    this vulnerability. Users of libgit2 that have implemented
+    recursive submodule clones manually are encouraged to review
+    their implementation for this vulnerability. (boo#1158793)
+
+-------------------------------------------------------------------
+Wed Dec 11 13:30:43 UTC 2019 - Andreas Stieger <[email protected]>
+
+- libgit2 0.28.3:
+  * A carefully constructed commit object with a very large number
+    of parents may have lead to out-of-bounds writes or potential
+    denial of service (boo#1158981)
+
+-------------------------------------------------------------------

Old:
----
  libgit2-0.28.2.tar.gz

New:
----
  libgit2-0.28.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libgit2.spec ++++++
--- /var/tmp/diff_new_pack.PlWq7V/_old  2020-03-01 08:51:30.157288615 +0100
+++ /var/tmp/diff_new_pack.PlWq7V/_new  2020-03-01 08:51:30.161288623 +0100
@@ -19,7 +19,7 @@
 
 %define sover 28
 Name:           libgit2
-Version:        0.28.2
+Version:        0.28.4
 Release:        0
 Summary:        C git library
 License:        GPL-2.0 WITH GCC-exception-2.0

++++++ libgit2-0.28.2.tar.gz -> libgit2-0.28.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/docs/changelog.md 
new/libgit2-0.28.4/docs/changelog.md
--- old/libgit2-0.28.2/docs/changelog.md        2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/docs/changelog.md        2019-12-10 20:39:58.000000000 
+0100
@@ -1,3 +1,78 @@
+v0.28.4
+--------
+
+This is a security release fixing the following issues:
+
+- CVE-2019-1348: the fast-import stream command "feature
+  export-marks=path" allows writing to arbitrary file paths. As
+  libgit2 does not offer any interface for fast-import, it is not
+  susceptible to this vulnerability.
+
+- CVE-2019-1349: by using NTFS 8.3 short names, backslashes or
+  alternate filesystreams, it is possible to cause submodules to
+  be written into pre-existing directories during a recursive
+  clone using git. As libgit2 rejects cloning into non-empty
+  directories by default, it is not susceptible to this
+  vulnerability.
+
+- CVE-2019-1350: recursive clones may lead to arbitrary remote
+  code executing due to improper quoting of command line
+  arguments. As libgit2 uses libssh2, which does not require us
+  to perform command line parsing, it is not susceptible to this
+  vulnerability.
+
+- CVE-2019-1351: Windows provides the ability to substitute
+  drive letters with arbitrary letters, including multi-byte
+  Unicode letters. To fix any potential issues arising from
+  interpreting such paths as relative paths, we have extended
+  detection of DOS drive prefixes to accomodate for such cases.
+
+- CVE-2019-1352: by using NTFS-style alternative file streams for
+  the ".git" directory, it is possible to overwrite parts of the
+  repository. While this has been fixed in the past for Windows,
+  the same vulnerability may also exist on other systems that
+  write to NTFS filesystems. We now reject any paths starting
+  with ".git:" on all systems.
+
+- CVE-2019-1353: by using NTFS-style 8.3 short names, it was
+  possible to write to the ".git" directory and thus overwrite
+  parts of the repository, leading to possible remote code
+  execution. While this problem was already fixed in the past for
+  Windows, other systems accessing NTFS filesystems are
+  vulnerable to this issue too. We now enable NTFS protecions by
+  default on all systems to fix this attack vector.
+
+- CVE-2019-1354: on Windows, backslashes are not a valid part of
+  a filename but are instead interpreted as directory separators.
+  As other platforms allowed to use such paths, it was possible
+  to write such invalid entries into a Git repository and was
+  thus an attack vector to write into the ".git" dierctory. We
+  now reject any entries starting with ".git\" on all systems.
+
+- CVE-2019-1387: it is possible to let a submodule's git
+  directory point into a sibling's submodule directory, which may
+  result in overwriting parts of the Git repository and thus lead
+  to arbitrary command execution. As libgit2 doesn't provide any
+  way to do submodule clones natively, it is not susceptible to
+  this vulnerability. Users of libgit2 that have implemented
+  recursive submodule clones manually are encouraged to review
+  their implementation for this vulnerability.
+
+v0.28.3
+-------
+
+This is a security release fixing the following issues:
+
+* A carefully constructed commit object with a very large number
+  of parents may lead to potential out-of-bounds writes or
+  potential denial of service.
+
+* The ProgramData configuration file is always read for compatibility
+  with Git for Windows and Portable Git installations.  The ProgramData
+  location is not necessarily writable only by administrators, so we
+  now ensure that the configuration file is owned by the administrator
+  or the current user.
+
 v0.28.2
 -------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/include/git2/version.h 
new/libgit2-0.28.4/include/git2/version.h
--- old/libgit2-0.28.2/include/git2/version.h   2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/include/git2/version.h   2019-12-10 20:39:58.000000000 
+0100
@@ -7,10 +7,10 @@
 #ifndef INCLUDE_git_version_h__
 #define INCLUDE_git_version_h__
 
-#define LIBGIT2_VERSION "0.28.2"
+#define LIBGIT2_VERSION "0.28.4"
 #define LIBGIT2_VER_MAJOR 0
 #define LIBGIT2_VER_MINOR 28
-#define LIBGIT2_VER_REVISION 2
+#define LIBGIT2_VER_REVISION 4
 #define LIBGIT2_VER_PATCH 0
 
 #define LIBGIT2_SOVERSION 28
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/src/commit_list.c 
new/libgit2-0.28.4/src/commit_list.c
--- old/libgit2-0.28.2/src/commit_list.c        2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/src/commit_list.c        2019-12-10 20:39:58.000000000 
+0100
@@ -69,11 +69,15 @@
 static git_commit_list_node **alloc_parents(
        git_revwalk *walk, git_commit_list_node *commit, size_t n_parents)
 {
+       size_t bytes;
+
        if (n_parents <= PARENTS_PER_COMMIT)
                return (git_commit_list_node **)((char *)commit + 
sizeof(git_commit_list_node));
 
-       return (git_commit_list_node **)git_pool_malloc(
-               &walk->commit_pool, (uint32_t)(n_parents * 
sizeof(git_commit_list_node *)));
+       if (git__multiply_sizet_overflow(&bytes, n_parents, 
sizeof(git_commit_list_node *)))
+               return NULL;
+
+       return (git_commit_list_node **)git_pool_malloc(&walk->commit_pool, 
bytes);
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/src/config.c 
new/libgit2-0.28.4/src/config.c
--- old/libgit2-0.28.2/src/config.c     2019-05-21 09:54:19.000000000 +0200
+++ new/libgit2-0.28.4/src/config.c     2019-12-10 20:39:58.000000000 +0100
@@ -1111,8 +1111,15 @@
 
 int git_config_find_programdata(git_buf *path)
 {
+       int ret;
+
        git_buf_sanitize(path);
-       return git_sysdir_find_programdata_file(path, 
GIT_CONFIG_FILENAME_PROGRAMDATA);
+       ret = git_sysdir_find_programdata_file(path,
+                                              GIT_CONFIG_FILENAME_PROGRAMDATA);
+       if (ret != GIT_OK)
+               return ret;
+
+       return git_path_validate_system_file_ownership(path->ptr);
 }
 
 int git_config__global_location(git_buf *buf)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/src/path.c 
new/libgit2-0.28.4/src/path.c
--- old/libgit2-0.28.2/src/path.c       2019-05-21 09:54:19.000000000 +0200
+++ new/libgit2-0.28.4/src/path.c       2019-12-10 20:39:58.000000000 +0100
@@ -14,13 +14,36 @@
 #include "win32/w32_buffer.h"
 #include "win32/w32_util.h"
 #include "win32/version.h"
+#include <AclAPI.h>
 #else
 #include <dirent.h>
 #endif
 #include <stdio.h>
 #include <ctype.h>
 
-#define LOOKS_LIKE_DRIVE_PREFIX(S) (git__isalpha((S)[0]) && (S)[1] == ':')
+static int dos_drive_prefix_length(const char *path)
+{
+       int i;
+
+       /*
+        * Does it start with an ASCII letter (i.e. highest bit not set),
+        * followed by a colon?
+        */
+       if (!(0x80 & (unsigned char)*path))
+               return *path && path[1] == ':' ? 2 : 0;
+
+       /*
+        * While drive letters must be letters of the English alphabet, it is
+        * possible to assign virtually _any_ Unicode character via `subst` as
+        * a drive letter to "virtual drives". Even `1`, or `รค`. Or fun stuff
+        * like this:
+        *
+        *      subst ึ: %USERPROFILE%\Desktop
+        */
+       for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++)
+               ; /* skip first UTF-8 character */
+       return path[i] == ':' ? i + 1 : 0;
+}
 
 #ifdef GIT_WIN32
 static bool looks_like_network_computer_name(const char *path, int pos)
@@ -122,11 +145,11 @@
        GIT_UNUSED(len);
 #else
        /*
-        * Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
-        * 'C:/' here
+        * Mimic unix behavior where '/.git' returns '/': 'C:/.git'
+        * will return 'C:/' here
         */
-       if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path))
-               return 2;
+       if (dos_drive_prefix_length(path) == len)
+               return len;
 
        /*
         * Similarly checks if we're dealing with a network computer name
@@ -259,11 +282,11 @@
 
 int git_path_root(const char *path)
 {
-       int offset = 0;
+       int offset = 0, prefix_len;
 
        /* Does the root of the path look like a windows drive ? */
-       if (LOOKS_LIKE_DRIVE_PREFIX(path))
-               offset += 2;
+       if ((prefix_len = dos_drive_prefix_length(path)))
+               offset += prefix_len;
 
 #ifdef GIT_WIN32
        /* Are we dealing with a windows network path? */
@@ -1608,8 +1631,12 @@
        if (!start)
                return true;
 
-       /* Reject paths like ".git\" */
-       if (path[start] == '\\')
+       /*
+        * Reject paths that start with Windows-style directory separators
+        * (".git\") or NTFS alternate streams (".git:") and could be used
+        * to write to the ".git" directory on Windows platforms.
+        */
+       if (path[start] == '\\' || path[start] == ':')
                return false;
 
        /* Reject paths like '.git ' or '.git.' */
@@ -1621,12 +1648,21 @@
        return false;
 }
 
-GIT_INLINE(bool) only_spaces_and_dots(const char *path)
+/*
+ * Windows paths that end with spaces and/or dots are elided to the
+ * path without them for backward compatibility.  That is to say
+ * that opening file "foo ", "foo." or even "foo . . ." will all
+ * map to a filename of "foo".  This function identifies spaces and
+ * dots at the end of a filename, whether the proper end of the
+ * filename (end of string) or a colon (which would indicate a
+ * Windows alternate data stream.)
+ */
+GIT_INLINE(bool) ntfs_end_of_filename(const char *path)
 {
        const char *c = path;
 
        for (;; c++) {
-               if (*c == '\0')
+               if (*c == '\0' || *c == ':')
                        return true;
                if (*c != ' ' && *c != '.')
                        return false;
@@ -1641,13 +1677,13 @@
 
        if (name[0] == '.' && len >= dotgit_len &&
            !strncasecmp(name + 1, dotgit_name, dotgit_len)) {
-               return !only_spaces_and_dots(name + dotgit_len + 1);
+               return !ntfs_end_of_filename(name + dotgit_len + 1);
        }
 
        /* Detect the basic NTFS shortname with the first six chars */
        if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' &&
            name[7] >= '1' && name[7] <= '4')
-               return !only_spaces_and_dots(name + 8);
+               return !ntfs_end_of_filename(name + 8);
 
        /* Catch fallback names */
        for (i = 0, saw_tilde = 0; i < 8; i++) {
@@ -1669,7 +1705,7 @@
                }
        }
 
-       return !only_spaces_and_dots(name + i);
+       return !ntfs_end_of_filename(name + i);
 }
 
 GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
@@ -1803,7 +1839,7 @@
        git_repository *repo,
        unsigned int flags)
 {
-       int protectHFS = 0, protectNTFS = 0;
+       int protectHFS = 0, protectNTFS = 1;
        int error = 0;
 
        flags |= GIT_PATH_REJECT_DOT_GIT_LITERAL;
@@ -1812,16 +1848,12 @@
        protectHFS = 1;
 #endif
 
-#ifdef GIT_WIN32
-       protectNTFS = 1;
-#endif
-
        if (repo && !protectHFS)
                error = git_repository__cvar(&protectHFS, repo, 
GIT_CVAR_PROTECTHFS);
        if (!error && protectHFS)
                flags |= GIT_PATH_REJECT_DOT_GIT_HFS;
 
-       if (repo && !protectNTFS)
+       if (repo)
                error = git_repository__cvar(&protectNTFS, repo, 
GIT_CVAR_PROTECTNTFS);
        if (!error && protectNTFS)
                flags |= GIT_PATH_REJECT_DOT_GIT_NTFS;
@@ -1909,3 +1941,79 @@
                return -1;
        }
 }
+
+int git_path_validate_system_file_ownership(const char *path)
+{
+#ifndef GIT_WIN32
+       GIT_UNUSED(path);
+       return GIT_OK;
+#else
+       git_win32_path buf;
+       PSID owner_sid;
+       PSECURITY_DESCRIPTOR descriptor = NULL;
+       HANDLE token;
+       TOKEN_USER *info = NULL;
+       DWORD err, len;
+       int ret;
+
+       if (git_win32_path_from_utf8(buf, path) < 0)
+               return -1;
+
+       err = GetNamedSecurityInfoW(buf, SE_FILE_OBJECT,
+                                   OWNER_SECURITY_INFORMATION |
+                                           DACL_SECURITY_INFORMATION,
+                                   &owner_sid, NULL, NULL, NULL, &descriptor);
+
+       if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
+               ret = GIT_ENOTFOUND;
+               goto cleanup;
+       }
+
+       if (err != ERROR_SUCCESS) {
+               git_error_set(GIT_ERROR_OS, "failed to get security 
information");
+               ret = GIT_ERROR;
+               goto cleanup;
+       }
+
+       if (!IsValidSid(owner_sid)) {
+               git_error_set(GIT_ERROR_INVALID, "programdata configuration 
file owner is unknown");
+               ret = GIT_ERROR;
+               goto cleanup;
+       }
+
+       if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
+           IsWellKnownSid(owner_sid, WinLocalSystemSid)) {
+               ret = GIT_OK;
+               goto cleanup;
+       }
+
+       /* Obtain current user's SID */
+       if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) &&
+           !GetTokenInformation(token, TokenUser, NULL, 0, &len)) {
+               info = git__malloc(len);
+               GIT_ERROR_CHECK_ALLOC(info);
+               if (!GetTokenInformation(token, TokenUser, info, len, &len)) {
+                       git__free(info);
+                       info = NULL;
+               }
+       }
+
+       /*
+        * If the file is owned by the same account that is running the current
+        * process, it's okay to read from that file.
+        */
+       if (info && EqualSid(owner_sid, info->User.Sid))
+               ret = GIT_OK;
+       else {
+               git_error_set(GIT_ERROR_INVALID, "programdata configuration 
file owner is not valid");
+               ret = GIT_ERROR;
+       }
+       free(info);
+
+cleanup:
+       if (descriptor)
+               LocalFree(descriptor);
+
+       return ret;
+#endif
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/src/path.h 
new/libgit2-0.28.4/src/path.h
--- old/libgit2-0.28.2/src/path.h       2019-05-21 09:54:19.000000000 +0200
+++ new/libgit2-0.28.4/src/path.h       2019-12-10 20:39:58.000000000 +0100
@@ -647,4 +647,16 @@
  */
 int git_path_normalize_slashes(git_buf *out, const char *path);
 
+/**
+ * Validate a system file's ownership
+ *
+ * Verify that the file in question is owned by an administrator or system
+ * account, or at least by the current user.
+ *
+ * This function returns 0 if successful. If the file is not owned by any of
+ * these, or any other if there have been problems determining the file
+ * ownership, it returns -1.
+ */
+int git_path_validate_system_file_ownership(const char *path);
+
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/src/repository.h 
new/libgit2-0.28.4/src/repository.h
--- old/libgit2-0.28.2/src/repository.h 2019-05-21 09:54:19.000000000 +0200
+++ new/libgit2-0.28.4/src/repository.h 2019-12-10 20:39:58.000000000 +0100
@@ -113,7 +113,7 @@
        /* core.protectHFS */
        GIT_PROTECTHFS_DEFAULT = GIT_CVAR_FALSE,
        /* core.protectNTFS */
-       GIT_PROTECTNTFS_DEFAULT = GIT_CVAR_FALSE,
+       GIT_PROTECTNTFS_DEFAULT = GIT_CVAR_TRUE,
        /* core.fsyncObjectFiles */
        GIT_FSYNCOBJECTFILES_DEFAULT = GIT_CVAR_FALSE,
 } git_cvar_value;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/tests/checkout/nasty.c 
new/libgit2-0.28.4/tests/checkout/nasty.c
--- old/libgit2-0.28.2/tests/checkout/nasty.c   2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/tests/checkout/nasty.c   2019-12-10 20:39:58.000000000 
+0100
@@ -206,9 +206,8 @@
  */
 void test_checkout_nasty__git_tilde1(void)
 {
-#ifdef GIT_WIN32
        test_checkout_fails("refs/heads/git_tilde1", ".git/foobar");
-#endif
+       test_checkout_fails("refs/heads/git_tilde1", "git~1/foobar");
 }
 
 /* A tree that contains an entry "git~2", when we have forced the short
@@ -274,6 +273,16 @@
 #endif
 }
 
+/* A tree that contains an entry ".git::$INDEX_ALLOCATION" because NTFS
+ * will interpret that as a synonym to ".git", even when mounted via SMB
+ * on macOS.
+ */
+void test_checkout_nasty__dotgit_alternate_data_stream(void)
+{
+       test_checkout_fails("refs/heads/dotgit_alternate_data_stream", 
".git/dummy-file");
+       test_checkout_fails("refs/heads/dotgit_alternate_data_stream", 
".git::$INDEX_ALLOCATION/dummy-file");
+}
+
 /* Trees that contains entries with a tree ".git" that contain
  * byte sequences:
  * { 0xe2, 0x80, 0x8c }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/tests/clar_libgit2.h 
new/libgit2-0.28.4/tests/clar_libgit2.h
--- old/libgit2-0.28.2/tests/clar_libgit2.h     2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/tests/clar_libgit2.h     2019-12-10 20:39:58.000000000 
+0100
@@ -29,8 +29,8 @@
  * calls that are supposed to fail!
  */
 #define cl_git_fail(expr) do { \
-       git_error_clear(); \
        if ((expr) == 0) \
+               git_error_clear(), \
                cl_git_report_failure(0, 0, __FILE__, __LINE__, "Function call 
succeeded: " #expr); \
        } while (0)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/tests/index/tests.c 
new/libgit2-0.28.4/tests/index/tests.c
--- old/libgit2-0.28.2/tests/index/tests.c      2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/tests/index/tests.c      2019-12-10 20:39:58.000000000 
+0100
@@ -541,7 +541,7 @@
        git_repository_free(bare_repo);
 }
 
-static void add_invalid_filename(git_repository *repo, const char *fn)
+static void assert_add_bypath_fails(git_repository *repo, const char *fn)
 {
        git_index *index;
        git_buf path = GIT_BUF_INIT;
@@ -562,7 +562,7 @@
 }
 
 /* Test that writing an invalid filename fails */
-void test_index_tests__add_invalid_filename(void)
+void test_index_tests__cannot_add_invalid_filename(void)
 {
        git_repository *repo;
 
@@ -577,13 +577,69 @@
        if (!git_path_exists("./invalid/.GiT"))
                cl_must_pass(p_mkdir("./invalid/.GiT", 0777));
 
-       add_invalid_filename(repo, ".git/hello");
-       add_invalid_filename(repo, ".GIT/hello");
-       add_invalid_filename(repo, ".GiT/hello");
-       add_invalid_filename(repo, "./.git/hello");
-       add_invalid_filename(repo, "./foo");
-       add_invalid_filename(repo, "./bar");
-       add_invalid_filename(repo, "subdir/../bar");
+       assert_add_bypath_fails(repo, ".git/hello");
+       assert_add_bypath_fails(repo, ".GIT/hello");
+       assert_add_bypath_fails(repo, ".GiT/hello");
+       assert_add_bypath_fails(repo, "./.git/hello");
+       assert_add_bypath_fails(repo, "./foo");
+       assert_add_bypath_fails(repo, "./bar");
+       assert_add_bypath_fails(repo, "subdir/../bar");
+
+       git_repository_free(repo);
+
+       cl_fixture_cleanup("invalid");
+}
+
+static void assert_add_fails(git_repository *repo, const char *fn)
+{
+       git_index *index;
+       git_buf path = GIT_BUF_INIT;
+       git_index_entry entry = {{0}};
+
+       cl_git_pass(git_repository_index(&index, repo));
+       cl_assert(git_index_entrycount(index) == 0);
+
+       entry.path = fn;
+       entry.mode = GIT_FILEMODE_BLOB;
+       cl_git_pass(git_oid_fromstr(&entry.id, 
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"));
+
+       cl_git_fail(git_index_add(index, &entry));
+
+       cl_assert(git_index_entrycount(index) == 0);
+
+       git_buf_dispose(&path);
+       git_index_free(index);
+}
+
+/*
+ * Test that writing an invalid filename fails on filesystem
+ * specific protected names
+ */
+void test_index_tests__cannot_add_protected_invalid_filename(void)
+{
+       git_repository *repo;
+       git_index *index;
+
+       cl_must_pass(p_mkdir("invalid", 0700));
+
+       cl_git_pass(git_repository_init(&repo, "./invalid", 0));
+
+       /* add a file to the repository so we can reference it later */
+       cl_git_pass(git_repository_index(&index, repo));
+       cl_git_mkfile("invalid/dummy.txt", "");
+       cl_git_pass(git_index_add_bypath(index, "dummy.txt"));
+       cl_must_pass(p_unlink("invalid/dummy.txt"));
+       cl_git_pass(git_index_remove_bypath(index, "dummy.txt"));
+       git_index_free(index);
+
+       cl_repo_set_bool(repo, "core.protectHFS", true);
+       cl_repo_set_bool(repo, "core.protectNTFS", true);
+
+       assert_add_fails(repo, ".git./hello");
+       assert_add_fails(repo, ".git\xe2\x80\xad/hello");
+       assert_add_fails(repo, "git~1/hello");
+       assert_add_fails(repo, ".git\xe2\x81\xaf/hello");
+       assert_add_fails(repo, ".git::$INDEX_ALLOCATION/dummy-file");
 
        git_repository_free(repo);
 
@@ -599,7 +655,7 @@
                        *c = out;
 }
 
-static void write_invalid_filename(git_repository *repo, const char *fn_orig)
+static void assert_write_fails(git_repository *repo, const char *fn_orig)
 {
        git_index *index;
        git_oid expected;
@@ -616,6 +672,7 @@
         */
        fn = git__strdup(fn_orig);
        replace_char(fn, '/', '_');
+       replace_char(fn, ':', '!');
 
        git_buf_joinpath(&path, "./invalid", fn);
 
@@ -627,6 +684,7 @@
 
        /* kids, don't try this at home */
        replace_char((char *)entry->path, '_', '/');
+       replace_char((char *)entry->path, '!', ':');
 
        /* write-tree */
        cl_git_fail(git_index_write_tree(&expected, index));
@@ -672,13 +730,13 @@
 
        cl_git_pass(git_repository_init(&repo, "./invalid", 0));
 
-       write_invalid_filename(repo, ".git/hello");
-       write_invalid_filename(repo, ".GIT/hello");
-       write_invalid_filename(repo, ".GiT/hello");
-       write_invalid_filename(repo, "./.git/hello");
-       write_invalid_filename(repo, "./foo");
-       write_invalid_filename(repo, "./bar");
-       write_invalid_filename(repo, "foo/../bar");
+       assert_write_fails(repo, ".git/hello");
+       assert_write_fails(repo, ".GIT/hello");
+       assert_write_fails(repo, ".GiT/hello");
+       assert_write_fails(repo, "./.git/hello");
+       assert_write_fails(repo, "./foo");
+       assert_write_fails(repo, "./bar");
+       assert_write_fails(repo, "foo/../bar");
 
        git_repository_free(repo);
 
@@ -696,16 +754,52 @@
        cl_repo_set_bool(repo, "core.protectHFS", true);
        cl_repo_set_bool(repo, "core.protectNTFS", true);
 
-       write_invalid_filename(repo, ".git./hello");
-       write_invalid_filename(repo, ".git\xe2\x80\xad/hello");
-       write_invalid_filename(repo, "git~1/hello");
-       write_invalid_filename(repo, ".git\xe2\x81\xaf/hello");
+       assert_write_fails(repo, ".git./hello");
+       assert_write_fails(repo, ".git\xe2\x80\xad/hello");
+       assert_write_fails(repo, "git~1/hello");
+       assert_write_fails(repo, ".git\xe2\x81\xaf/hello");
+       assert_write_fails(repo, ".git::$INDEX_ALLOCATION/dummy-file");
+
+       git_repository_free(repo);
+
+       cl_fixture_cleanup("invalid");
+}
+
+void test_index_tests__protectntfs_on_by_default(void)
+{
+       git_repository *repo;
+
+       p_mkdir("invalid", 0700);
+
+       cl_git_pass(git_repository_init(&repo, "./invalid", 0));
+       assert_write_fails(repo, ".git./hello");
+       assert_write_fails(repo, "git~1/hello");
 
        git_repository_free(repo);
 
        cl_fixture_cleanup("invalid");
 }
 
+void test_index_tests__can_disable_protectntfs(void)
+{
+       git_repository *repo;
+       git_index *index;
+
+       cl_must_pass(p_mkdir("valid", 0700));
+       cl_git_rewritefile("valid/git~1", "steal the shortname");
+
+       cl_git_pass(git_repository_init(&repo, "./valid", 0));
+       cl_git_pass(git_repository_index(&index, repo));
+       cl_repo_set_bool(repo, "core.protectNTFS", false);
+
+       cl_git_pass(git_index_add_bypath(index, "git~1"));
+
+       git_index_free(index);
+       git_repository_free(repo);
+
+       cl_fixture_cleanup("valid");
+}
+
 void test_index_tests__remove_entry(void)
 {
        git_repository *repo;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/tests/object/tree/write.c 
new/libgit2-0.28.4/tests/object/tree/write.c
--- old/libgit2-0.28.2/tests/object/tree/write.c        2019-05-21 
09:54:19.000000000 +0200
+++ new/libgit2-0.28.4/tests/object/tree/write.c        2019-12-10 
20:39:58.000000000 +0100
@@ -141,7 +141,7 @@
        cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
 
        for (i = 0; i < ARRAY_SIZE(entries); ++i) {
-               git_oid *id = entries[i].attr == GIT_FILEMODE_TREE ?  &tid : 
&bid; 
+               git_oid *id = entries[i].attr == GIT_FILEMODE_TREE ?  &tid : 
&bid;
 
                cl_git_pass(git_treebuilder_insert(NULL,
                        builder, entries[i].filename, id, entries[i].attr));
@@ -418,10 +418,8 @@
         */
        cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
 
-#ifndef GIT_WIN32
-       cl_git_pass(git_treebuilder_insert(NULL, builder, ".git.", &bid, 
GIT_FILEMODE_BLOB));
-       cl_git_pass(git_treebuilder_insert(NULL, builder, "git~1", &bid, 
GIT_FILEMODE_BLOB));
-#endif
+       cl_git_fail(git_treebuilder_insert(NULL, builder, ".git.", &bid, 
GIT_FILEMODE_BLOB));
+       cl_git_fail(git_treebuilder_insert(NULL, builder, "git~1", &bid, 
GIT_FILEMODE_BLOB));
 
 #ifndef __APPLE__
        cl_git_pass(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", 
&bid, GIT_FILEMODE_BLOB));
@@ -444,6 +442,7 @@
 
        cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", 
&bid, GIT_FILEMODE_BLOB));
        cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xe2\x80\xad", 
&bid, GIT_FILEMODE_BLOB));
+       cl_git_fail(git_treebuilder_insert(NULL, builder, 
".git::$INDEX_ALLOCATION/dummy-file", &bid, GIT_FILEMODE_BLOB));
 
        git_treebuilder_free(builder);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/tests/path/core.c 
new/libgit2-0.28.4/tests/path/core.c
--- old/libgit2-0.28.2/tests/path/core.c        2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/tests/path/core.c        2019-12-10 20:39:58.000000000 
+0100
@@ -352,3 +352,14 @@
 
        git_buf_dispose(&out);
 }
+
+void test_path_core__join_unrooted_respects_funny_windows_roots(void)
+{
+       test_join_unrooted("๐Ÿ’ฉ:/foo/bar/foobar", 9, "bar/foobar", "๐Ÿ’ฉ:/foo");
+       test_join_unrooted("๐Ÿ’ฉ:/foo/bar/foobar", 13, "foobar", "๐Ÿ’ฉ:/foo/bar");
+       test_join_unrooted("๐Ÿ’ฉ:/foo", 5, "๐Ÿ’ฉ:/foo", "๐Ÿ’ฉ:/asdf");
+       test_join_unrooted("๐Ÿ’ฉ:/foo/bar", 5, "๐Ÿ’ฉ:/foo/bar", "๐Ÿ’ฉ:/asdf");
+       test_join_unrooted("๐Ÿ’ฉ:/foo/bar/foobar", 9, "๐Ÿ’ฉ:/foo/bar/foobar", 
"๐Ÿ’ฉ:/foo");
+       test_join_unrooted("๐Ÿ’ฉ:/foo/bar/foobar", 13, "๐Ÿ’ฉ:/foo/bar/foobar", 
"๐Ÿ’ฉ:/foo/bar");
+       test_join_unrooted("๐Ÿ’ฉ:/foo/bar/foobar", 9, "๐Ÿ’ฉ:/foo/bar/foobar", 
"๐Ÿ’ฉ:/foo/");
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.28.2/tests/path/dotgit.c 
new/libgit2-0.28.4/tests/path/dotgit.c
--- old/libgit2-0.28.2/tests/path/dotgit.c      2019-05-21 09:54:19.000000000 
+0200
+++ new/libgit2-0.28.4/tests/path/dotgit.c      2019-12-10 20:39:58.000000000 
+0100
@@ -116,4 +116,5 @@
        cl_assert_equal_b(true, git_path_isvalid(NULL, ".gitmodules", 0, 
GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS));
        cl_assert_equal_b(false, git_path_isvalid(NULL, ".gitmodules", S_IFLNK, 
GIT_PATH_REJECT_DOT_GIT_HFS));
        cl_assert_equal_b(false, git_path_isvalid(NULL, ".gitmodules", S_IFLNK, 
GIT_PATH_REJECT_DOT_GIT_NTFS));
+       cl_assert_equal_b(false, git_path_isvalid(NULL, ".gitmodules . 
.::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS));
 }
Binary files 
old/libgit2-0.28.2/tests/resources/nasty/.gitted/objects/33/8190107c7ee7d8f5aa30061fc19b7d5ddcda86
 and 
new/libgit2-0.28.4/tests/resources/nasty/.gitted/objects/33/8190107c7ee7d8f5aa30061fc19b7d5ddcda86
 differ
Binary files 
old/libgit2-0.28.2/tests/resources/nasty/.gitted/objects/97/c14994866466aeb73e769a6f34e07c7f4b53f7
 and 
new/libgit2-0.28.4/tests/resources/nasty/.gitted/objects/97/c14994866466aeb73e769a6f34e07c7f4b53f7
 differ
Binary files 
old/libgit2-0.28.2/tests/resources/nasty/.gitted/objects/b8/edf3ad62dbcbc983857a5bfee7b0181ee1a513
 and 
new/libgit2-0.28.4/tests/resources/nasty/.gitted/objects/b8/edf3ad62dbcbc983857a5bfee7b0181ee1a513
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libgit2-0.28.2/tests/resources/nasty/.gitted/refs/heads/dotgit_alternate_data_stream
 
new/libgit2-0.28.4/tests/resources/nasty/.gitted/refs/heads/dotgit_alternate_data_stream
--- 
old/libgit2-0.28.2/tests/resources/nasty/.gitted/refs/heads/dotgit_alternate_data_stream
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/libgit2-0.28.4/tests/resources/nasty/.gitted/refs/heads/dotgit_alternate_data_stream
    2019-12-10 20:39:58.000000000 +0100
@@ -0,0 +1 @@
+b8edf3ad62dbcbc983857a5bfee7b0181ee1a513


Reply via email to