Commit c7122033789f678884d8f3cc2dcf50b611921b32

Edward Thomson 2015-09-03T11:43:48

Merge pull request #3409 from libgit2/update-v23 Maintenance backports for v23

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4747818..73c9630 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -152,8 +152,18 @@ STRING(REGEX REPLACE "^.*LIBGIT2_SOVERSION ([0-9]+)$" "\\1" LIBGIT2_SOVERSION "$
 INCLUDE_DIRECTORIES(src include)
 
 IF (SECURITY_FOUND)
-  MESSAGE("-- Found Security ${SECURITY_DIRS}")
-  LIST(APPEND LIBGIT2_PC_LIBS "-framework Security")
+  # OS X 10.7 and older do not have some functions we use, fall back to OpenSSL there
+  CHECK_LIBRARY_EXISTS("${SECURITY_DIRS}" SSLCreateContext "Security/SecureTransport.h" HAVE_NEWER_SECURITY)
+  IF (HAVE_NEWER_SECURITY)
+    MESSAGE("-- Found Security ${SECURITY_DIRS}")
+    LIST(APPEND LIBGIT2_PC_LIBS "-framework Security")
+  ELSE()
+    MESSAGE("-- Security framework is too old, falling back to OpenSSL")
+    SET(SECURITY_FOUND "NO")
+    SET(SECURITY_DIRS "")
+    SET(SECURITY_DIR "")
+    SET(USE_OPENSSL "ON")
+  ENDIF()
 ENDIF()
 
 IF (COREFOUNDATION_FOUND)
@@ -286,7 +296,7 @@ IF (LIBSSH2_FOUND)
 	#SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}")
 	SET(SSH_LIBRARIES ${LIBSSH2_LIBRARIES})
 
-	CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
+	CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
 	IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)
 		ADD_DEFINITIONS(-DGIT_SSH_MEMORY_CREDENTIALS)
 	ENDIF()
diff --git a/COPYING b/COPYING
index 6f6115e..1b88b9b 100644
--- a/COPYING
+++ b/COPYING
@@ -407,6 +407,52 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 ----------------------------------------------------------------------
 
 The regex library (deps/regex/) is licensed under the GNU LGPL
+(available at the end of this file).
+
+Definitions for data structures and routines for the regular
+expression library.
+
+Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008
+Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+ 
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with the GNU C Library; if not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+----------------------------------------------------------------------
+
+The bundled winhttp definition files (deps/winhttp/) are licensed under
+the GNU LGPL (available at the end of this file).
+
+Copyright (C) 2007 Francois Gouget
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+----------------------------------------------------------------------
 
                   GNU LESSER GENERAL PUBLIC LICENSE
                        Version 2.1, February 1999
diff --git a/include/git2/config.h b/include/git2/config.h
index 6d3fdb0..537663e 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -171,6 +171,9 @@ GIT_EXTERN(int) git_config_new(git_config **out);
  * parsed; it's expected to be a native Git config file following
  * the default Git config syntax (see man git-config).
  *
+ * If the file does not exist, the file will still be added and it
+ * will be created the first time we write to it.
+ *
  * Note that the configuration object will free the file
  * automatically.
  *
@@ -202,8 +205,7 @@ GIT_EXTERN(int) git_config_add_file_ondisk(
  *
  * @param out The configuration instance to create
  * @param path Path to the on-disk file to open
- * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist
- * or an error code
+ * @return 0 on success, or an error code
  */
 GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path);
 
diff --git a/include/git2/cred_helpers.h b/include/git2/cred_helpers.h
index 840c225..1416d56 100644
--- a/include/git2/cred_helpers.h
+++ b/include/git2/cred_helpers.h
@@ -34,7 +34,7 @@ typedef struct git_cred_userpass_payload {
  *
  * @param cred The newly created credential object.
  * @param url The resource for which we are demanding a credential.
- * @param user_from_url The username that was embedded in a "user@host"
+ * @param user_from_url The username that was embedded in a "user\@host"
  *                          remote url, or NULL if not included.
  * @param allowed_types A bitmask stating which cred types are OK to return.
  * @param payload The payload provided when specifying this callback.  (This is
diff --git a/src/curl_stream.c b/src/curl_stream.c
index 6534bdb..ca06c20 100644
--- a/src/curl_stream.c
+++ b/src/curl_stream.c
@@ -220,6 +220,7 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port)
 	curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 1);
 	curl_easy_setopt(handle, CURLOPT_CERTINFO, 1);
 	curl_easy_setopt(handle, CURLOPT_HTTPPROXYTUNNEL, 1);
+	curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
 
 	/* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); */
 
