aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format
diff options
context:
space:
mode:
authorAdrian Pronk <private>2021-07-25 17:58:36 +1200
committerAdrian Pronk <private>2021-07-25 17:58:36 +1200
commita55116466586f5396b34f5296abdd7c5e68b98b8 (patch)
tree20585ee095d05eef9e8f5ee7b1f8d7ec8d2c888b /plumbing/format
parent437ae96746723ceac4cf6bc5bb730b4f848b79ad (diff)
downloadgo-git-a55116466586f5396b34f5296abdd7c5e68b98b8.tar.gz
plumbing: config, support correct escaping as per git-config rules
Diffstat (limited to 'plumbing/format')
-rw-r--r--plumbing/format/config/encoder.go17
-rw-r--r--plumbing/format/config/fixtures_test.go21
2 files changed, 25 insertions, 13 deletions
diff --git a/plumbing/format/config/encoder.go b/plumbing/format/config/encoder.go
index 62921e0..de069ae 100644
--- a/plumbing/format/config/encoder.go
+++ b/plumbing/format/config/encoder.go
@@ -11,6 +11,10 @@ type Encoder struct {
w io.Writer
}
+var (
+ subsectionReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`)
+ valueReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`, "\n", `\n`, "\t", `\t`, "\b", `\b`)
+)
// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{w}
@@ -48,8 +52,7 @@ func (e *Encoder) encodeSection(s *Section) error {
}
func (e *Encoder) encodeSubsection(sectionName string, s *Subsection) error {
- //TODO: escape
- if err := e.printf("[%s \"%s\"]\n", sectionName, s.Name); err != nil {
+ if err := e.printf("[%s \"%s\"]\n", sectionName, subsectionReplacer.Replace(s.Name)); err != nil {
return err
}
@@ -58,12 +61,14 @@ func (e *Encoder) encodeSubsection(sectionName string, s *Subsection) error {
func (e *Encoder) encodeOptions(opts Options) error {
for _, o := range opts {
- pattern := "\t%s = %s\n"
- if strings.ContainsAny(o.Value, `"#\`) || strings.HasPrefix(o.Value, " ") || strings.HasSuffix(o.Value, " ") {
- pattern = "\t%s = %q\n"
+ var value string
+ if strings.ContainsAny(o.Value, "#;\"\t\n\\") || strings.HasPrefix(o.Value, " ") || strings.HasSuffix(o.Value, " ") {
+ value = `"`+valueReplacer.Replace(o.Value)+`"`
+ } else {
+ value = o.Value
}
- if err := e.printf(pattern, o.Key, o.Value); err != nil {
+ if err := e.printf("\t%s = %s\n", o.Key, value); err != nil {
return err
}
}
diff --git a/plumbing/format/config/fixtures_test.go b/plumbing/format/config/fixtures_test.go
index 3255213..899ddf7 100644
--- a/plumbing/format/config/fixtures_test.go
+++ b/plumbing/format/config/fixtures_test.go
@@ -48,17 +48,24 @@ var fixtures = []*Fixture{
option1 = "has # hash"
option2 = "has \" quote"
option3 = "has \\ backslash"
- option4 = " has leading spaces"
- option5 = "has trailing spaces "
- option6 = has no special characters
-`,
+ option4 = "has ; semicolon"
+ option5 = "has \n line-feed"
+ option6 = "has \t tab"
+ option7 = " has leading spaces"
+ option8 = "has trailing spaces "
+ option9 = has no special characters
+`+"\toption10 = has unusual \x01\x7f\xc8\x80 characters\n",
Config: New().
AddOption("section", "", "option1", `has # hash`).
AddOption("section", "", "option2", `has " quote`).
AddOption("section", "", "option3", `has \ backslash`).
- AddOption("section", "", "option4", ` has leading spaces`).
- AddOption("section", "", "option5", `has trailing spaces `).
- AddOption("section", "", "option6", `has no special characters`),
+ AddOption("section", "", "option4", `has ; semicolon`).
+ AddOption("section", "", "option5", "has \n line-feed").
+ AddOption("section", "", "option6", "has \t tab").
+ AddOption("section", "", "option7", ` has leading spaces`).
+ AddOption("section", "", "option8", `has trailing spaces `).
+ AddOption("section", "", "option9", `has no special characters`).
+ AddOption("section", "", "option10", "has unusual \x01\x7f\u0200 characters"),
},
{
Raw: `