summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/main.yml4
-rw-r--r--INSTALL4
-rw-r--r--builtin/clone.c9
-rwxr-xr-xci/install-dependencies.sh24
-rwxr-xr-xci/lib.sh7
-rw-r--r--compat/nedmalloc/nedmalloc.c1
-rw-r--r--compat/win32/syslog.c2
-rw-r--r--http-push.c8
-rw-r--r--http.c105
-rw-r--r--http.h8
-rw-r--r--range-diff.c29
-rw-r--r--remote-curl.c32
12 files changed, 149 insertions, 84 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index a3fbbe6398..07f3ab3f8f 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -282,7 +282,7 @@ jobs:
pool: ubuntu-latest
- jobname: linux-gcc
cc: gcc
- pool: ubuntu-latest
+ pool: ubuntu-20.04
- jobname: osx-clang
cc: clang
pool: macos-latest
@@ -340,7 +340,7 @@ jobs:
if: needs.ci-config.outputs.enabled == 'yes'
env:
jobname: StaticAnalysis
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v1
- run: ci/install-dependencies.sh
diff --git a/INSTALL b/INSTALL
index 8474ad01bf..88c8b3cd46 100644
--- a/INSTALL
+++ b/INSTALL
@@ -145,6 +145,10 @@ Issues of note:
patches into an IMAP mailbox, you do not have to have them
(use NO_CURL).
+ Git requires version "7.19.5" or later of "libcurl" to build
+ without NO_CURL. This version requirement may be bumped in
+ the future.
+
- "expat" library; git-http-push uses it for remote lock
management over DAV. Similar to "curl" above, this is optional
(with NO_EXPAT).
diff --git a/builtin/clone.c b/builtin/clone.c
index c042b2e256..9ab17cab19 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -251,6 +251,15 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
}
/*
+ * It should not be possible to overflow `ptrdiff_t` by passing in an
+ * insanely long URL, but GCC does not know that and will complain
+ * without this check.
+ */
+ if (end - start < 0)
+ die(_("No directory name could be guessed.\n"
+ "Please specify a directory on the command line"));
+
+ /*
* Strip trailing port number if we've got only a
* hostname (that is, there is no dir separator but a
* colon). This check is required such that we do not
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index 0b1184e04a..2d54427175 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -5,7 +5,7 @@
. ${0%/*}/lib.sh
-P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION
+P4WHENCE=https://cdist2.perforce.com/perforce/r21.2
LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
UBUNTU_COMMON_PKGS="make libssl-dev libcurl4-openssl-dev libexpat-dev
tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl
@@ -16,7 +16,7 @@ linux-clang|linux-gcc)
sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
sudo apt-get -q update
sudo apt-get -q -y install language-pack-is libsvn-perl apache2 \
- $UBUNTU_COMMON_PKGS
+ $UBUNTU_COMMON_PKGS $PYTHON_PACKAGE
case "$jobname" in
linux-gcc)
sudo apt-get -q -y install gcc-8
@@ -44,13 +44,15 @@ osx-clang|osx-gcc)
test -z "$BREW_INSTALL_PACKAGES" ||
brew install $BREW_INSTALL_PACKAGES
brew link --force gettext
- brew install --cask --no-quarantine perforce || {
- # Update the definitions and try again
- cask_repo="$(brew --repository)"/Library/Taps/homebrew/homebrew-cask &&
- git -C "$cask_repo" pull --no-stat --ff-only &&
- brew install --cask --no-quarantine perforce
- } ||
- brew install homebrew/cask/perforce
+ mkdir -p $HOME/bin
+ (
+ cd $HOME/bin
+ wget -q "$P4WHENCE/bin.macosx1015x86_64/helix-core-server.tgz" &&
+ tar -xf helix-core-server.tgz &&
+ sudo xattr -d com.apple.quarantine p4 p4d 2>/dev/null || true
+ )
+ PATH="$PATH:${HOME}/bin"
+ export PATH
case "$jobname" in
osx-gcc)
brew install gcc@9
@@ -81,9 +83,9 @@ esac
if type p4d >/dev/null && type p4 >/dev/null
then
echo "$(tput setaf 6)Perforce Server Version$(tput sgr0)"
- p4d -V | grep Rev.
+ p4d -V
echo "$(tput setaf 6)Perforce Client Version$(tput sgr0)"
- p4 -V | grep Rev.
+ p4 -V
fi
if type git-lfs >/dev/null
then
diff --git a/ci/lib.sh b/ci/lib.sh
index 38c0eac351..702ea96a38 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -184,13 +184,13 @@ export SKIP_DASHED_BUILT_INS=YesPlease
case "$jobname" in
linux-clang|linux-gcc)
+ PYTHON_PACKAGE=python2
if [ "$jobname" = linux-gcc ]
then
export CC=gcc-8
- MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python3"
- else
- MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python2"
+ PYTHON_PACKAGE=python3
fi
+ MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/$PYTHON_PACKAGE"
export GIT_TEST_HTTPD=true
@@ -199,7 +199,6 @@ linux-clang|linux-gcc)
# were recorded in the Homebrew database upon creating the OS X
# image.
# Keep that in mind when you encounter a broken OS X build!
- export LINUX_P4_VERSION="16.2"
export LINUX_GIT_LFS_VERSION="1.5.2"
P4_PATH="$HOME/custom/p4"
diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c
index 1cc31c3502..141c30f07f 100644
--- a/compat/nedmalloc/nedmalloc.c
+++ b/compat/nedmalloc/nedmalloc.c
@@ -323,7 +323,6 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in
}
static void DestroyCaches(nedpool *p) THROWSPEC
{
- if(p->caches)
{
threadcache *tc;
int n;
diff --git a/compat/win32/syslog.c b/compat/win32/syslog.c
index 161978d720..1f8d8934cc 100644
--- a/compat/win32/syslog.c
+++ b/compat/win32/syslog.c
@@ -43,6 +43,7 @@ void syslog(int priority, const char *fmt, ...)
va_end(ap);
while ((pos = strstr(str, "%1")) != NULL) {
+ size_t offset = pos - str;
char *oldstr = str;
str = realloc(str, st_add(++str_len, 1));
if (!str) {
@@ -50,6 +51,7 @@ void syslog(int priority, const char *fmt, ...)
warning_errno("realloc failed");
return;
}
+ pos = str + offset;
memmove(pos + 2, pos + 1, strlen(pos));
pos[1] = ' ';
}
diff --git a/http-push.c b/http-push.c
index 6a4a43e07f..756779bb19 100644
--- a/http-push.c
+++ b/http-push.c
@@ -198,14 +198,14 @@ static void curl_setup_http(CURL *curl, const char *url,
const char *custom_req, struct buffer *buffer,
curl_write_callback write_fn)
{
- curl_easy_setopt(curl, CURLOPT_PUT, 1);
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_INFILE, buffer);
curl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
-#ifndef NO_CURL_IOCTL
- curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
- curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);
+#ifndef NO_CURL_SEEK
+ curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);
+ curl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
diff --git a/http.c b/http.c
index 8b23a546af..cda8bae086 100644
--- a/http.c
+++ b/http.c
@@ -186,22 +186,20 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
return size / eltsize;
}
-#ifndef NO_CURL_IOCTL
-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp)
+#ifndef NO_CURL_SEEK
+int seek_buffer(void *clientp, curl_off_t offset, int origin)
{
struct buffer *buffer = clientp;
- switch (cmd) {
- case CURLIOCMD_NOP:
- return CURLIOE_OK;
-
- case CURLIOCMD_RESTARTREAD:
- buffer->posn = 0;
- return CURLIOE_OK;
-
- default:
- return CURLIOE_UNKNOWNCMD;
+ if (origin != SEEK_SET)
+ BUG("seek_buffer only handles SEEK_SET");
+ if (offset < 0 || offset >= buffer->buf.len) {
+ error("curl seek would be outside of buffer");
+ return CURL_SEEKFUNC_FAIL;
}
+
+ buffer->posn = offset;
+ return CURL_SEEKFUNC_OK;
}
#endif
@@ -810,20 +808,37 @@ void setup_curl_trace(CURL *handle)
}
#ifdef CURLPROTO_HTTP
-static long get_curl_allowed_protocols(int from_user)
+static void proto_list_append(struct strbuf *list, const char *proto)
+{
+ if (!list)
+ return;
+ if (list->len)
+ strbuf_addch(list, ',');
+ strbuf_addstr(list, proto);
+}
+
+static long get_curl_allowed_protocols(int from_user, struct strbuf *list)
{
- long allowed_protocols = 0;
+ long bits = 0;
- if (is_transport_allowed("http", from_user))
- allowed_protocols |= CURLPROTO_HTTP;
- if (is_transport_allowed("https", from_user))
- allowed_protocols |= CURLPROTO_HTTPS;
- if (is_transport_allowed("ftp", from_user))
- allowed_protocols |= CURLPROTO_FTP;
- if (is_transport_allowed("ftps", from_user))
- allowed_protocols |= CURLPROTO_FTPS;
+ if (is_transport_allowed("http", from_user)) {
+ bits |= CURLPROTO_HTTP;
+ proto_list_append(list, "http");
+ }
+ if (is_transport_allowed("https", from_user)) {
+ bits |= CURLPROTO_HTTPS;
+ proto_list_append(list, "https");
+ }
+ if (is_transport_allowed("ftp", from_user)) {
+ bits |= CURLPROTO_FTP;
+ proto_list_append(list, "ftp");
+ }
+ if (is_transport_allowed("ftps", from_user)) {
+ bits |= CURLPROTO_FTPS;
+ proto_list_append(list, "ftps");
+ }
- return allowed_protocols;
+ return bits;
}
#endif
@@ -981,10 +996,24 @@ static CURL *get_curl_handle(void)
curl_easy_setopt(result, CURLOPT_POST301, 1);
#endif
#ifdef CURLPROTO_HTTP
+#if LIBCURL_VERSION_NUM >= 0x075500
+ {
+ struct strbuf buf = STRBUF_INIT;
+
+ get_curl_allowed_protocols(0, &buf);
+ curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);
+ strbuf_reset(&buf);
+
+ get_curl_allowed_protocols(-1, &buf);
+ curl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);
+ strbuf_release(&buf);
+ }
+#else
curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,
- get_curl_allowed_protocols(0));
+ get_curl_allowed_protocols(0, NULL));
curl_easy_setopt(result, CURLOPT_PROTOCOLS,
- get_curl_allowed_protocols(-1));
+ get_curl_allowed_protocols(-1, NULL));
+#endif
#else
warning(_("Protocol restrictions not supported with cURL < 7.19.4"));
#endif
@@ -1523,6 +1552,32 @@ void run_active_slot(struct active_request_slot *slot)
finish_active_slot(slot);
}
#endif
+
+ /*
+ * The value of slot->finished we set before the loop was used
+ * to set our "finished" variable when our request completed.
+ *
+ * 1. The slot may not have been reused for another requst
+ * yet, in which case it still has &finished.
+ *
+ * 2. The slot may already be in-use to serve another request,
+ * which can further be divided into two cases:
+ *
+ * (a) If call run_active_slot() hasn't been called for that
+ * other request, slot->finished would have been cleared
+ * by get_active_slot() and has NULL.
+ *
+ * (b) If the request did call run_active_slot(), then the
+ * call would have updated slot->finished at the beginning
+ * of this function, and with the clearing of the member
+ * below, we would find that slot->finished is now NULL.
+ *
+ * In all cases, slot->finished has no useful information to
+ * anybody at this point. Some compilers warn us for
+ * attempting to smuggle a pointer that is about to become
+ * invalid, i.e. &finished. We clear it here to assure them.
+ */
+ slot->finished = NULL;
}
static void release_active_slot(struct active_request_slot *slot)
diff --git a/http.h b/http.h
index 5de792ef3f..90679e1410 100644
--- a/http.h
+++ b/http.h
@@ -41,8 +41,8 @@
#define CURLE_HTTP_RETURNED_ERROR CURLE_HTTP_NOT_FOUND
#endif
-#if LIBCURL_VERSION_NUM < 0x070c03
-#define NO_CURL_IOCTL
+#if LIBCURL_VERSION_NUM < 0x071200
+#define NO_CURL_SEEK
#endif
/*
@@ -82,8 +82,8 @@ struct buffer {
size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
-#ifndef NO_CURL_IOCTL
-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);
+#ifndef NO_CURL_SEEK
+int seek_buffer(void *clientp, curl_off_t offset, int origin);
#endif
/* Slot lifecycle functions */
diff --git a/range-diff.c b/range-diff.c
index b9950f10c8..9e2b788cdf 100644
--- a/range-diff.c
+++ b/range-diff.c
@@ -25,17 +25,6 @@ struct patch_util {
struct object_id oid;
};
-static size_t find_end_of_line(char *buffer, unsigned long size)
-{
- char *eol = memchr(buffer, '\n', size);
-
- if (!eol)
- return size;
-
- *eol = '\0';
- return eol + 1 - buffer;
-}
-
/*
* Reads the patches into a string list, with the `util` field being populated
* as struct object_id (will need to be free()d).
@@ -48,7 +37,7 @@ static int read_patches(const char *range, struct string_list *list,
struct patch_util *util = NULL;
int in_header = 1;
char *line, *current_filename = NULL;
- int offset, len;
+ ssize_t len;
size_t size;
strvec_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges",
@@ -83,11 +72,18 @@ static int read_patches(const char *range, struct string_list *list,
line = contents.buf;
size = contents.len;
- for (offset = 0; size > 0; offset += len, size -= len, line += len) {
+ for (; size > 0; size -= len, line += len) {
const char *p;
+ char *eol;
+
+ eol = memchr(line, '\n', size);
+ if (eol) {
+ *eol = '\0';
+ len = eol + 1 - line;
+ } else {
+ len = size;
+ }
- len = find_end_of_line(line, size);
- line[len - 1] = '\0';
if (skip_prefix(line, "commit ", &p)) {
if (util) {
string_list_append(list, buf.buf)->util = util;
@@ -129,7 +125,8 @@ static int read_patches(const char *range, struct string_list *list,
strbuf_addch(&buf, '\n');
if (!util->diff_offset)
util->diff_offset = buf.len;
- line[len - 1] = '\n';
+ if (eol)
+ *eol = '\n';
orig_len = len;
len = parse_git_diff_header(&root, &linenr, 0, line,
len, size, &patch);
diff --git a/remote-curl.c b/remote-curl.c
index 0290b04891..f50531624a 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -707,26 +707,24 @@ static size_t rpc_out(void *ptr, size_t eltsize,
return avail;
}
-#ifndef NO_CURL_IOCTL
-static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)
+#ifndef NO_CURL_SEEK
+static int rpc_seek(void *clientp, curl_off_t offset, int origin)
{
struct rpc_state *rpc = clientp;
- switch (cmd) {
- case CURLIOCMD_NOP:
- return CURLIOE_OK;
+ if (origin != SEEK_SET)
+ BUG("rpc_seek only handles SEEK_SET, not %d", origin);
- case CURLIOCMD_RESTARTREAD:
- if (rpc->initial_buffer) {
- rpc->pos = 0;
- return CURLIOE_OK;
+ if (rpc->initial_buffer) {
+ if (offset < 0 || offset > rpc->len) {
+ error("curl seek would be outside of rpc buffer");
+ return CURL_SEEKFUNC_FAIL;
}
- error(_("unable to rewind rpc post data - try increasing http.postBuffer"));
- return CURLIOE_FAILRESTART;
-
- default:
- return CURLIOE_UNKNOWNCMD;
+ rpc->pos = offset;
+ return CURL_SEEKFUNC_OK;
}
+ error(_("unable to rewind rpc post data - try increasing http.postBuffer"));
+ return CURL_SEEKFUNC_FAIL;
}
#endif
@@ -947,9 +945,9 @@ retry:
rpc->initial_buffer = 1;
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);
curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);
-#ifndef NO_CURL_IOCTL
- curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);
- curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);
+#ifndef NO_CURL_SEEK
+ curl_easy_setopt(slot->curl, CURLOPT_SEEKFUNCTION, rpc_seek);
+ curl_easy_setopt(slot->curl, CURLOPT_SEEKDATA, rpc);
#endif
if (options.verbosity > 1) {
fprintf(stderr, "POST %s (chunked)\n", rpc->service_name);