diff --git a/src/diff_driver.c b/src/diff_driver.c
index 9d13371..bc35189 100644
--- a/src/diff_driver.c
+++ b/src/diff_driver.c
@@ -97,8 +97,7 @@ static int diff_driver_add_patterns(
 	for (scan = regex_str; scan; scan = end) {
 		/* get pattern to fill in */
 		if ((pat = git_array_alloc(drv->fn_patterns)) == NULL) {
-			error = -1;
-			break;
+			return -1;
 		}
 
 		pat->flags = regex_flags;
@@ -117,10 +116,9 @@ static int diff_driver_add_patterns(
 			break;
 
 		if ((error = regcomp(&pat->re, buf.ptr, regex_flags)) != 0) {
-			/* if regex fails to compile, warn? fail? */
-			error = giterr_set_regex(&pat->re, error);
-			regfree(&pat->re);
-			break;
+			/*
+			 * TODO: issue a warning
+			 */
 		}
 	}
 
@@ -128,7 +126,8 @@ static int diff_driver_add_patterns(
 		(void)git_array_pop(drv->fn_patterns); /* release last item */
 	git_buf_free(&buf);
 
-	return error;
+	/* We want to ignore bad patterns, so return success regardless */
+	return 0;
 }
 
 static int diff_driver_xfuncname(const git_config_entry *entry, void *payload)
diff --git a/src/remote.c b/src/remote.c
index f31fc15..9f82aae 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -1325,11 +1325,13 @@ static int update_tips_for_spec(
 	for (; i < refs->length; ++i) {
 		head = git_vector_get(refs, i);
 		autotag = 0;
+		git_buf_clear(&refname);
 
 		/* Ignore malformed ref names (which also saves us from tag^{} */
 		if (!git_reference_is_valid_name(head->name))
 			continue;
 
+		/* If we have a tag, see if the auto-follow rules say to update it */
 		if (git_refspec_src_matches(&tagspec, head->name)) {
 			if (tagopt != GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
 
@@ -1339,10 +1341,11 @@ static int update_tips_for_spec(
 				git_buf_clear(&refname);
 				if (git_buf_puts(&refname, head->name) < 0)
 					goto on_error;
-			} else {
-				continue;
 			}
-		} else if (git_refspec_src_matches(spec, head->name)) {
+		}
+
+		/* If we didn't want to auto-follow the tag, check if the refspec matches */
+		if (!autotag && git_refspec_src_matches(spec, head->name)) {
 			if (spec->dst) {
 				if (git_refspec_transform(&refname, spec, head->name) < 0)
 					goto on_error;
@@ -1356,7 +1359,10 @@ static int update_tips_for_spec(
 
 				continue;
 			}
-		} else {
+		}
+
+		/* If we still don't have a refname, we don't want it */
+		if (git_buf_len(&refname) == 0) {
 			continue;
 		}
 
diff --git a/src/transports/http.c b/src/transports/http.c
index e3d90de..87f3ee8 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -36,6 +36,8 @@ static const char *post_verb = "POST";
 
 #define PARSE_ERROR_GENERIC	-1
 #define PARSE_ERROR_REPLAY	-2
+/** Look at the user field */
+#define PARSE_ERROR_EXT         -3
 
 #define CHUNK_SIZE	4096
 
@@ -78,6 +80,7 @@ typedef struct {
 	git_vector www_authenticate;
 	enum last_cb last_cb;
 	int parse_error;
+	int error;
 	unsigned parse_finished : 1;
 
 	/* Authentication */
@@ -351,7 +354,8 @@ static int on_headers_complete(http_parser *parser)
 				if (error == GIT_PASSTHROUGH) {
 					no_callback = 1;
 				} else if (error < 0) {
-					return PARSE_ERROR_GENERIC;
+					t->error = error;
+					return t->parse_error = PARSE_ERROR_EXT;
 				} else {
 					assert(t->cred);
 
@@ -712,6 +716,10 @@ replay:
 			goto replay;
 		}
 
+		if (t->parse_error == PARSE_ERROR_EXT) {
+			return t->error;
+		}
+
 		if (t->parse_error < 0)
 			return -1;
 
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index 0920f2e..1d46d4b 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -957,7 +957,7 @@ int git_smart__push(git_transport *transport, git_push *push, const git_remote_c
 
 	packbuilder_payload.pb = push->pb;
 
-	if (cbs && cbs->transfer_progress) {
+	if (cbs && cbs->push_transfer_progress) {
 		packbuilder_payload.cb = cbs->push_transfer_progress;
 		packbuilder_payload.cb_payload = cbs->payload;
 	}
diff --git a/tests/diff/drivers.c b/tests/diff/drivers.c
index e3a0014..42af38a 100644
--- a/tests/diff/drivers.c
+++ b/tests/diff/drivers.c
@@ -250,3 +250,29 @@ void test_diff_drivers__builtins(void)
 	git_buf_free(&expected);
 	git_vector_free(&files);
 }
+
+void test_diff_drivers__invalid_pattern(void)
+{
+	git_config *cfg;
+	git_index *idx;
+	git_diff *diff;
+	git_patch *patch;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+
+	g_repo = cl_git_sandbox_init("userdiff");
+	cl_git_mkfile("userdiff/.gitattributes", "*.storyboard diff=storyboard\n");
+
+	cl_git_pass(git_repository_config__weakptr(&cfg, g_repo));
+	cl_git_pass(git_config_set_string(cfg, "diff.storyboard.xfuncname", "<!--(.*?)-->"));
+
+	cl_git_mkfile("userdiff/dummy.storyboard", "");
+	cl_git_pass(git_repository_index__weakptr(&idx, g_repo));
+	cl_git_pass(git_index_add_bypath(idx, "dummy.storyboard"));
+	cl_git_mkfile("userdiff/dummy.storyboard", "some content\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+
+	git_patch_free(patch);
+	git_diff_free(diff);
+}