Skip to content

Commit cfbe82d

Browse files
authored
Merge pull request #69 from 99designs/percent-encode-slash
Percent-encode filenames with slash
2 parents db030e0 + 51593cf commit cfbe82d

File tree

4 files changed

+64
-13
lines changed

4 files changed

+64
-13
lines changed

file.go

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
jose "github.com/dvsekhvalnov/jose2go"
1313
homedir "github.com/mitchellh/go-homedir"
14+
"github.com/mtibben/percent"
1415
)
1516

1617
func init() {
@@ -22,6 +23,11 @@ func init() {
2223
})
2324
}
2425

26+
var filenameEscape = func(s string) string {
27+
return percent.Encode(s, "/")
28+
}
29+
var filenameUnescape = percent.Decode
30+
2531
type fileKeyring struct {
2632
dir string
2733
passwordFunc PromptFunc
@@ -73,12 +79,12 @@ func (k *fileKeyring) unlock() error {
7379
}
7480

7581
func (k *fileKeyring) Get(key string) (Item, error) {
76-
dir, err := k.resolveDir()
82+
filename, err := k.filename(key)
7783
if err != nil {
7884
return Item{}, err
7985
}
8086

81-
bytes, err := ioutil.ReadFile(filepath.Join(dir, key))
87+
bytes, err := ioutil.ReadFile(filename)
8288
if os.IsNotExist(err) {
8389
return Item{}, ErrKeyNotFound
8490
} else if err != nil {
@@ -101,12 +107,12 @@ func (k *fileKeyring) Get(key string) (Item, error) {
101107
}
102108

103109
func (k *fileKeyring) GetMetadata(key string) (Metadata, error) {
104-
dir, err := k.resolveDir()
110+
filename, err := k.filename(key)
105111
if err != nil {
106112
return Metadata{}, err
107113
}
108114

109-
stat, err := os.Stat(filepath.Join(dir, key))
115+
stat, err := os.Stat(filename)
110116
if os.IsNotExist(err) {
111117
return Metadata{}, ErrKeyNotFound
112118
} else if err != nil {
@@ -131,11 +137,6 @@ func (k *fileKeyring) Set(i Item) error {
131137
return err
132138
}
133139

134-
dir, err := k.resolveDir()
135-
if err != nil {
136-
return err
137-
}
138-
139140
if err = k.unlock(); err != nil {
140141
return err
141142
}
@@ -148,16 +149,29 @@ func (k *fileKeyring) Set(i Item) error {
148149
return err
149150
}
150151

151-
return ioutil.WriteFile(filepath.Join(dir, i.Key), []byte(token), 0600)
152+
filename, err := k.filename(i.Key)
153+
if err != nil {
154+
return err
155+
}
156+
return ioutil.WriteFile(filename, []byte(token), 0600)
152157
}
153158

154-
func (k *fileKeyring) Remove(key string) error {
159+
func (k *fileKeyring) filename(key string) (string, error) {
155160
dir, err := k.resolveDir()
161+
if err != nil {
162+
return "", err
163+
}
164+
165+
return filepath.Join(dir, filenameEscape(key)), nil
166+
}
167+
168+
func (k *fileKeyring) Remove(key string) error {
169+
filename, err := k.filename(key)
156170
if err != nil {
157171
return err
158172
}
159173

160-
return os.Remove(filepath.Join(dir, key))
174+
return os.Remove(filename)
161175
}
162176

163177
func (k *fileKeyring) Keys() ([]string, error) {
@@ -169,7 +183,7 @@ func (k *fileKeyring) Keys() ([]string, error) {
169183
var keys = []string{}
170184
files, _ := ioutil.ReadDir(dir)
171185
for _, f := range files {
172-
keys = append(keys, f.Name())
186+
keys = append(keys, filenameUnescape(f.Name()))
173187
}
174188

175189
return keys, nil

file_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,33 @@ func TestFileKeyringSetWhenEmpty(t *testing.T) {
2929
t.Fatalf("Key wasn't persisted: %q", foundItem.Key)
3030
}
3131
}
32+
33+
func TestFileKeyringGetWithSlashes(t *testing.T) {
34+
k := &fileKeyring{
35+
dir: os.TempDir(),
36+
passwordFunc: fixedStringPrompt("no more secrets"),
37+
}
38+
39+
item := Item{Key: "https://aws-sso-portal.awsapps.com/start", Data: []byte("https://aws-sso-portal.awsapps.com/start")}
40+
41+
if err := k.Set(item); err != nil {
42+
t.Fatal(err)
43+
}
44+
45+
if err := k.Remove(item.Key); err != nil {
46+
t.Fatal(err)
47+
}
48+
}
49+
50+
func TestFilenameWithBadChars(t *testing.T) {
51+
a := `abc/.././123`
52+
e := filenameEscape(a)
53+
if e != `abc%2F..%2F.%2F123` {
54+
t.Fatalf("Unexpected result from filenameEscape: %s", e)
55+
}
56+
57+
b := filenameUnescape(e)
58+
if b != a {
59+
t.Fatal("Unexpected filenameEscape")
60+
}
61+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d
1111
github.com/kr/pretty v0.1.0 // indirect
1212
github.com/mitchellh/go-homedir v1.1.0
13+
github.com/mtibben/percent v0.2.1
1314
github.com/stretchr/objx v0.2.0 // indirect
1415
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
1516
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=
2+
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=
13
github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
24
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
35
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
@@ -19,6 +21,10 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
1921
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
2022
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
2123
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
24+
github.com/mtibben/percent v0.2.0 h1:3A04NiaCmcLX6jkb4zCYIABXWJydnjhE+tzGlzNjdss=
25+
github.com/mtibben/percent v0.2.0/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=
26+
github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs=
27+
github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=
2228
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2329
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2430
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=

0 commit comments

Comments
 (0)