From aa9d3360ba6f27bd985df78e9247d3e756141bee Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 11 Mar 2015 00:46:39 +0300 Subject: [PATCH] Canonical case-folding for Debian stanzas. #193 --- deb/format.go | 28 +++++++++++++++++++++++++++- deb/format_test.go | 12 ++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/deb/format.go b/deb/format.go index 5663a564..ccc6327d 100644 --- a/deb/format.go +++ b/deb/format.go @@ -5,6 +5,7 @@ import ( "errors" "io" "strings" + "unicode" ) // Stanza or paragraph of Debian control file @@ -157,6 +158,31 @@ func init() { multilineFields["MD5Sum"] = true } +func canonicalCase(field string) string { + upper := strings.ToUpper(field) + if upper == "SHA1" || upper == "SHA256" { + return upper + } + if upper == "MD5SUM" { + return "MD5Sum" + } + + startOfWord := true + + return strings.Map(func(r rune) rune { + if startOfWord { + startOfWord = false + return unicode.ToUpper(r) + } + + if r == '-' { + startOfWord = true + } + + return unicode.ToLower(r) + }, field) +} + // ControlFileReader implements reading of control files stanza by stanza type ControlFileReader struct { scanner *bufio.Scanner @@ -195,7 +221,7 @@ func (c *ControlFileReader) ReadStanza() (Stanza, error) { if len(parts) != 2 { return nil, ErrMalformedStanza } - lastField = parts[0] + lastField = canonicalCase(parts[0]) _, lastFieldMultiline = multilineFields[lastField] if lastFieldMultiline { stanza[lastField] = parts[1] diff --git a/deb/format_test.go b/deb/format_test.go index 41046def..d7f43acc 100644 --- a/deb/format_test.go +++ b/deb/format_test.go @@ -123,6 +123,18 @@ func (s *ControlFileSuite) TestReadWriteStanza(c *C) { c.Assert(strings.HasPrefix(str, "Package: "), Equals, true) } +func (s *ControlFileSuite) TestCanonicalCase(c *C) { + c.Check(canonicalCase("Package"), Equals, "Package") + c.Check(canonicalCase("package"), Equals, "Package") + c.Check(canonicalCase("pAckaGe"), Equals, "Package") + c.Check(canonicalCase("MD5Sum"), Equals, "MD5Sum") + c.Check(canonicalCase("SHA1"), Equals, "SHA1") + c.Check(canonicalCase("SHA256"), Equals, "SHA256") + c.Check(canonicalCase("Package-List"), Equals, "Package-List") + c.Check(canonicalCase("package-list"), Equals, "Package-List") + c.Check(canonicalCase("packaGe-lIst"), Equals, "Package-List") +} + func (s *ControlFileSuite) BenchmarkReadStanza(c *C) { for i := 0; i < c.N; i++ { reader := bytes.NewBufferString(controlFile)