## Description Encode all paths given to kopia with base64URL to ensure no special characters that kopia can't handle end up in there. The encoded paths are not stored in backup details nor are they ever surfaced to the user. This also works around the previous limitation where Corso was unable to properly backup or restore exchange email layouts that had folders containing `/` characters ## Type of change <!--- Please check the type of change your PR introduces: ---> - [x] 🌻 Feature - [x] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🐹 Trivial/Minor ## Issue(s) * closes #865 ## Test Plan <!-- How will this be tested prior to merging.--> - [ ] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
package kopia
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
type PathEncoderSuite struct {
|
|
suite.Suite
|
|
}
|
|
|
|
func TestPathEncoderSuite(t *testing.T) {
|
|
suite.Run(t, new(PathEncoderSuite))
|
|
}
|
|
|
|
func (suite *PathEncoderSuite) TestEncodeDecode() {
|
|
t := suite.T()
|
|
elements := []string{"these", "are", "some", "path", "elements"}
|
|
|
|
encoded := encodeElements(elements...)
|
|
|
|
decoded := make([]string, 0, len(elements))
|
|
|
|
for _, e := range encoded {
|
|
dec, err := decodeElement(e)
|
|
require.NoError(t, err)
|
|
|
|
decoded = append(decoded, dec)
|
|
}
|
|
|
|
assert.Equal(t, elements, decoded)
|
|
}
|
|
|
|
func (suite *PathEncoderSuite) TestEncodeAsPathDecode() {
|
|
table := []struct {
|
|
name string
|
|
elements []string
|
|
expected []string
|
|
}{
|
|
{
|
|
name: "MultipleElements",
|
|
elements: []string{"these", "are", "some", "path", "elements"},
|
|
expected: []string{"these", "are", "some", "path", "elements"},
|
|
},
|
|
{
|
|
name: "SingleElement",
|
|
elements: []string{"elements"},
|
|
expected: []string{"elements"},
|
|
},
|
|
{
|
|
name: "EmptyPath",
|
|
elements: []string{""},
|
|
expected: []string{""},
|
|
},
|
|
{
|
|
name: "NilPath",
|
|
elements: nil,
|
|
// Gets "" back because individual elements are decoded and "" is the 0
|
|
// value for the decoder.
|
|
expected: []string{""},
|
|
},
|
|
}
|
|
|
|
for _, test := range table {
|
|
suite.T().Run(test.name, func(t *testing.T) {
|
|
encoded := encodeAsPath(test.elements...)
|
|
|
|
// Sanity check, first and last character should not be '/'.
|
|
assert.Equal(t, strings.Trim(encoded, "/"), encoded)
|
|
|
|
decoded := make([]string, 0, len(test.elements))
|
|
|
|
for _, e := range strings.Split(encoded, "/") {
|
|
dec, err := decodeElement(e)
|
|
require.NoError(t, err)
|
|
|
|
decoded = append(decoded, dec)
|
|
}
|
|
|
|
assert.Equal(t, test.expected, decoded)
|
|
})
|
|
}
|
|
}
|
|
|
|
func FuzzEncodeDecodeSingleString(f *testing.F) {
|
|
f.Fuzz(func(t *testing.T, in string) {
|
|
encoded := encodeElements(in)
|
|
assert.Len(t, encoded, 1)
|
|
assert.False(t, strings.ContainsRune(encoded[0], '/'))
|
|
|
|
decoded, err := decodeElement(encoded[0])
|
|
require.NoError(t, err)
|
|
assert.Equal(t, in, decoded)
|
|
})
|
|
}
|