From 58e0a0f357b27c2e47d0399207e6ca64c416d1e7 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 10 Nov 2020 18:39:57 +0200 Subject: [PATCH 1/6] Add ReferenceNormalizeName --- reference.go | 35 +++++++++++++++++++++++++++++++++++ reference_test.go | 23 +++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/reference.go b/reference.go index b5f5e47..c44d2d6 100644 --- a/reference.go +++ b/reference.go @@ -488,3 +488,38 @@ func ReferenceIsValidName(name string) bool { } return false } + +type ReferenceFormat uint + +const ( + ReferenceFormatNormal ReferenceFormat = C.GIT_REFERENCE_FORMAT_NORMAL + ReferenceFormatAllowOnelevel ReferenceFormat = C.GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL + ReferenceFormatRefspecPattern ReferenceFormat = C.GIT_REFERENCE_FORMAT_REFSPEC_PATTERN + ReferenceFormatRefspecShorthand ReferenceFormat = C.GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND +) + +// ReferenceNormalizeName normalizes the reference name and checks validity. +// +// This will normalize the reference name by removing any leading slash '/' +// characters and collapsing runs of adjacent slashes between name components +// into a single slash. +// +// Once normalized, if the reference name is valid, it will be returned in the +// user allocated buffer. +// +// See git_reference_symbolic_create() for rules about valid names. +func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + bufSize := C.ulong(1024) + buf := (*C.char)(C.malloc(bufSize)) + defer C.free(unsafe.Pointer(buf)) + + ecode := C.git_reference_normalize_name(buf, bufSize, cname, C.uint(flags)) + if ecode < 0 { + return "", MakeGitError(ecode) + } + + return C.GoString(buf), nil +} diff --git a/reference_test.go b/reference_test.go index b6721e1..691d17d 100644 --- a/reference_test.go +++ b/reference_test.go @@ -224,6 +224,29 @@ func TestReferenceIsValidName(t *testing.T) { } } +func TestReferenceNormalizeName(t *testing.T) { + t.Parallel() + + ref, err := ReferenceNormalizeName("refs/heads//master", ReferenceFormatNormal) + checkFatal(t, err) + + if ref != "refs/heads/master" { + t.Errorf("refs/heads//master should be normalized correctly") + } + + ref, err = ReferenceNormalizeName("master", ReferenceFormatAllowOnelevel|ReferenceFormatRefspecShorthand) + checkFatal(t, err) + + if ref != "master" { + t.Errorf("master should be normalized correctly") + } + + ref, err = ReferenceNormalizeName("foo^", ReferenceFormatNormal) + if !IsErrorCode(err, ErrInvalidSpec) { + t.Errorf("foo^ should be invalid") + } +} + func compareStringList(t *testing.T, expected, actual []string) { for i, v := range expected { if actual[i] != v { -- 2.45.2 From 0476e7d58f5de6597a6b24805e3dc5ab7e6162e1 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 10 Nov 2020 18:51:52 +0200 Subject: [PATCH 2/6] Add LockOSThread --- reference.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reference.go b/reference.go index c44d2d6..cf31c32 100644 --- a/reference.go +++ b/reference.go @@ -516,6 +516,9 @@ func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) buf := (*C.char)(C.malloc(bufSize)) defer C.free(unsafe.Pointer(buf)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ecode := C.git_reference_normalize_name(buf, bufSize, cname, C.uint(flags)) if ecode < 0 { return "", MakeGitError(ecode) -- 2.45.2 From c58fb46e564a7c4b6af4ce8243f97481605f17ea Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 10 Nov 2020 19:11:44 +0200 Subject: [PATCH 3/6] Fix for Go 1.9 that didn't treat typedefs of the same type as the same type --- reference.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference.go b/reference.go index cf31c32..672945f 100644 --- a/reference.go +++ b/reference.go @@ -512,7 +512,7 @@ func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - bufSize := C.ulong(1024) + bufSize := C.size_t(1024) buf := (*C.char)(C.malloc(bufSize)) defer C.free(unsafe.Pointer(buf)) -- 2.45.2 From e69f00381364628e1c89db141d3eb8dfc27ec99a Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 13 Nov 2020 16:52:55 +0200 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: lhchavez --- reference.go | 3 --- reference_test.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/reference.go b/reference.go index 672945f..701fb07 100644 --- a/reference.go +++ b/reference.go @@ -504,9 +504,6 @@ const ( // characters and collapsing runs of adjacent slashes between name components // into a single slash. // -// Once normalized, if the reference name is valid, it will be returned in the -// user allocated buffer. -// // See git_reference_symbolic_create() for rules about valid names. func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) { cname := C.CString(name) diff --git a/reference_test.go b/reference_test.go index 691d17d..0b02f55 100644 --- a/reference_test.go +++ b/reference_test.go @@ -231,7 +231,7 @@ func TestReferenceNormalizeName(t *testing.T) { checkFatal(t, err) if ref != "refs/heads/master" { - t.Errorf("refs/heads//master should be normalized correctly") + t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "refs/heads//master", ref, want) } ref, err = ReferenceNormalizeName("master", ReferenceFormatAllowOnelevel|ReferenceFormatRefspecShorthand) -- 2.45.2 From af9ac641c17b11c99733eb34c8791c77f05b1880 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 13 Nov 2020 16:56:25 +0200 Subject: [PATCH 5/6] Code review fixes --- reference.go | 7 ++++++- reference_test.go | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/reference.go b/reference.go index 701fb07..c86f97e 100644 --- a/reference.go +++ b/reference.go @@ -489,6 +489,11 @@ func ReferenceIsValidName(name string) bool { return false } +const ( + // This should match GIT_REFNAME_MAX in src/refs.h + refnameMaxLength = 1024 +) + type ReferenceFormat uint const ( @@ -509,7 +514,7 @@ func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - bufSize := C.size_t(1024) + bufSize := C.size_t(refnameMaxLength) buf := (*C.char)(C.malloc(bufSize)) defer C.free(unsafe.Pointer(buf)) diff --git a/reference_test.go b/reference_test.go index 0b02f55..e42db41 100644 --- a/reference_test.go +++ b/reference_test.go @@ -231,14 +231,14 @@ func TestReferenceNormalizeName(t *testing.T) { checkFatal(t, err) if ref != "refs/heads/master" { - t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "refs/heads//master", ref, want) + t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "refs/heads//master", ref, "refs/heads/master") } ref, err = ReferenceNormalizeName("master", ReferenceFormatAllowOnelevel|ReferenceFormatRefspecShorthand) checkFatal(t, err) if ref != "master" { - t.Errorf("master should be normalized correctly") + t.Errorf("ReferenceNormalizeName(%q) = %q; want %q", "master", ref, "master") } ref, err = ReferenceNormalizeName("foo^", ReferenceFormatNormal) -- 2.45.2 From 201889963f179e84890d6e2bebd5103e478b7e57 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 13 Nov 2020 17:46:43 +0200 Subject: [PATCH 6/6] Fix review comment --- reference.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/reference.go b/reference.go index c86f97e..7b5e3c2 100644 --- a/reference.go +++ b/reference.go @@ -491,7 +491,7 @@ func ReferenceIsValidName(name string) bool { const ( // This should match GIT_REFNAME_MAX in src/refs.h - refnameMaxLength = 1024 + _refnameMaxLength = C.size_t(1024) ) type ReferenceFormat uint @@ -514,14 +514,13 @@ func ReferenceNormalizeName(name string, flags ReferenceFormat) (string, error) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - bufSize := C.size_t(refnameMaxLength) - buf := (*C.char)(C.malloc(bufSize)) + buf := (*C.char)(C.malloc(_refnameMaxLength)) defer C.free(unsafe.Pointer(buf)) runtime.LockOSThread() defer runtime.UnlockOSThread() - ecode := C.git_reference_normalize_name(buf, bufSize, cname, C.uint(flags)) + ecode := C.git_reference_normalize_name(buf, _refnameMaxLength, cname, C.uint(flags)) if ecode < 0 { return "", MakeGitError(ecode) } -- 2.45.2