Commit ff5873ad950ca2de9f4680e01ee7c8cb258f9874

Vicent Marti 2011-02-02T04:01:14

Fix EOL issues in ref parsing under Win32 Reference files can be loaded using Win32 line endings, too. Signed-off-by: Vicent Marti <tanoku@gmail.com>

diff --git a/src/refs.c b/src/refs.c
index 6bee6fa..40c47f2 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -117,8 +117,12 @@ static int parse_sym_ref(git_reference *ref, gitfo_buf *file_content)
 
 	/* remove newline at the end of file */
 	eol = strchr(ref->target.ref, '\n');
-	if (eol != NULL)
-		*eol = '\0';
+	if (eol == NULL)
+		return GIT_EREFCORRUPTED;
+
+	*eol = '\0';
+	if (eol[-1] == '\r')
+		eol[-1] = '\0';
 
 	ref->type = GIT_REF_SYMBOLIC;
 
@@ -132,13 +136,17 @@ static int parse_oid_ref(git_reference *ref, gitfo_buf *file_content)
 	buffer = (char *)file_content->data;
 
 	/* File format: 40 chars (OID) + newline */
-	if (file_content->len != GIT_OID_HEXSZ + 1)
+	if (file_content->len < GIT_OID_HEXSZ + 1)
 		return GIT_EREFCORRUPTED;
 
 	if (git_oid_mkstr(&ref->target.oid, buffer) < GIT_SUCCESS)
 		return GIT_EREFCORRUPTED;
 
-	if (buffer[GIT_OID_HEXSZ] != '\n')
+	buffer = buffer + GIT_OID_HEXSZ;
+	if (*buffer == '\r')
+		buffer++;
+
+	if (*buffer != '\n')
 		return GIT_EREFCORRUPTED;
 
 	ref->type = GIT_REF_OID;
@@ -201,6 +209,10 @@ static int lookup_loose_ref(
 	if (error < GIT_SUCCESS)
 		goto cleanup;
 
+	error = git_hashtable_insert(repo->references.cache, ref->name, ref);
+	if (error < GIT_SUCCESS)
+		goto cleanup;
+
 	*ref_out = ref;
 	return GIT_SUCCESS;
 
@@ -252,7 +264,14 @@ static int parse_packed_line_peel(
 	if (git_oid_mkstr(&oid, buffer) < GIT_SUCCESS)
 		return GIT_EPACKEDREFSCORRUPTED;
 
-	*buffer_out = buffer + GIT_OID_HEXSZ + 1;
+	buffer = buffer + GIT_OID_HEXSZ;
+	if (*buffer == '\r')
+		buffer++;
+
+	if (*buffer != '\n')
+		return GIT_EPACKEDREFSCORRUPTED;
+
+	*buffer_out = buffer + 1;
 
 	/* 
 	 * TODO: do we need the packed line?
@@ -299,6 +318,10 @@ static int parse_packed_line(
 		goto cleanup;
 	}
 
+	/* windows line feeds */
+	if (refname_end[-1] == '\r')
+		refname_end--;
+
 	refname_len = refname_end - refname_begin;
 
 	ref->name = git__malloc(refname_len + 1);