fix(config): avoid clobbering user-provided key value pairs
let me know if this looks off @whyrusleeping @jbenet
Brian Tiger Chow committed
Jan 12, 2015 at 18:31 UTC
e84fc5df22e3225459590fdaa4ab7844cedc2a06
2 files changed
+29
-3
repo/config/config.go
+12
@@ -219,3 +219,15 @@ func FromMap(v map[string]interface{}) (*Config, error) {
219
}
220
return &conf, nil
221
}
222
+
223
+func ToMap(conf *Config) (map[string]interface{}, error) {
224
+ var buf bytes.Buffer
225
+ if err := json.NewEncoder(&buf).Encode(conf); err != nil {
226
+ return nil, err
227
+ }
228
+ var m map[string]interface{}
229
+ if err := json.NewDecoder(&buf).Decode(&m); err != nil {
230
+ return nil, fmt.Errorf("Failure to decode config: %s", err)
231
+ }
232
+ return m, nil
233
+}
repo/fsrepo/fsrepo.go
+17
-3
@@ -99,7 +99,7 @@ func (r *FSRepo) Config() *config.Config {
99
}
100
101
// SetConfig updates the FSRepo's config.
102
-func (r *FSRepo) SetConfig(conf *config.Config) error {
102
+func (r *FSRepo) SetConfig(updated *config.Config) error {
103
if r.state != opened {
104
panic(fmt.Sprintln("repo is", r.state))
105
}
@@ -107,10 +107,24 @@ func (r *FSRepo) SetConfig(conf *config.Config) error {
107
if err != nil {
108
return err
109
}
110
- if err := writeConfigFile(configFilename, conf); err != nil {
110
+ // to avoid clobbering user-provided keys, must read the config from disk
111
+ // as a map, write the updated struct values to the map and write the map
112
+ // to disk.
113
+ var mapconf map[string]interface{}
114
+ if err := readConfigFile(configFilename, &mapconf); err != nil {
115
+ return err
116
+ }
117
+ m, err := config.ToMap(updated)
118
+ if err != nil {
119
+ return err
120
+ }
121
+ for k, v := range m {
122
+ mapconf[k] = v
123
+ }
124
+ if err := writeConfigFile(configFilename, mapconf); err != nil {
125
return err
126
}
113
- *r.config = *conf // copy so caller cannot modify the private config
127
+ *r.config = *updated // copy so caller cannot modify this private config
128
return nil
129
}
130