Skip to content

Commit feef6fc

Browse files
committed
Clean all volume paths
Signed-off-by: Mathieu Champlon <[email protected]>
1 parent 0d0f00f commit feef6fc

File tree

4 files changed

+53
-16
lines changed

4 files changed

+53
-16
lines changed

loader/loader.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ func createTransformHook(additionalTransformers ...Transformer) mapstructure.Dec
342342
reflect.TypeOf(types.UlimitsConfig{}): transformUlimits,
343343
reflect.TypeOf(types.UnitBytes(0)): transformSize,
344344
reflect.TypeOf([]types.ServicePortConfig{}): transformServicePort,
345-
reflect.TypeOf(types.ServiceSecretConfig{}): transformStringSourceMap,
346-
reflect.TypeOf(types.ServiceConfigObjConfig{}): transformStringSourceMap,
345+
reflect.TypeOf(types.ServiceSecretConfig{}): transformFileReferenceConfig,
346+
reflect.TypeOf(types.ServiceConfigObjConfig{}): transformFileReferenceConfig,
347347
reflect.TypeOf(types.StringOrNumberList{}): transformStringOrNumberList,
348348
reflect.TypeOf(map[string]*types.ServiceNetworkConfig{}): transformServiceNetworkMap,
349349
reflect.TypeOf(types.Mapping{}): transformMappingOrListFunc("=", false),
@@ -852,17 +852,27 @@ var transformServiceDeviceRequest TransformerFunc = func(data interface{}) (inte
852852
}
853853
}
854854

855-
var transformStringSourceMap TransformerFunc = func(data interface{}) (interface{}, error) {
855+
var transformFileReferenceConfig TransformerFunc = func(data interface{}) (interface{}, error) {
856856
switch value := data.(type) {
857857
case string:
858858
return map[string]interface{}{"source": value}, nil
859859
case map[string]interface{}:
860-
return groupXFieldsIntoExtensions(data.(map[string]interface{})), nil
860+
if target, ok := value["target"]; ok {
861+
value["target"] = cleanTarget(target.(string))
862+
}
863+
return groupXFieldsIntoExtensions(value), nil
861864
default:
862865
return data, errors.Errorf("invalid type %T for secret", value)
863866
}
864867
}
865868

869+
func cleanTarget(target string) string {
870+
if target == "" {
871+
return ""
872+
}
873+
return path.Clean(target)
874+
}
875+
866876
var transformBuildConfig TransformerFunc = func(data interface{}) (interface{}, error) {
867877
switch value := data.(type) {
868878
case string:
@@ -906,9 +916,15 @@ var transformExtendsConfig TransformerFunc = func(data interface{}) (interface{}
906916
var transformServiceVolumeConfig TransformerFunc = func(data interface{}) (interface{}, error) {
907917
switch value := data.(type) {
908918
case string:
909-
return ParseVolume(value)
919+
volume, err := ParseVolume(value)
920+
volume.Target = cleanTarget(volume.Target)
921+
return volume, err
910922
case map[string]interface{}:
911-
return groupXFieldsIntoExtensions(data.(map[string]interface{})), nil
923+
data := groupXFieldsIntoExtensions(data.(map[string]interface{}))
924+
if target, ok := data["target"]; ok {
925+
data["target"] = cleanTarget(target.(string))
926+
}
927+
return data, nil
912928
default:
913929
return data, errors.Errorf("invalid type %T for service volume", value)
914930
}

loader/loader_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1812,7 +1812,7 @@ services:
18121812
assert.NilError(t, err)
18131813
}
18141814

1815-
func TestLoadService(t *testing.T) {
1815+
func TestLoadServiceWithEnvFile(t *testing.T) {
18161816
file, err := os.CreateTemp("", "test-compose-go")
18171817
assert.NilError(t, err)
18181818
defer os.Remove(file.Name())
@@ -1830,3 +1830,33 @@ func TestLoadService(t *testing.T) {
18301830
assert.NilError(t, err)
18311831
assert.Equal(t, "YES", *s.Environment["HALLO"])
18321832
}
1833+
1834+
func TestLoadServiceWithVolumes(t *testing.T) {
1835+
m := map[string]interface{}{
1836+
"volumes": []interface{}{
1837+
"source:/path 1/",
1838+
map[string]interface{}{
1839+
"target": "/path 2/",
1840+
},
1841+
},
1842+
"configs": []interface{}{
1843+
map[string]interface{}{
1844+
"target": "/path 3/",
1845+
},
1846+
},
1847+
"secrets": []interface{}{
1848+
map[string]interface{}{
1849+
"target": "/path 4/",
1850+
},
1851+
},
1852+
}
1853+
s, err := LoadService("Test Name", m, ".", nil, true)
1854+
assert.NilError(t, err)
1855+
assert.Equal(t, len(s.Volumes), 2)
1856+
assert.Equal(t, "/path 1", s.Volumes[0].Target)
1857+
assert.Equal(t, "/path 2", s.Volumes[1].Target)
1858+
assert.Equal(t, len(s.Configs), 1)
1859+
assert.Equal(t, "/path 3", s.Configs[0].Target)
1860+
assert.Equal(t, len(s.Secrets), 1)
1861+
assert.Equal(t, "/path 4", s.Secrets[0].Target)
1862+
}

loader/volume.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package loader
1818

1919
import (
20-
"path"
2120
"strings"
2221
"unicode"
2322
"unicode/utf8"
@@ -57,7 +56,6 @@ func ParseVolume(spec string) (types.ServiceVolumeConfig, error) {
5756
}
5857
}
5958

60-
volume.Target = path.Clean(volume.Target)
6159
populateType(&volume)
6260
return volume, nil
6361
}

loader/volume_test.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@ func TestParseVolumeAnonymousVolume(t *testing.T) {
3434
}
3535
}
3636

37-
func TestParseVolumeCleanTarget(t *testing.T) {
38-
volume, err := ParseVolume("/path/")
39-
expected := types.ServiceVolumeConfig{Type: "volume", Target: "/path", Volume: &types.ServiceVolumeVolume{}}
40-
assert.NilError(t, err)
41-
assert.Check(t, is.DeepEqual(expected, volume))
42-
}
43-
4437
func TestParseVolumeAnonymousVolumeWindows(t *testing.T) {
4538
for _, path := range []string{"C:\\path", "Z:\\path\\foo"} {
4639
volume, err := ParseVolume(path)

0 commit comments

Comments
 (0)