Commit 84dd3820d41046d35cb8b3bf65e67d0eb7e68f6c

Vicent Marti 2011-08-18T02:13:51

posix: Properly handle `snprintf` in all platforms

diff --git a/src/config.c b/src/config.c
index c48376f..7712507 100644
--- a/src/config.c
+++ b/src/config.c
@@ -179,7 +179,7 @@ int git_config_delete(git_config *cfg, const char *name)
 int git_config_set_long(git_config *cfg, const char *name, long int value)
 {
 	char str_value[32]; /* All numbers should fit in here */
-	snprintf(str_value, sizeof(str_value), "%ld", value);
+	p_snprintf(str_value, sizeof(str_value), "%ld", value);
 	return git_config_set_string(cfg, name, str_value);
 }
 
diff --git a/src/config_file.c b/src/config_file.c
index 837d42d..840817c 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -211,7 +211,7 @@ static int cvar_normalize_name(cvar_t *var, char **output)
 
 	/* If there aren't any spaces in the section, it's easy */
 	if (section_sp == NULL) {
-		ret = snprintf(name, len + 1, "%s.%s", var->section, var->name);
+		ret = p_snprintf(name, len + 1, "%s.%s", var->section, var->name);
 		if (ret < 0) {
 			free(name);
 			return git__throw(GIT_EOSERR, "Failed to normalize name. OS err: %s", strerror(errno));
@@ -672,12 +672,8 @@ static int parse_section_header_ext(const char *line, const char *base_name, cha
 		goto out;
 	}
 
-	ret = snprintf(*section_name, total_len, "%s %s", base_name, subsection);
-	if (ret >= total_len) {
-		/* If this fails, we've checked the length wrong */
-		error = git__throw(GIT_ERROR, "Failed to parse ext header. Wrong total length calculation");
-		goto out;
-	} else if (ret < 0) {
+	ret = p_snprintf(*section_name, total_len, "%s %s", base_name, subsection);
+	if (ret < 0) {
 		error = git__throw(GIT_EOSERR, "Failed to parse ext header. OS error: %s", strerror(errno));
 		goto out;
 	}
@@ -1140,7 +1136,7 @@ static int parse_multiline_variable(diskfile_backend *cfg, const char *first, ch
 		goto out;
 	}
 
-	ret = snprintf(buf, len, "%s %s", first, line);
+	ret = p_snprintf(buf, len, "%s %s", first, line);
 	if (ret < 0) {
 		error = git__throw(GIT_EOSERR, "Failed to parse multiline var. Failed to put together two lines. OS err: %s", strerror(errno));
 		free(buf);
diff --git a/src/odb.c b/src/odb.c
index fcba4fc..ec81cda 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -49,13 +49,11 @@ typedef struct
 static int format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type)
 {
 	const char *type_str = git_object_type2string(obj_type);
-	int len = snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len);
-
-	assert(len > 0);             /* otherwise snprintf() is broken  */
-	assert(((size_t) len) < n);  /* otherwise the caller is broken! */
+	int len = p_snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len);
 
 	if (len < 0 || ((size_t) len) >= n)
 		return git__throw(GIT_ERROR, "Cannot format object header. Length is out of bounds");
+
 	return len+1;
 }
 
diff --git a/src/pkt.c b/src/pkt.c
index 5370111..516800b 100644
--- a/src/pkt.c
+++ b/src/pkt.c
@@ -33,6 +33,7 @@
 #include "pkt.h"
 #include "util.h"
 #include "netops.h"
+#include "posix.h"
 
 #include <ctype.h>
 
@@ -285,7 +286,7 @@ static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps, 
 
 	git_oid_fmt(oid, &head->oid);
 	memset(cmd, 0x0, len + 1);
-	snprintf(cmd, len + 1, "%04xwant %s%c%s\n", len, oid, 0, capstr);
+	p_snprintf(cmd, len + 1, "%04xwant %s%c%s\n", len, oid, 0, capstr);
 	error = gitno_send(fd, cmd, len, 0);
 	free(cmd);
 	return error;
diff --git a/src/reflog.c b/src/reflog.c
index 7a056a0..d28e5cb 100644
--- a/src/reflog.c
+++ b/src/reflog.c
@@ -254,7 +254,7 @@ int git_reflog_write(git_reference *ref, const git_oid *oid_old,
 	if (oid_old)
 		git_oid_to_string(old, GIT_OID_HEXSZ+1, oid_old);
 	else
-		snprintf(old, GIT_OID_HEXSZ+1, "%0*d", GIT_OID_HEXSZ, 0);
+		p_snprintf(old, GIT_OID_HEXSZ+1, "%0*d", GIT_OID_HEXSZ, 0);
 
 	return reflog_write(log_path, old, new, committer, msg);
 }
diff --git a/src/remote.c b/src/remote.c
index 618e8f0..d54d8c7 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -100,7 +100,7 @@ int git_remote_get(git_remote **out, git_config *cfg, const char *name)
 		goto cleanup;
 	}
 
