- OPTIONS="-DTHREADSAFE=OFF -DBUILD_EXAMPLES=ON -DENABLE_WERROR=ON"
dist: trusty
+osx_image: xcode8.3
sudo: false
addons:
-v0.27 + 1
+v0.27.4
+-------
+
+This is a security release fixing out-of-bounds reads when
+processing smart-protocol "ng" packets.
+
+When parsing an "ng" packet, we keep track of both the current position
+as well as the remaining length of the packet itself. But instead of
+taking care not to exceed the length, we pass the current pointer's
+position to `strchr`, which will search for a certain character until
+hitting NUL. It is thus possible to create a crafted packet which
+doesn't contain a NUL byte to trigger an out-of-bounds read.
+
+The issue was discovered by the oss-fuzz project, issue 9406.
+
+v0.27.3
+-------
+
+This is a security release fixing out-of-bounds reads when
+reading objects from a packfile. This corresponds to
+CVE-2018-10887 and CVE-2018-10888, which were both reported by
+Riccardo Schirone.
+
+When packing objects into a single so-called packfile, objects
+may not get stored as complete copies but instead as deltas
+against another object "base". A specially crafted delta object
+could trigger an integer overflow and thus bypass our input
+validation, which may result in copying memory before or after
+the base object into the final deflated object. This may lead to
+objects containing copies of system memory being written into the
+object database. As the hash of those objects cannot be easily
+controlled by the attacker, it is unlikely that any of those
+objects will be valid and referenced by the commit graph.
+
+Note that the error could also be triggered by the function
+`git_apply__patch`. But as this function is not in use outside of
+our test suite, it is not a possible attack vector.
+
+v0.27.2
---------
### Changes or improvements
-### API additions
+* Fix builds with LibreSSL 2.7.
-### API removals
+* Fix for `git_diff_status_char()` not returning the correct mapping for
+ `GIT_DELTA_TYPECHANGE`.
-### Breaking API changes
+* Fix for the submodules API not reporting errors when parsing the ".gitmodules"
+ file.
+
+* Fix for accepting a ".gitmodules" file where two submodules have the same
+ path.
+
+* Fix for hiding references in a graph walk not always limiting the graph
+ correctly.
+
+* Fix for directory patterns with trailing spaces in attribute files not being
+ handled correctly.
+
+* Fix SSH transports not properly disconnecting from the server.
+
+* Fix reading HEAD reflog in worktrees.
+
+* Update our copy of SHA1DC to fix errors with endianess on some platforms.
+
+v0.27.1
+---------
+
+This is a security release fixing insufficient validation of submodule names
+(CVE-2018-11235, reported by Etienne Stalmans) and disallows `.gitmodules` files
+as symlinks.
+
+While submodule names come from the untrusted ".gitmodules" file, we blindly
+append the name to "$GIT_DIR/modules" to construct the final path of the
+submodule repository. In case the name contains e.g. "../", an adversary would
+be able to escape your repository and write data at arbitrary paths. In
+accordance with git, we now enforce some rules for submodule names which will
+cause libgit2 to ignore these malicious names.
+
+Adding a symlink as `.gitmodules` into the index from the workdir or checking
+out such files is not allowed as this can make a Git implementation write
+outside of the repository and bypass the `fsck` checks for CVE-2018-11235.
+
+libgit2 is not susceptible to CVE-2018-11233.
v0.27
---------
INCLUDE(CheckSymbolExists)
INCLUDE(CheckStructHasMember)
INCLUDE(AddCFlagIfSupported)
-INCLUDE(FindPkgConfig)
+INCLUDE(FindPkgLibraries)
INCLUDE(FindThreads)
INCLUDE(FindStatNsec)
INCLUDE(IdeSplitSources)
if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/libgit2/script/appveyor-mingw.sh)
test_script:
- ps: |
+ # Disable DHE key exchange to fix intermittent build failures ("A buffer
+ # provided was too small") due to SChannel bug. See e.g.
+ # - https://github.com/aws/aws-sdk-cpp/issues/671
+ # - https://github.com/dotnet/corefx/issues/7812
+ New-Item HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman -Force | New-ItemProperty -Name Enabled -Value 0 -Force
$ErrorActionPreference="Stop"
Start-FileDownload https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar -FileName poxyproxy.jar
# Run this early so we know it's ready by the time we need it
--- /dev/null
+INCLUDE(FindPkgConfig)
+
+# This function will find and set up a pkg-config based module.
+# If a pc-file was found, it will resolve library paths to
+# absolute paths. Furthermore, the function will automatically
+# fall back to use static libraries in case no dynamic libraries
+# were found.
+FUNCTION(FIND_PKGLIBRARIES prefix package)
+ PKG_CHECK_MODULES(${prefix} ${package})
+ IF(NOT ${prefix}_FOUND)
+ RETURN()
+ ENDIF()
+
+ FOREACH(LIBRARY ${${prefix}_LIBRARIES})
+ FIND_LIBRARY(${LIBRARY}_RESOLVED ${LIBRARY} PATHS ${${prefix}_LIBRARY_DIRS})
+ IF(${${LIBRARY}_RESOLVED} STREQUAL "${LIBRARY}_RESOLVED-NOTFOUND")
+ MESSAGE(FATAL_ERROR "could not resolve ${LIBRARY}")
+ ENDIF()
+ LIST(APPEND RESOLVED_LIBRARIES ${${LIBRARY}_RESOLVED})
+ ENDFOREACH(LIBRARY)
+
+ SET(${prefix}_FOUND 1 PARENT_SCOPE)
+ SET(${prefix}_LIBRARIES ${RESOLVED_LIBRARIES} PARENT_SCOPE)
+ SET(${prefix}_INCLUDE_DIRS ${${prefix}_INCLUDE_DIRS} PARENT_SCOPE)
+ SET(${prefix}_LDFLAGS ${${prefix}_LDFLAGS} PARENT_SCOPE)
+
+ MESSAGE(STATUS " Resolved libraries: ${RESOLVED_LIBRARIES}")
+ENDFUNCTION()
-LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
FILE(GLOB_RECURSE SRC_EXAMPLE_GIT2 network/*.c network/*.h common.?)
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
-#define LIBGIT2_VERSION "0.27.0"
+#define LIBGIT2_VERSION "0.27.4"
#define LIBGIT2_VER_MAJOR 0
#define LIBGIT2_VER_MINOR 27
-#define LIBGIT2_VER_REVISION 0
+#define LIBGIT2_VER_REVISION 4
#define LIBGIT2_VER_PATCH 0
#define LIBGIT2_SOVERSION 27
"${libgit2_SOURCE_DIR}/src"
"${libgit2_SOURCE_DIR}/include")
SET(LIBGIT2_LIBS "")
-SET(LIBGIT2_LIBDIRS "")
# Installation paths
#
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp")
LIST(APPEND LIBGIT2_LIBS winhttp)
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp")
- LIST(APPEND LIBGIT2_LIBDIRS ${LIBWINHTTP_PATH})
ELSE()
LIST(APPEND LIBGIT2_LIBS "winhttp")
LIST(APPEND LIBGIT2_PC_LIBS "-lwinhttp")
LIST(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32")
ELSE ()
IF (CURL)
- PKG_CHECK_MODULES(CURL libcurl)
+ FIND_PKGLIBRARIES(CURL libcurl)
ENDIF ()
-
IF (CURL_FOUND)
SET(GIT_CURL 1)
LIST(APPEND LIBGIT2_INCLUDES ${CURL_INCLUDE_DIRS})
- LIST(APPEND LIBGIT2_LIBDIRS ${CURL_LIBRARY_DIRS})
LIST(APPEND LIBGIT2_LIBS ${CURL_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS})
ENDIF()
# Optional external dependency: libssh2
IF (USE_SSH)
- PKG_CHECK_MODULES(LIBSSH2 libssh2)
+ FIND_PKGLIBRARIES(LIBSSH2 libssh2)
ENDIF()
IF (LIBSSH2_FOUND)
SET(GIT_SSH 1)
LIST(APPEND LIBGIT2_INCLUDES ${LIBSSH2_INCLUDE_DIRS})
LIST(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES})
- LIST(APPEND LIBGIT2_LIBDIRS ${LIBSSH2_LIBRARY_DIRS})
LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
- #SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}")
CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)
SET(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE)
SET(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE)
SET(LIBGIT2_LIBS ${LIBGIT2_LIBS} PARENT_SCOPE)
-SET(LIBGIT2_LIBDIRS ${LIBGIT2_LIBDIRS} PARENT_SCOPE)
IF(XCODE_VERSION)
# This is required for Xcode to actually link the libgit2 library
ENDIF()
# Compile and link libgit2
-LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
ADD_LIBRARY(git2 ${WIN_RC} ${LIBGIT2_OBJECTS})
TARGET_LINK_LIBRARIES(git2 ${LIBGIT2_LIBS})
if (--spec->length == 0)
return GIT_ENOTFOUND;
+ /* Remove trailing spaces. */
+ while (pattern[spec->length - 1] == ' ' || pattern[spec->length - 1] == '\t')
+ if (--spec->length == 0)
+ return GIT_ENOTFOUND;
+
if (pattern[spec->length - 1] == '/') {
spec->length--;
spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY;
unsigned int flags = GIT_PATH_REJECT_WORKDIR_DEFAULTS;
if (action & CHECKOUT_ACTION__REMOVE) {
- if (!git_path_isvalid(repo, delta->old_file.path, flags)) {
+ if (!git_path_isvalid(repo, delta->old_file.path, delta->old_file.mode, flags)) {
giterr_set(GITERR_CHECKOUT, "cannot remove invalid path '%s'", delta->old_file.path);
return -1;
}
}
if (action & ~CHECKOUT_ACTION__REMOVE) {
- if (!git_path_isvalid(repo, delta->new_file.path, flags)) {
+ if (!git_path_isvalid(repo, delta->new_file.path, delta->new_file.mode, flags)) {
giterr_set(GITERR_CHECKOUT, "cannot checkout to invalid path '%s'", delta->new_file.path);
return -1;
}
*out = NULL;
*out_len = 0;
- /* Check that the base size matches the data we were given;
- * if not we would underflow while accessing data from the
- * base object, resulting in data corruption or segfault.
- */
+ /*
+ * Check that the base size matches the data we were given;
+ * if not we would underflow while accessing data from the
+ * base object, resulting in data corruption or segfault.
+ */
if ((hdr_sz(&base_sz, &delta, delta_end) < 0) || (base_sz != base_len)) {
giterr_set(GITERR_INVALID, "failed to apply delta: base size does not match given data");
return -1;
while (delta < delta_end) {
unsigned char cmd = *delta++;
if (cmd & 0x80) {
- /* cmd is a copy instruction; copy from the base.
- */
- size_t off = 0, len = 0;
-
- if (cmd & 0x01) off = *delta++;
- if (cmd & 0x02) off |= *delta++ << 8UL;
- if (cmd & 0x04) off |= *delta++ << 16UL;
- if (cmd & 0x08) off |= *delta++ << 24UL;
-
- if (cmd & 0x10) len = *delta++;
- if (cmd & 0x20) len |= *delta++ << 8UL;
- if (cmd & 0x40) len |= *delta++ << 16UL;
- if (!len) len = 0x10000;
-
- if (base_len < off + len || res_sz < len)
+ /* cmd is a copy instruction; copy from the base. */
+ size_t off = 0, len = 0, end;
+
+#define ADD_DELTA(o, shift) { if (delta < delta_end) (o) |= ((unsigned) *delta++ << shift); else goto fail; }
+ if (cmd & 0x01) ADD_DELTA(off, 0UL);
+ if (cmd & 0x02) ADD_DELTA(off, 8UL);
+ if (cmd & 0x04) ADD_DELTA(off, 16UL);
+ if (cmd & 0x08) ADD_DELTA(off, 24UL);
+
+ if (cmd & 0x10) ADD_DELTA(len, 0UL);
+ if (cmd & 0x20) ADD_DELTA(len, 8UL);
+ if (cmd & 0x40) ADD_DELTA(len, 16UL);
+ if (!len) len = 0x10000;
+#undef ADD_DELTA
+
+ if (GIT_ADD_SIZET_OVERFLOW(&end, off, len) ||
+ base_len < end || res_sz < len)
goto fail;
+
memcpy(res_dp, base + off, len);
res_dp += len;
res_sz -= len;
- }
- else if (cmd) {
- /* cmd is a literal insert instruction; copy from
- * the delta stream itself.
- */
+ } else if (cmd) {
+ /*
+ * cmd is a literal insert instruction; copy from
+ * the delta stream itself.
+ */
if (delta_end - delta < cmd || res_sz < cmd)
goto fail;
memcpy(res_dp, delta, cmd);
res_dp += cmd;
res_sz -= cmd;
- }
- else {
- /* cmd == 0 is reserved for future encodings.
- */
+ } else {
+ /* cmd == 0 is reserved for future encodings. */
goto fail;
}
}
case GIT_DELTA_COPIED: code = 'C'; break;
case GIT_DELTA_IGNORED: code = 'I'; break;
case GIT_DELTA_UNTRACKED: code = '?'; break;
+ case GIT_DELTA_TYPECHANGE: code = 'T'; break;
case GIT_DELTA_UNREADABLE: code = 'X'; break;
default: code = ' '; break;
}
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
+#ifdef __unix__
+#include <sys/types.h> /* make sure macros like _BIG_ENDIAN visible */
+#endif
#endif
#ifdef SHA1DC_CUSTOM_INCLUDE_SHA1_C
#include "sha1.h"
#include "ubc_check.h"
+#if (defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
+ defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
+ defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
+ defined(__386) || defined(_M_X64) || defined(_M_AMD64))
+#define SHA1DC_ON_INTEL_LIKE_PROCESSOR
+#endif
/*
Because Little-Endian architectures are most common,
If you are compiling on a big endian platform and your compiler does not define one of these,
you will have to add whatever macros your tool chain defines to indicate Big-Endianness.
*/
-#ifdef SHA1DC_BIGENDIAN
-#undef SHA1DC_BIGENDIAN
-#endif
-#if (defined(_BYTE_ORDER) || defined(__BYTE_ORDER) || defined(__BYTE_ORDER__))
-
-#if ((defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)) || \
- (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || \
- (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)) )
+#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
+/*
+ * Should detect Big Endian under GCC since at least 4.6.0 (gcc svn
+ * rev #165881). See
+ * https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
+ *
+ * This also works under clang since 3.2, it copied the GCC-ism. See
+ * clang.git's 3b198a97d2 ("Preprocessor: add __BYTE_ORDER__
+ * predefined macro", 2012-07-27)
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define SHA1DC_BIGENDIAN
#endif
-#else
-
-#if (defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN) || defined(__BIG_ENDIAN__) || \
- defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
- defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \
- defined(__sparc))
+/* Not under GCC-alike */
+#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN)
+/*
+ * Should detect Big Endian under glibc.git since 14245eb70e ("entered
+ * into RCS", 1992-11-25). Defined in <endian.h> which will have been
+ * brought in by standard headers. See glibc.git and
+ * https://sourceforge.net/p/predef/wiki/Endianness/
+ */
+#if __BYTE_ORDER == __BIG_ENDIAN
#define SHA1DC_BIGENDIAN
#endif
+/* Not under GCC-alike or glibc */
+#elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+/*
+ * *BSD and newlib (embeded linux, cygwin, etc).
+ * the defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) part prevents
+ * this condition from matching with Solaris/sparc.
+ * (Solaris defines only one endian macro)
+ */
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define SHA1DC_BIGENDIAN
#endif
+/* Not under GCC-alike or glibc or *BSD or newlib */
+#elif (defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
+ defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \
+ defined(__sparc))
+/*
+ * Should define Big Endian for a whitelist of known processors. See
+ * https://sourceforge.net/p/predef/wiki/Endianness/ and
+ * http://www.oracle.com/technetwork/server-storage/solaris/portingtosolaris-138514.html
+ */
+#define SHA1DC_BIGENDIAN
+
+/* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist> */
+#elif defined(SHA1DC_ON_INTEL_LIKE_PROCESSOR)
+/*
+ * As a last resort before we do anything else we're not 100% sure
+ * about below, we blacklist specific processors here. We could add
+ * more, see e.g. https://wiki.debian.org/ArchitectureSpecificsMemo
+ */
+#else /* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist> or <processor blacklist> */
+
+/* We do nothing more here for now */
+/*#error "Uncomment this to see if you fall through all the detection"*/
+
+#endif /* Big Endian detection */
+
#if (defined(SHA1DC_FORCE_LITTLEENDIAN) && defined(SHA1DC_BIGENDIAN))
#undef SHA1DC_BIGENDIAN
#endif
#endif
/*ENDIANNESS SELECTION*/
-#if (defined SHA1DC_FORCE_UNALIGNED_ACCESS || \
- defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
- defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || \
- defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
- defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
- defined(__386) || defined(_M_X64) || defined(_M_AMD64))
-
+#if defined(SHA1DC_FORCE_UNALIGNED_ACCESS) || defined(SHA1DC_ON_INTEL_LIKE_PROCESSOR)
#define SHA1DC_ALLOW_UNALIGNED_ACCESS
-
#endif /*UNALIGNMENT DETECTION*/
#ifdef _MSC_VER
#pragma warning(push)
-#pragma warning(disable: 4127) /* Complier complains about the checks in the above macro being constant. */
+#pragma warning(disable: 4127) /* Compiler complains about the checks in the above macro being constant. */
#endif
#ifdef DOSTORESTATE0
if (ignore_case)
match->flags |= GIT_ATTR_FNMATCH_ICASE;
- while (match->length > 0) {
- if (match->pattern[match->length - 1] == ' ' ||
- match->pattern[match->length - 1] == '\t') {
- match->pattern[match->length - 1] = 0;
- match->length --;
- } else {
- break;
- }
- }
-
scan = git__next_line(scan);
/*
git_index_entry **out,
git_repository *repo,
const char *path,
+ struct stat *st,
bool from_workdir)
{
size_t pathlen = strlen(path), alloclen;
struct entry_internal *entry;
unsigned int path_valid_flags = GIT_PATH_REJECT_INDEX_DEFAULTS;
+ uint16_t mode = 0;
/* always reject placing `.git` in the index and directory traversal.
* when requested, disallow platform-specific filenames and upgrade to
*/
if (from_workdir)
path_valid_flags |= GIT_PATH_REJECT_WORKDIR_DEFAULTS;
+ if (st)
+ mode = st->st_mode;
- if (!git_path_isvalid(repo, path, path_valid_flags)) {
+ if (!git_path_isvalid(repo, path, mode, path_valid_flags)) {
giterr_set(GITERR_INDEX, "invalid path: '%s'", path);
return -1;
}
{
int error = 0;
git_index_entry *entry = NULL;
+ git_buf path = GIT_BUF_INIT;
struct stat st;
git_oid oid;
+ git_repository *repo;
if (INDEX_OWNER(index) == NULL)
return create_index_error(-1,
"could not initialize index entry. "
"Index is not backed up by an existing repository.");
- if (index_entry_create(&entry, INDEX_OWNER(index), rel_path, true) < 0)
+ /*
+ * FIXME: this is duplicated with the work in
+ * git_blob__create_from_paths. It should accept an optional stat
+ * structure so we can pass in the one we have to do here.
+ */
+ repo = INDEX_OWNER(index);
+ if (git_repository__ensure_not_bare(repo, "create blob from file") < 0)
+ return GIT_EBAREREPO;
+
+ if (git_buf_joinpath(&path, git_repository_workdir(repo), rel_path) < 0)
+ return -1;
+
+ error = git_path_lstat(path.ptr, &st);
+ git_buf_free(&path);
+
+ if (error < 0)
+ return error;
+
+ if (index_entry_create(&entry, INDEX_OWNER(index), rel_path, &st, true) < 0)
return -1;
/* write the blob to disk and get the oid and stat info */
git_index *index,
const git_index_entry *src)
{
- if (index_entry_create(out, INDEX_OWNER(index), src->path, false) < 0)
+ if (index_entry_create(out, INDEX_OWNER(index), src->path, NULL, false) < 0)
return -1;
index_entry_cpy(*out, src);
git_index *index,
const git_index_entry *src)
{
- if (index_entry_create(out, INDEX_OWNER(index), src->path, false) < 0)
+ if (index_entry_create(out, INDEX_OWNER(index), src->path, NULL, false) < 0)
return -1;
index_entry_cpy_nocache(*out, src);
struct stat st;
int error;
- if (index_entry_create(&entry, INDEX_OWNER(index), path, true) < 0)
- return -1;
-
if ((error = git_buf_joinpath(&abspath, git_repository_workdir(repo), path)) < 0)
return error;
return -1;
}
+ if (index_entry_create(&entry, INDEX_OWNER(index), path, &st, true) < 0)
+ return -1;
+
git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
if ((error = git_repository_open(&sub, abspath.ptr)) < 0)
if (git_buf_joinpath(&path, root, tentry->filename) < 0)
return -1;
- if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr, false) < 0)
+ if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr, NULL, false) < 0)
return -1;
entry->mode = tentry->attr;
{
struct memory_packer_db *db = (struct memory_packer_db *)_backend;
+ git_mempack_reset(_backend);
git_oidmap_free(db->objects);
git__free(db);
}
return 0; /* NULL byte -- end of string */
}
-static bool verify_dotgit_hfs(const char *path, size_t len)
+static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char *needle, size_t needle_len)
{
- if (next_hfs_char(&path, &len) != '.' ||
- next_hfs_char(&path, &len) != 'g' ||
- next_hfs_char(&path, &len) != 'i' ||
- next_hfs_char(&path, &len) != 't' ||
- next_hfs_char(&path, &len) != 0)
+ size_t i;
+ char c;
+
+ if (next_hfs_char(&path, &len) != '.')
+ return true;
+
+ for (i = 0; i < needle_len; i++) {
+ c = next_hfs_char(&path, &len);
+ if (c != needle[i])
+ return true;
+ }
+
+ if (next_hfs_char(&path, &len) != '\0')
return true;
return false;
}
+static bool verify_dotgit_hfs(const char *path, size_t len)
+{
+ return verify_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git"));
+}
+
GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len)
{
git_buf *reserved = git_repository__reserved_names_win32;
return false;
}
+GIT_INLINE(bool) only_spaces_and_dots(const char *path)
+{
+ const char *c = path;
+
+ for (;; c++) {
+ if (*c == '\0')
+ return true;
+ if (*c != ' ' && *c != '.')
+ return false;
+ }
+
+ return true;
+}
+
+GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, size_t len, const char *dotgit_name, size_t dotgit_len, const char *shortname_pfix)
+{
+ int i, saw_tilde;
+
+ if (name[0] == '.' && len >= dotgit_len &&
+ !strncasecmp(name + 1, dotgit_name, dotgit_len)) {
+ return !only_spaces_and_dots(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);
+
+ /* Catch fallback names */
+ for (i = 0, saw_tilde = 0; i < 8; i++) {
+ if (name[i] == '\0') {
+ return true;
+ } else if (saw_tilde) {
+ if (name[i] < '0' || name[i] > '9')
+ return true;
+ } else if (name[i] == '~') {
+ if (name[i+1] < '1' || name[i+1] > '9')
+ return true;
+ saw_tilde = 1;
+ } else if (i >= 6) {
+ return true;
+ } else if (name[i] < 0) {
+ return true;
+ } else if (git__tolower(name[i]) != shortname_pfix[i]) {
+ return true;
+ }
+ }
+
+ return !only_spaces_and_dots(name + i);
+}
+
GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
{
if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\')
return true;
}
+/*
+ * Return the length of the common prefix between str and prefix, comparing them
+ * case-insensitively (must be ASCII to match).
+ */
+GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char *prefix)
+{
+ size_t count = 0;
+
+ while (len >0 && tolower(*str) == tolower(*prefix)) {
+ count++;
+ str++;
+ prefix++;
+ len--;
+ }
+
+ return count;
+}
+
/*
* We fundamentally don't like some paths when dealing with user-inputted
* strings (in checkout or ref names): we don't want dot or dot-dot
git_repository *repo,
const char *component,
size_t len,
+ uint16_t mode,
unsigned int flags)
{
if (len == 0)
return false;
}
- if (flags & GIT_PATH_REJECT_DOT_GIT_HFS &&
- !verify_dotgit_hfs(component, len))
- return false;
+ if (flags & GIT_PATH_REJECT_DOT_GIT_HFS) {
+ if (!verify_dotgit_hfs(component, len))
+ return false;
+ if (S_ISLNK(mode) && git_path_is_hfs_dotgit_modules(component, len))
+ return false;
+ }
- if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS &&
- !verify_dotgit_ntfs(repo, component, len))
- return false;
+ if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) {
+ if (!verify_dotgit_ntfs(repo, component, len))
+ return false;
+ if (S_ISLNK(mode) && git_path_is_ntfs_dotgit_modules(component, len))
+ return false;
+ }
/* don't bother rerunning the `.git` test if we ran the HFS or NTFS
* specific tests, they would have already rejected `.git`.
*/
if ((flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 &&
- (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
- (flags & GIT_PATH_REJECT_DOT_GIT_LITERAL) &&
- len == 4 &&
- component[0] == '.' &&
- (component[1] == 'g' || component[1] == 'G') &&
- (component[2] == 'i' || component[2] == 'I') &&
- (component[3] == 't' || component[3] == 'T'))
- return false;
+ (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
+ (flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) {
+ if (len >= 4 &&
+ component[0] == '.' &&
+ (component[1] == 'g' || component[1] == 'G') &&
+ (component[2] == 'i' || component[2] == 'I') &&
+ (component[3] == 't' || component[3] == 'T')) {
+ if (len == 4)
+ return false;
+
+ if (S_ISLNK(mode) && common_prefix_icase(component, len, ".gitmodules") == len)
+ return false;
+ }
+ }
return true;
}
bool git_path_isvalid(
git_repository *repo,
const char *path,
+ uint16_t mode,
unsigned int flags)
{
const char *start, *c;
return false;
if (*c == '/') {
- if (!verify_component(repo, start, (c - start), flags))
+ if (!verify_component(repo, start, (c - start), mode, flags))
return false;
start = c+1;
}
}
- return verify_component(repo, start, (c - start), flags);
+ return verify_component(repo, start, (c - start), mode, flags);
}
int git_path_normalize_slashes(git_buf *out, const char *path)
return 0;
}
+
+static int verify_dotgit_generic(const char *name, size_t len, const char *dotgit_name, size_t dotgit_len, const char *shortname_pfix)
+{
+ if (!verify_dotgit_ntfs_generic(name, len, dotgit_name, dotgit_len, shortname_pfix))
+ return false;
+
+ return verify_dotgit_hfs_generic(name, len, dotgit_name, dotgit_len);
+}
+
+int git_path_is_ntfs_dotgit_modules(const char *name, size_t len)
+{
+ return !verify_dotgit_ntfs_generic(name, len, "gitmodules", CONST_STRLEN("gitmodules"), "gi7eba");
+}
+
+int git_path_is_hfs_dotgit_modules(const char *name, size_t len)
+{
+ return !verify_dotgit_hfs_generic(name, len, "gitmodules", CONST_STRLEN("gitmodules"));
+}
+
+int git_path_is_dotgit_modules(const char *name, size_t len)
+{
+ if (git_path_is_hfs_dotgit_modules(name, len))
+ return 1;
+
+ return git_path_is_ntfs_dotgit_modules(name, len);
+}
+
+int git_path_is_ntfs_dotgit_ignore(const char *name, size_t len)
+{
+ return !verify_dotgit_ntfs_generic(name, len, "gitignore", CONST_STRLEN("gitignore"), "gi250a");
+}
+
+int git_path_is_hfs_dotgit_ignore(const char *name, size_t len)
+{
+ return !verify_dotgit_hfs_generic(name, len, "gitignore", CONST_STRLEN("gitignore"));
+}
+
+int git_path_is_dotgit_ignore(const char *name, size_t len)
+{
+ if (git_path_is_hfs_dotgit_ignore(name, len))
+ return 1;
+
+ return git_path_is_ntfs_dotgit_ignore(name, len);
+}
+
+int git_path_is_hfs_dotgit_attributes(const char *name, size_t len)
+{
+ return !verify_dotgit_hfs_generic(name, len, "gitattributes", CONST_STRLEN("gitattributes"));
+}
+
+int git_path_is_ntfs_dotgit_attributes(const char *name, size_t len)
+{
+ return !verify_dotgit_ntfs_generic(name, len, "gitattributes", CONST_STRLEN("gitattributes"), "gi7d29");
+}
+
+int git_path_is_dotgit_attributes(const char *name, size_t len)
+{
+ if (git_path_is_hfs_dotgit_attributes(name, len))
+ return 1;
+
+ return git_path_is_ntfs_dotgit_attributes(name, len);
+}
extern bool git_path_isvalid(
git_repository *repo,
const char *path,
+ uint16_t mode,
unsigned int flags);
/**
*/
int git_path_normalize_slashes(git_buf *out, const char *path);
+/**
+ * Check whether a path component corresponds to a .gitmodules file
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_dotgit_modules(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitmodules file in NTFS
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_ntfs_dotgit_modules(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitmodules file in HFS+
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_hfs_dotgit_modules(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_dotgit_ignore(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file in NTFS
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_ntfs_dotgit_ignore(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file in HFS+
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_hfs_dotgit_ignore(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_dotgit_attributes(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitattributes file in NTFS
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_ntfs_dotgit_attributes(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitattributes file in HFS+
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_hfs_dotgit_attributes(const char *name, size_t len);
+
#endif
assert(file && backend && name);
- if (!git_path_isvalid(backend->repo, name, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
+ if (!git_path_isvalid(backend->repo, name, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
giterr_set(GITERR_INVALID, "invalid reference name '%s'", name);
return GIT_EINVALIDSPEC;
}
GIT_INLINE(int) retrieve_reflog_path(git_buf *path, git_repository *repo, const char *name)
{
+ if (strcmp(name, GIT_HEAD_FILE) == 0)
+ return git_buf_join3(path, '/', repo->gitdir, GIT_REFLOG_DIR, name);
return git_buf_join3(path, '/', repo->commondir, GIT_REFLOG_DIR, name);
}
repo = backend->repo;
- if (!git_path_isvalid(backend->repo, refname, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
+ if (!git_path_isvalid(backend->repo, refname, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
giterr_set(GITERR_INVALID, "invalid reference name '%s'", refname);
return GIT_EINVALIDSPEC;
}
GITERR_CHECK_ALLOC(*dest);
+ (*dest)->db = source->db;
+ GIT_REFCOUNT_INC((*dest)->db);
+
return 0;
}
* with the given name pointing to the reference pointed to by
* the file. If it is not a symbolic reference, it will return
* the resolved reference.
+ *
+ * Note that because the refdb is not involved for symbolic references, they
+ * won't be owned, hence you should either not make the returned reference
+ * 'externally visible', or perform the lookup before returning it to the user.
*/
int git_reference__read_head(
git_reference **out,
git_buf buf = GIT_BUF_INIT;
size_t j, pos;
git_remote_head key;
+ git_refspec *cur;
const char* formatters[] = {
GIT_REFS_DIR "%s",
NULL
};
- git_refspec *cur = git__calloc(1, sizeof(git_refspec));
+ assert(out && spec && refs);
+
+ cur = git__calloc(1, sizeof(git_refspec));
GITERR_CHECK_ALLOC(cur);
cur->force = spec->force;
goto on_error;
/* only write for non-anonymous remotes */
- if (name && (error = write_add_refspec(repo, name, fetch, true)) < 0)
+ if (repo && name && (error = write_add_refspec(repo, name, fetch, true)) < 0)
goto on_error;
if (repo && (error = lookup_remote_prune_config(remote, config_ro, name)) < 0)
return 0;
}
-static int everybody_uninteresting(git_commit_list *orig)
-{
- git_commit_list *list = orig;
-
- while (list) {
- git_commit_list_node *commit = list->item;
- list = list->next;
- if (!commit->uninteresting)
- return 0;
- }
-
- return 1;
-}
-
/* How many unintersting commits we want to look at after we run out of interesting ones */
#define SLOP 5
if (!list)
return 0;
- /*
- * If the destination list has commits with an earlier date
- * than our source we want to continue looking.
- */
- if (time <= list->item->time)
- return SLOP;
-
- /* If we find interesting commits, we reset the slop count */
- if (!everybody_uninteresting(list))
- return SLOP;
+ for (; list; list = list->next) {
+ /*
+ * If the destination list has commits with an earlier date than
+ * our source or if it still contains interesting commits we
+ * want to continue looking.
+ */
+ if (!list->item->uninteresting || list->item->time > time)
+ return SLOP;
+ }
/* Everything's uninteresting, reduce the count */
return slop - 1;
ssl_opts |= SSL_OP_NO_COMPRESSION;
#endif
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
#else
-# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+# if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
GIT_INLINE(BIO_METHOD*) BIO_meth_new(int type, const char *name)
{
static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name);
static git_config_backend *open_gitmodules(git_repository *repo, int gitmod);
-static git_config *gitmodules_snapshot(git_repository *repo);
+static int gitmodules_snapshot(git_config **snap, git_repository *repo);
static int get_url_base(git_buf *url, git_repository *repo);
static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo);
static int lookup_default_remote(git_remote **remote, git_repository *repo);
* TODO: for some use-cases, this might need case-folding on a
* case-insensitive filesystem
*/
-static int load_submodule_names(git_strmap *out, git_config *cfg)
+static int load_submodule_names(git_strmap *out, git_repository *repo, git_config *cfg)
{
const char *key = "submodule\\..*\\.path";
git_config_iterator *iter;
git_config_entry *entry;
git_buf buf = GIT_BUF_INIT;
- int rval;
+ int rval, isvalid;
int error = 0;
if ((error = git_config_iterator_glob_new(&iter, cfg, key)) < 0)
fdot = strchr(entry->name, '.');
ldot = strrchr(entry->name, '.');
+ if (git_strmap_exists(out, entry->value)) {
+ giterr_set(GITERR_SUBMODULE,
+ "duplicated submodule path '%s'", entry->value);
+ error = -1;
+ goto out;
+ }
+
+ git_buf_clear(&buf);
git_buf_put(&buf, fdot + 1, ldot - fdot - 1);
+ isvalid = git_submodule_name_is_valid(repo, buf.ptr, 0);
+ if (isvalid < 0) {
+ error = isvalid;
+ goto out;
+ }
+ if (!isvalid)
+ continue;
+
git_strmap_insert(out, entry->value, git_buf_detach(&buf), &rval);
if (rval < 0) {
giterr_set(GITERR_NOMEMORY, "error inserting submodule into hash table");
return -1;
}
}
+ if (error == GIT_ITEROVER)
+ error = 0;
+out:
+ git_buf_free(&buf);
git_config_iterator_free(iter);
- return 0;
+ return error;
}
int git_submodule_lookup(
return 0;
}
+int git_submodule_name_is_valid(git_repository *repo, const char *name, int flags)
+{
+ git_buf buf = GIT_BUF_INIT;
+ int error, isvalid;
+
+ if (flags == 0)
+ flags = GIT_PATH_REJECT_FILESYSTEM_DEFAULTS;
+
+ /* Avoid allocating a new string if we can avoid it */
+ if (strchr(name, '\\') != NULL) {
+ if ((error = git_path_normalize_slashes(&buf, name)) < 0)
+ return error;
+ } else {
+ git_buf_attach_notowned(&buf, name, strlen(name));
+ }
+
+ isvalid = git_path_isvalid(repo, buf.ptr, 0, flags);
+ git_buf_free(&buf);
+
+ return isvalid;
+}
+
static void submodule_free_dup(void *sm)
{
git_submodule_free(sm);
git_strmap *names = 0;
git_strmap_alloc(&names);
- if ((error = load_submodule_names(names, cfg)))
+ if ((error = load_submodule_names(names, git_index_owner(idx), cfg)))
goto done;
if ((error = git_iterator_for_index(&i, git_index_owner(idx), idx, NULL)) < 0)
const git_index_entry *entry;
git_strmap *names = 0;
git_strmap_alloc(&names);
- if ((error = load_submodule_names(names, cfg)))
+ if ((error = load_submodule_names(names, git_tree_owner(head), cfg)))
goto done;
if ((error = git_iterator_for_tree(&i, head, NULL)) < 0)
data.map = map;
data.repo = repo;
- if ((mods = gitmodules_snapshot(repo)) == NULL)
+ if ((error = gitmodules_snapshot(&mods, repo)) < 0) {
+ if (error == GIT_ENOTFOUND)
+ error = 0;
goto cleanup;
+ }
data.mods = mods;
if ((error = git_config_foreach(
int git_submodule_reload(git_submodule *sm, int force)
{
- int error = 0;
+ int error = 0, isvalid;
git_config *mods;
GIT_UNUSED(force);
assert(sm);
+ isvalid = git_submodule_name_is_valid(sm->repo, sm->name, 0);
+ if (isvalid <= 0) {
+ /* This should come with a warning, but we've no API for that */
+ return isvalid;
+ }
+
if (!git_repository_is_bare(sm->repo)) {
/* refresh config data */
- mods = gitmodules_snapshot(sm->repo);
+ if ((error = gitmodules_snapshot(&mods, sm->repo)) < 0 && error != GIT_ENOTFOUND)
+ return error;
if (mods != NULL) {
error = submodule_read_config(sm, mods);
git_config_free(mods);
git_strmap *map = data->map;
git_buf name = GIT_BUF_INIT;
git_submodule *sm;
- int error;
+ int error, isvalid;
if (git__prefixcmp(entry->name, "submodule.") != 0)
return 0;
if ((error = git_buf_set(&name, namestart, property - namestart -1)) < 0)
return error;
+ isvalid = git_submodule_name_is_valid(data->repo, name.ptr, 0);
+ if (isvalid <= 0) {
+ error = isvalid;
+ goto done;
+ }
+
/*
* Now that we have the submodule's name, we can use that to
* figure out whether it's in the map. If it's not, we create
}
/**
- * Returns a snapshot of $WORK_TREE/.gitmodules.
+ * Requests a snapshot of $WORK_TREE/.gitmodules.
*
- * We ignore any errors and just pretend the file isn't there.
+ * Returns GIT_ENOTFOUND in case no .gitmodules file exist
*/
-static git_config *gitmodules_snapshot(git_repository *repo)
+static int gitmodules_snapshot(git_config **snap, git_repository *repo)
{
const char *workdir = git_repository_workdir(repo);
- git_config *mods = NULL, *snap = NULL;
+ git_config *mods = NULL;
git_buf path = GIT_BUF_INIT;
+ int error;
- if (workdir != NULL) {
- if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0)
- return NULL;
+ if (!workdir)
+ return GIT_ENOTFOUND;
- if (git_config_open_ondisk(&mods, path.ptr) < 0)
- mods = NULL;
- }
+ if ((error = git_buf_joinpath(&path, workdir, GIT_MODULES_FILE)) < 0)
+ return error;
- git_buf_free(&path);
+ if ((error = git_config_open_ondisk(&mods, path.ptr)) < 0)
+ goto cleanup;
+
+ if ((error = git_config_snapshot(snap, mods)) < 0)
+ goto cleanup;
- if (mods) {
- git_config_snapshot(&snap, mods);
+ error = 0;
+
+cleanup:
+ if (mods)
git_config_free(mods);
- }
+ git_buf_free(&path);
- return snap;
+ return error;
}
static git_config_backend *open_gitmodules(
extern int git_submodule__map(
git_repository *repo,
git_strmap *map);
+
+/**
+ * Check whether a submodule's name is valid.
+ *
+ * Check the path against the path validity rules, either the filesystem
+ * defaults (like checkout does) or whichever you want to compare against.
+ *
+ * @param repo the repository which contains the submodule
+ * @param name the name to check
+ * @param flags the `GIT_PATH` flags to use for the check (0 to use filesystem defaults)
+ */
+extern int git_submodule_name_is_valid(git_repository *repo, const char *name, int flags);
+
#endif
static int foreach_reference_cb(git_reference *reference, void *payload)
{
git_revwalk *walk = (git_revwalk *)payload;
+ int error;
+
+ if (git_reference_type(reference) != GIT_REF_OID) {
+ git_reference_free(reference);
+ return 0;
+ }
- int error = git_revwalk_hide(walk, git_reference_target(reference));
+ error = git_revwalk_hide(walk, git_reference_target(reference));
/* The reference is in the local repository, so the target may not
* exist on the remote. It also may not be a commit. */
if (error == GIT_ENOTFOUND || error == GITERR_INVALID) {
pkt->ref = NULL;
pkt->type = GIT_PKT_NG;
+ if (len < 3)
+ goto out_err;
line += 3; /* skip "ng " */
- if (!(ptr = strchr(line, ' ')))
+ len -= 3;
+ if (!(ptr = memchr(line, ' ', len)))
goto out_err;
len = ptr - line;
memcpy(pkt->ref, line, len);
pkt->ref[len] = '\0';
+ if (len < 1)
+ goto out_err;
line = ptr + 1;
- if (!(ptr = strchr(line, '\n')))
+ len -= 1;
+ if (!(ptr = memchr(line, '\n', len)))
goto out_err;
len = ptr - line;
}
if (s->session) {
+ libssh2_session_disconnect(s->session, "closing transport");
libssh2_session_free(s->session);
s->session = NULL;
}
}
do {
- rc = libssh2_session_startup(s, socket->s);
+ rc = libssh2_session_handshake(s, socket->s);
} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
if (rc != LIBSSH2_ERROR_NONE) {
static int valid_entry_name(git_repository *repo, const char *filename)
{
return *filename != '\0' &&
- git_path_isvalid(repo, filename,
+ git_path_isvalid(repo, filename, 0,
GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_PATH_REJECT_SLASH);
}
#include "common.h"
#ifdef GIT_WIN32
+# include "win32/utf-conv.h"
# include "win32/w32_buffer.h"
+
+# ifdef HAVE_QSORT_S
+# include <search.h>
+# endif
#endif
#ifdef _MSC_VER
goto out;
}
- if ((wt = git__calloc(1, sizeof(struct git_repository))) == NULL) {
+ if ((wt = git__calloc(1, sizeof(*wt))) == NULL) {
error = -1;
goto out;
}
SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\")
ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\")
+ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
INCLUDE_DIRECTORIES(${CLAR_PATH} ${libgit2_BINARY_DIR}/src)
FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h)
${CLAR_PATH}/clar.c
PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite)
-LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
ADD_EXECUTABLE(libgit2_clar ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS})
assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
}
+void test_attr_ignore__ignore_dir(void)
+{
+ cl_git_rewritefile("attr/.gitignore", "dir/\n");
+
+ assert_is_ignored(true, "dir");
+ assert_is_ignored(true, "dir/file");
+}
+
+void test_attr_ignore__ignore_dir_with_trailing_space(void)
+{
+ cl_git_rewritefile("attr/.gitignore", "dir/ \n");
+
+ assert_is_ignored(true, "dir");
+ assert_is_ignored(true, "dir/file");
+}
+
void test_attr_ignore__ignore_root(void)
{
cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder");
test_checkout_passes("refs/heads/symlink3", ".git/foobar");
}
+void test_checkout_nasty__gitmodules_symlink(void)
+{
+ cl_repo_set_bool(repo, "core.protectHFS", true);
+ test_checkout_fails("refs/heads/gitmodules-symlink", ".gitmodules");
+ cl_repo_set_bool(repo, "core.protectHFS", false);
+
+ cl_repo_set_bool(repo, "core.protectNTFS", true);
+ test_checkout_fails("refs/heads/gitmodules-symlink", ".gitmodules");
+ cl_repo_set_bool(repo, "core.protectNTFS", false);
+
+ test_checkout_fails("refs/heads/gitmodules-symlink", ".gitmodules");
+}
#include "clar_libgit2.h"
+#include "diff_generate.h"
#include "git2/checkout.h"
#include "path.h"
#include "posix.h"
git_object_free(obj);
}
}
+
+void test_checkout_typechange__status_char(void)
+{
+ size_t i;
+ git_oid oid;
+ git_commit *commit;
+ git_diff *diff;
+ const git_diff_delta *delta;
+ git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+ char expected[8] = {'M', 'M', 'R', 'T', 'D', 'R', 'A', 'R'};
+
+ git_oid_fromstr(&oid, "9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a");
+ cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
+ diffopts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
+ cl_git_pass(git_diff__commit(&diff, g_repo, commit, &diffopts));
+ cl_git_pass(git_diff_find_similar(diff, NULL));
+
+ for (i = 0; i < git_diff_num_deltas(diff); i++) {
+ delta = git_diff_get_delta(diff, i);
+ cl_assert_equal_i(expected[i], git_diff_status_char(delta->status));
+ }
+
+ git_diff_free(diff);
+ git_commit_free(commit);
+}
--- /dev/null
+#include "clar_libgit2.h"
+
+#include "delta.h"
+
+void test_delta_apply__read_at_off(void)
+{
+ unsigned char base[16] = { 0 }, delta[] = { 0x10, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00 };
+ void *out;
+ size_t outlen;
+
+ cl_git_fail(git_delta_apply(&out, &outlen, base, sizeof(base), delta, sizeof(delta)));
+}
+
+void test_delta_apply__read_after_limit(void)
+{
+ unsigned char base[16] = { 0 }, delta[] = { 0x10, 0x70, 0xff };
+ void *out;
+ size_t outlen;
+
+ cl_git_fail(git_delta_apply(&out, &outlen, base, sizeof(base), delta, sizeof(delta)));
+}
#include "git2/sys/diff.h"
#include "buffer.h"
+#include "delta.h"
#include "filebuf.h"
#include "repository.h"
git_buf_free(&buf);
}
-void test_diff_stats__rename_and_modifiy_no_find(void)
+void test_diff_stats__rename_and_modify_no_find(void)
{
git_buf buf = GIT_BUF_INIT;
const char *stat =
cl_fixture_cleanup("./repowithunborn");
}
+void test_fetchhead_nonetwork__fetch_into_repo_with_symrefs(void)
+{
+ git_repository *repo;
+ git_remote *remote;
+ git_reference *symref;
+
+ repo = cl_git_sandbox_init("empty_standard_repo");
+
+ /*
+ * Testing for a specific constellation where the repository has at
+ * least one symbolic reference in its refdb.
+ */
+ cl_git_pass(git_reference_symbolic_create(&symref, repo, "refs/heads/symref", "refs/heads/master", 0, NULL));
+
+ cl_git_pass(git_remote_set_url(repo, "origin", cl_fixture("testrepo.git")));
+ cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
+ cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
+
+ git_remote_free(remote);
+ git_reference_free(symref);
+ cl_git_sandbox_cleanup();
+}
+
void test_fetchhead_nonetwork__quote_in_branch_name(void)
{
cl_set_cleanup(&cleanup_repository, "./test1");
void test_path_core__isvalid_standard(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/file.txt", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.file", 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/file.txt", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.file", 0, 0));
}
void test_path_core__isvalid_empty_dir_component(void)
{
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo//bar", 0));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo//bar", 0, 0));
/* leading slash */
- cl_assert_equal_b(false, git_path_isvalid(NULL, "/", 0));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo", 0));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo/bar", 0));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "/", 0, 0));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo", 0, 0));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo/bar", 0, 0));
/* trailing slash */
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/", 0));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/", 0));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/", 0, 0));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/", 0, 0));
}
void test_path_core__isvalid_dot_and_dotdot(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0));
-
- cl_assert_equal_b(true, git_path_isvalid(NULL, "..", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/..", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".", GIT_PATH_REJECT_TRAVERSAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", GIT_PATH_REJECT_TRAVERSAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.", GIT_PATH_REJECT_TRAVERSAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", GIT_PATH_REJECT_TRAVERSAL));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "..", GIT_PATH_REJECT_TRAVERSAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", GIT_PATH_REJECT_TRAVERSAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/..", GIT_PATH_REJECT_TRAVERSAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", GIT_PATH_REJECT_TRAVERSAL));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0));
+
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "..", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/..", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_TRAVERSAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.", 0, GIT_PATH_REJECT_TRAVERSAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "..", 0, GIT_PATH_REJECT_TRAVERSAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/..", 0, GIT_PATH_REJECT_TRAVERSAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL));
}
void test_path_core__isvalid_dot_git(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git/foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git/bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.GIT/bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.Git", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_LITERAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git/foo", GIT_PATH_REJECT_DOT_GIT_LITERAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git", GIT_PATH_REJECT_DOT_GIT_LITERAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git/bar", GIT_PATH_REJECT_DOT_GIT_LITERAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.GIT/bar", GIT_PATH_REJECT_DOT_GIT_LITERAL));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/.Git", GIT_PATH_REJECT_DOT_GIT_LITERAL));
-
- cl_assert_equal_b(true, git_path_isvalid(NULL, "!git", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/!git", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "!git/bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.tig", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig/bar", 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git/foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git/bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.GIT/bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.Git", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "!git", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/!git", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "!git/bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.tig", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig/bar", 0, 0));
}
void test_path_core__isvalid_backslash(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo\\file.txt", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\file.txt", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\", 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo\\file.txt", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\", 0, 0));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo\\file.txt", GIT_PATH_REJECT_BACKSLASH));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\file.txt", GIT_PATH_REJECT_BACKSLASH));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\", GIT_PATH_REJECT_BACKSLASH));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\", 0, GIT_PATH_REJECT_BACKSLASH));
}
void test_path_core__isvalid_trailing_dot(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo.", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo...", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar.", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo./bar", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo.", GIT_PATH_REJECT_TRAILING_DOT));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo...", GIT_PATH_REJECT_TRAILING_DOT));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar.", GIT_PATH_REJECT_TRAILING_DOT));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo./bar", GIT_PATH_REJECT_TRAILING_DOT));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo.", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo...", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar.", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo./bar", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo.", 0, GIT_PATH_REJECT_TRAILING_DOT));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo...", 0, GIT_PATH_REJECT_TRAILING_DOT));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar.", 0, GIT_PATH_REJECT_TRAILING_DOT));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo./bar", 0, GIT_PATH_REJECT_TRAILING_DOT));
}
void test_path_core__isvalid_trailing_space(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar ", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, " ", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo /bar", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", GIT_PATH_REJECT_TRAILING_SPACE));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", GIT_PATH_REJECT_TRAILING_SPACE));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar ", GIT_PATH_REJECT_TRAILING_SPACE));
- cl_assert_equal_b(false, git_path_isvalid(NULL, " ", GIT_PATH_REJECT_TRAILING_SPACE));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo /bar", GIT_PATH_REJECT_TRAILING_SPACE));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar ", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, " ", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo /bar", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, " ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo /bar", 0, GIT_PATH_REJECT_TRAILING_SPACE));
}
void test_path_core__isvalid_trailing_colon(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar:", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ":", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:/bar", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:", GIT_PATH_REJECT_TRAILING_COLON));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar:", GIT_PATH_REJECT_TRAILING_COLON));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ":", GIT_PATH_REJECT_TRAILING_COLON));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:/bar", GIT_PATH_REJECT_TRAILING_COLON));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar:", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ":", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:/bar", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:", 0, GIT_PATH_REJECT_TRAILING_COLON));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar:", 0, GIT_PATH_REJECT_TRAILING_COLON));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ":", 0, GIT_PATH_REJECT_TRAILING_COLON));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:/bar", 0, GIT_PATH_REJECT_TRAILING_COLON));
}
void test_path_core__isvalid_dotgit_ntfs(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git ", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.. .", 0));
-
- cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1 ", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.. .", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_NTFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git ", GIT_PATH_REJECT_DOT_GIT_NTFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.", GIT_PATH_REJECT_DOT_GIT_NTFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.. .", GIT_PATH_REJECT_DOT_GIT_NTFS));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1", GIT_PATH_REJECT_DOT_GIT_NTFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1 ", GIT_PATH_REJECT_DOT_GIT_NTFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.", GIT_PATH_REJECT_DOT_GIT_NTFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.. .", GIT_PATH_REJECT_DOT_GIT_NTFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git ", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.. .", 0, 0));
+
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1 ", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.. .", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
}
void test_path_core__isvalid_dos_paths(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf\\zippy", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:asdf\\foobar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "con", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "prn", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "nul", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "aux", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf\\zippy", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:asdf\\foobar", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "con", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "prn", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "nul", GIT_PATH_REJECT_DOS_PATHS));
-
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "auxn", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "aux\\foo", GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "con", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "prn", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "nul", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "aux", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "con", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "prn", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "nul", 0, GIT_PATH_REJECT_DOS_PATHS));
+
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "auxn", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "aux\\foo", 0, GIT_PATH_REJECT_DOS_PATHS));
}
void test_path_core__isvalid_dos_paths_withnum(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf\\zippy", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:asdf\\foobar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt1", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "com1", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf\\zippy", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:asdf\\foobar", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "com1/foo", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "lpt1", GIT_PATH_REJECT_DOS_PATHS));
-
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "comn", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt0", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt10", GIT_PATH_REJECT_DOS_PATHS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "lptn", GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt1", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "com1", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "com1/foo", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "lpt1", 0, GIT_PATH_REJECT_DOS_PATHS));
+
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "comn", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt0", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt10", 0, GIT_PATH_REJECT_DOS_PATHS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "lptn", 0, GIT_PATH_REJECT_DOS_PATHS));
}
void test_path_core__isvalid_nt_chars(void)
{
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\001foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\037bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf<bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf>foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf:foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\"bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf|foo", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf?bar", 0));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf*bar", 0));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\001foo", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\037bar", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf<bar", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf>foo", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf:foo", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\"bar", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf|foo", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf?bar", GIT_PATH_REJECT_NT_CHARS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf*bar", GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\001foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\037bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf<bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf>foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf:foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\"bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf|foo", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf?bar", 0, 0));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf*bar", 0, 0));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\001foo", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\037bar", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf<bar", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf>foo", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf:foo", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\"bar", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf|foo", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf?bar", 0, GIT_PATH_REJECT_NT_CHARS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf*bar", 0, GIT_PATH_REJECT_NT_CHARS));
}
void test_path_core__isvalid_dotgit_with_hfs_ignorables(void)
{
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".git\xe2\x80\x8c", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".g\xe2\x80\x8eIt", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, ".\xe2\x80\x8fgIt", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xaa.gIt", GIT_PATH_REJECT_DOT_GIT_HFS));
-
- cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", GIT_PATH_REJECT_DOT_GIT_HFS));
-
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".g", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, " .git", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "..git\xe2\x80\x8c", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT.", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2\x80It", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".\xe2gIt", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, "\xe2\x80\xaa.gi", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x80\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2i\x80T\x8e", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", GIT_PATH_REJECT_DOT_GIT_HFS));
- cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+ cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
}
static void test_join_unrooted(
--- /dev/null
+#include "clar_libgit2.h"
+#include "path.h"
+
+static char *gitmodules_altnames[] = {
+ ".gitmodules",
+
+ /*
+ * Equivalent to the ".git\u200cmodules" string from git but hard-coded
+ * as a UTF-8 sequence
+ */
+ ".git\xe2\x80\x8cmodules",
+
+ ".Gitmodules",
+ ".gitmoduleS",
+
+ ".gitmodules ",
+ ".gitmodules.",
+ ".gitmodules ",
+ ".gitmodules. ",
+ ".gitmodules .",
+ ".gitmodules..",
+ ".gitmodules ",
+ ".gitmodules. ",
+ ".gitmodules . ",
+ ".gitmodules .",
+
+ ".Gitmodules ",
+ ".Gitmodules.",
+ ".Gitmodules ",
+ ".Gitmodules. ",
+ ".Gitmodules .",
+ ".Gitmodules..",
+ ".Gitmodules ",
+ ".Gitmodules. ",
+ ".Gitmodules . ",
+ ".Gitmodules .",
+
+ "GITMOD~1",
+ "gitmod~1",
+ "GITMOD~2",
+ "gitmod~3",
+ "GITMOD~4",
+
+ "GITMOD~1 ",
+ "gitmod~2.",
+ "GITMOD~3 ",
+ "gitmod~4. ",
+ "GITMOD~1 .",
+ "gitmod~2 ",
+ "GITMOD~3. ",
+ "gitmod~4 . ",
+
+ "GI7EBA~1",
+ "gi7eba~9",
+
+ "GI7EB~10",
+ "GI7EB~11",
+ "GI7EB~99",
+ "GI7EB~10",
+ "GI7E~100",
+ "GI7E~101",
+ "GI7E~999",
+ "~1000000",
+ "~9999999",
+};
+
+static char *gitmodules_not_altnames[] = {
+ ".gitmodules x",
+ ".gitmodules .x",
+
+ " .gitmodules",
+
+ "..gitmodules",
+
+ "gitmodules",
+
+ ".gitmodule",
+
+ ".gitmodules x ",
+ ".gitmodules .x",
+
+ "GI7EBA~",
+ "GI7EBA~0",
+ "GI7EBA~~1",
+ "GI7EBA~X",
+ "Gx7EBA~1",
+ "GI7EBX~1",
+
+ "GI7EB~1",
+ "GI7EB~01",
+ "GI7EB~1",
+};
+
+void test_path_dotgit__dotgit_modules(void)
+{
+ size_t i;
+ cl_assert_equal_i(1, git_path_is_dotgit_modules(".gitmodules", strlen(".gitmodules")));
+ cl_assert_equal_i(1, git_path_is_dotgit_modules(".git\xe2\x80\x8cmodules", strlen(".git\xe2\x80\x8cmodules")));
+
+ for (i = 0; i < ARRAY_SIZE(gitmodules_altnames); i++) {
+ const char *name = gitmodules_altnames[i];
+ if (!git_path_is_dotgit_modules(name, strlen(name)))
+ cl_fail(name);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(gitmodules_not_altnames); i++) {
+ const char *name = gitmodules_not_altnames[i];
+ if (git_path_is_dotgit_modules(name, strlen(name)))
+ cl_fail(name);
+ }
+
+}
+
+void test_path_dotgit__dotgit_modules_symlink(void)
+{
+ 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_git_pass(git_reference_dup(&b, a));
cl_assert(git_reference_cmp(a, b) == 0);
+ cl_assert(git_reference_owner(b) == g_repo);
git_reference_free(b);
git_reference_free(a);
cl_git_pass(git_reference_dup(&b, a));
cl_assert(git_reference_cmp(a, b) == 0);
+ cl_assert(git_reference_owner(b) == g_repo);
git_reference_free(b);
git_reference_free(a);
--- /dev/null
+e30b60b120761f44ebd0f0a7b0e9445ce8e11d68
--- /dev/null
+ref: refs/heads/master
--- /dev/null
+[core]
+ bare = true
+ repositoryformatversion = 0
+ filemode = false
+ symlinks = false
+ ignorecase = true
--- /dev/null
+Unnamed repository; edit this file 'description' to name the repository.
--- /dev/null
+P pack-9adacb9971981a1a3264fd473da5b800f2715959.pack
+
--- /dev/null
+# pack-refs with: peeled fully-peeled sorted
+3ae0f53011bdb7e68f99bde4943449f36c1c318a refs/heads/A
+061978578d7c9ff2ba92dd36d31fd8d809871030 refs/heads/B
+743398b425d6c216d6cfaae3786b5bc436393ae5 refs/heads/C
+790ba0facf6fd103699a5c40cd19dad277ff49cd refs/heads/D
+d3d783066cf7d95def6844b9c5118c1e7bcce7df refs/heads/E
+d3d783066cf7d95def6844b9c5118c1e7bcce7df refs/heads/master
cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oid, _walk));
}
+
+/*
+ * Ensure that we correctly hide all parent commits of a newer
+ * commit when first hiding older commits.
+ *
+ * % git rev-list D ^B ^A ^E
+ * 790ba0facf6fd103699a5c40cd19dad277ff49cd
+ * b82cee5004151ae0c4f82b69fb71b87477664b6f
+ */
+void test_revwalk_basic__newer_hidden_commit_hides_old_commits(void)
+{
+ git_oid oid;
+
+ revwalk_basic_setup_walk("revwalk.git");
+
+ cl_git_pass(git_revwalk_push_ref(_walk, "refs/heads/D"));
+ cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/B"));
+ cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/A"));
+ cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/E"));
+
+ cl_git_pass(git_revwalk_next(&oid, _walk));
+ cl_assert(git_oid_streq(&oid, "b82cee5004151ae0c4f82b69fb71b87477664b6f"));
+ cl_git_pass(git_revwalk_next(&oid, _walk));
+ cl_assert(git_oid_streq(&oid, "790ba0facf6fd103699a5c40cd19dad277ff49cd"));
+
+ cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oid, _walk));
+}
--- /dev/null
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "fileops.h"
+#include "repository.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_escape__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+#define EVIL_SM_NAME "../../modules/evil"
+#define EVIL_SM_NAME_WINDOWS "..\\\\..\\\\modules\\\\evil"
+#define EVIL_SM_NAME_WINDOWS_UNESC "..\\..\\modules\\evil"
+
+static int find_evil(git_submodule *sm, const char *name, void *payload)
+{
+ int *foundit = (int *) payload;
+
+ GIT_UNUSED(sm);
+
+ if (!git__strcmp(EVIL_SM_NAME, name) ||
+ !git__strcmp(EVIL_SM_NAME_WINDOWS_UNESC, name))
+ *foundit = true;
+
+ return 0;
+}
+
+void test_submodule_escape__from_gitdir(void)
+{
+ int foundit;
+ git_submodule *sm;
+ git_buf buf = GIT_BUF_INIT;
+ unsigned int sm_location;
+
+ g_repo = setup_fixture_submodule_simple();
+
+ cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules"));
+ cl_git_rewritefile(buf.ptr,
+ "[submodule \"" EVIL_SM_NAME "\"]\n"
+ " path = testrepo\n"
+ " url = ../testrepo.git\n");
+ git_buf_free(&buf);
+
+ /* Find it all the different ways we know about it */
+ foundit = 0;
+ cl_git_pass(git_submodule_foreach(g_repo, find_evil, &foundit));
+ cl_assert_equal_i(0, foundit);
+ cl_git_fail_with(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, EVIL_SM_NAME));
+ /*
+ * We do know about this as it's in the index and HEAD, but the data is
+ * incomplete as there is no configured data for it (we pretend it
+ * doesn't exist). This leaves us with an odd situation but it's
+ * consistent with what we would do if we did add a submodule with no
+ * configuration.
+ */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+ cl_git_pass(git_submodule_location(&sm_location, sm));
+ cl_assert_equal_i(GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS_IN_HEAD, sm_location);
+ git_submodule_free(sm);
+}
+
+void test_submodule_escape__from_gitdir_windows(void)
+{
+ int foundit;
+ git_submodule *sm;
+ git_buf buf = GIT_BUF_INIT;
+ unsigned int sm_location;
+
+ g_repo = setup_fixture_submodule_simple();
+
+ cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules"));
+ cl_git_rewritefile(buf.ptr,
+ "[submodule \"" EVIL_SM_NAME_WINDOWS "\"]\n"
+ " path = testrepo\n"
+ " url = ../testrepo.git\n");
+ git_buf_free(&buf);
+
+ /* Find it all the different ways we know about it */
+ foundit = 0;
+ cl_git_pass(git_submodule_foreach(g_repo, find_evil, &foundit));
+ cl_assert_equal_i(0, foundit);
+ cl_git_fail_with(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, EVIL_SM_NAME_WINDOWS_UNESC));
+ /*
+ * We do know about this as it's in the index and HEAD, but the data is
+ * incomplete as there is no configured data for it (we pretend it
+ * doesn't exist). This leaves us with an odd situation but it's
+ * consistent with what we would do if we did add a submodule with no
+ * configuration.
+ */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+ cl_git_pass(git_submodule_location(&sm_location, sm));
+ cl_assert_equal_i(GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS_IN_HEAD, sm_location);
+ git_submodule_free(sm);
+}
cl_assert_equal_i(8, data.count);
}
+static int foreach_cb(git_submodule *sm, const char *name, void *payload)
+{
+ GIT_UNUSED(sm);
+ GIT_UNUSED(name);
+ GIT_UNUSED(payload);
+ return 0;
+}
+
+void test_submodule_lookup__duplicated_path(void)
+{
+ cl_git_rewritefile("submod2/.gitmodules",
+ "[submodule \"sm1\"]\n"
+ " path = duplicated-path\n"
+ " url = sm1\n"
+ "[submodule \"sm2\"]\n"
+ " path = duplicated-path\n"
+ " url = sm2\n");
+
+ cl_git_fail(git_submodule_foreach(g_repo, foreach_cb, NULL));
+}
+
void test_submodule_lookup__lookup_even_with_unborn_head(void)
{
git_reference *head;
cl_git_fail(git_submodule_lookup(&sm, g_repo, "nonexisting"));
}
-static int foreach_cb(git_submodule *sm, const char *name, void *payload)
-{
- GIT_UNUSED(sm);
- GIT_UNUSED(name);
- GIT_UNUSED(payload);
- return 0;
-}
-
void test_submodule_lookup__foreach_in_bare_repository_fails(void)
{
cl_git_sandbox_cleanup();
cl_git_fail(git_submodule_foreach(g_repo, foreach_cb, NULL));
}
+
+void test_submodule_lookup__fail_invalid_gitmodules(void)
+{
+ git_submodule *sm;
+ sm_lookup_data data;
+ memset(&data, 0, sizeof(data));
+
+ cl_git_rewritefile("submod2/.gitmodules",
+ "[submodule \"Test_App\"\n"
+ " path = Test_App\n"
+ " url = ../Test_App\n");
+
+ cl_git_fail(git_submodule_lookup(&sm, g_repo, "Test_App"));
+
+ cl_git_fail(git_submodule_foreach(g_repo, sm_lookup_cb, &data));
+}
cleanup_fixture_worktree(&fixture);
}
+void test_worktree_reflog__read_worktree_HEAD(void)
+{
+ git_reflog *reflog;
+ const git_reflog_entry *entry;
+
+ cl_git_pass(git_reflog_read(&reflog, fixture.worktree, "HEAD"));
+ cl_assert_equal_i(1, git_reflog_entrycount(reflog));
+
+ entry = git_reflog_entry_byindex(reflog, 0);
+ cl_assert(entry != NULL);
+ cl_assert_equal_s("checkout: moving from 099fabac3a9ea935598528c27f866e34089c2eff to testrepo-worktree", git_reflog_entry_message(entry));
+
+ git_reflog_free(reflog);
+}
+
+void test_worktree_reflog__read_parent_HEAD(void)
+{
+ git_reflog *reflog;
+
+ cl_git_pass(git_reflog_read(&reflog, fixture.repo, "HEAD"));
+ /* there is no logs/HEAD in the parent repo */
+ cl_assert_equal_i(0, git_reflog_entrycount(reflog));
+
+ git_reflog_free(reflog);
+}
+
void test_worktree_reflog__read(void)
{
git_reflog *reflog;
cl_git_pass(git_reference_lookup(&ref, fixture.repo, "refs/heads/testrepo-worktree"));
cl_git_pass(git_repository_head_for_worktree(&head, fixture.repo, "testrepo-worktree"));
cl_assert(git_reference_cmp(ref, head) == 0);
+ cl_assert(git_reference_owner(ref) == fixture.repo);
git_reference_free(ref);
git_reference_free(head);