-	ret = snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "url");
+	ret = p_snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "url");
 	if (ret < 0) {
 		error = git__throw(GIT_EOSERR, "Failed to build config var name");
 		goto cleanup;
@@ -119,7 +119,7 @@ int git_remote_get(git_remote **out, git_config *cfg, const char *name)
 		goto cleanup;
 	}
 
-	ret = snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "fetch");
+	ret = p_snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "fetch");
 	if (ret < 0) {
 		error = git__throw(GIT_EOSERR, "Failed to build config var name");
 		goto cleanup;
@@ -131,7 +131,7 @@ int git_remote_get(git_remote **out, git_config *cfg, const char *name)
 		goto cleanup;
 	}
 
-	ret = snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "push");
+	ret = p_snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "push");
 	if (ret < 0) {
 		error = git__throw(GIT_EOSERR, "Failed to build config var name");
 		goto cleanup;
diff --git a/src/transport_local.c b/src/transport_local.c
index 6cb261b..3d72a1b 100644
--- a/src/transport_local.c
+++ b/src/transport_local.c
@@ -7,6 +7,7 @@
 #include "git2/tag.h"
 #include "refs.h"
 #include "transport.h"
+#include "posix.h"
 
 typedef struct {
 	git_transport parent;
@@ -93,7 +94,7 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec)
 	head = git__malloc(sizeof(git_remote_head));
 	peel_len = strlen(name) + STRLEN(peeled);
 	head->name = git__malloc(peel_len + 1);
-	ret = snprintf(head->name, peel_len + 1, "%s%s", name, peeled);
+	ret = p_snprintf(head->name, peel_len + 1, "%s%s", name, peeled);
 	if (ret >= peel_len + 1) {
 		error = git__throw(GIT_ERROR, "The string is magically to long");
 	}
diff --git a/src/unix/posix.h b/src/unix/posix.h
index 8eebbd4..f355844 100644
--- a/src/unix/posix.h
+++ b/src/unix/posix.h
@@ -12,5 +12,6 @@
 #define p_realpath(p, po) realpath(p, po)
 #define p_fnmatch(p, s, f) fnmatch(p, s, f)
 #define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a)
+#define p_snprintf(b, c, f, ...) snprintf(b, c, f, __VA_ARGS__)
 
 #endif
diff --git a/src/util.c b/src/util.c
index 57274b0..29bf755 100644
--- a/src/util.c
+++ b/src/util.c
@@ -118,19 +118,6 @@ Return:
 	return GIT_SUCCESS;
 }
 
-int git__fmt(char *buf, size_t buf_sz, const char *fmt, ...)
-{
-	va_list va;
-	int r;
-
-	va_start(va, fmt);
-	r = vsnprintf(buf, buf_sz, fmt, va);
-	va_end(va);
-	if (r < 0 || ((size_t) r) >= buf_sz)
-		return git__throw(GIT_ERROR, "Failed to format string");
-	return r;
-}
-
 void git__strntolower(char *str, int len)
 {
 	int i;
@@ -367,4 +354,4 @@ int git__strcmp_cb(const void *a, const void *b)
 	const char *strb = (const char *)b;
 
 	return strcmp(stra, strb);
-}
\ No newline at end of file
+}
diff --git a/src/util.h b/src/util.h
index f70bfe7..4a33420 100644
--- a/src/util.h
+++ b/src/util.h
@@ -66,8 +66,6 @@ GIT_INLINE(void *) git__realloc(void *ptr, size_t size)
 	return new_ptr;
 }
 
-extern int git__fmt(char *, size_t, const char *, ...)
-	GIT_FORMAT_PRINTF(3, 4);
 extern int git__prefixcmp(const char *str, const char *prefix);
 extern int git__suffixcmp(const char *str, const char *suffix);
 
diff --git a/src/win32/posix.c b/src/win32/posix.c
index 1ce3f05..0e9d3f0 100644
--- a/src/win32/posix.c
+++ b/src/win32/posix.c
@@ -218,3 +218,15 @@ int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
 	return vsnprintf(buffer, count, format, argptr);
 #endif
 }
+
+int p_snprintf(char *buffer, size_t count, const char *format, ...)
+{
+	va_list va;
+	int r;
+
+	va_start(va, format);
+	r = p_vsnprintf(buffer, count, format, va);
+	va_end(va);
+
+	return r;
+}
diff --git a/src/win32/posix.h b/src/win32/posix.h
index efac68e..536089e 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -24,5 +24,6 @@ extern int p_readlink(const char *link, char *target, size_t target_len);
 extern int p_hide_directory__w32(const char *path);
 extern char *p_realpath(const char *orig_path, char *buffer);
 extern int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr);
+extern int p_snprintf(char *buffer, size_t count, const char *format, ...) GIT_FORMAT_PRINTF(3, 4);
 
 #endif