From 45e40eb27a0fc80d82f36ec06bd40eb0c38e18df Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 6 Dec 2014 22:01:54 +0100 Subject: [PATCH] Correctly encode non utf8 node names --- cmd/restic/Makefile | 2 +- tree.go | 23 +++++++++++++++++++++++ tree_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/cmd/restic/Makefile b/cmd/restic/Makefile index b9484168e..6e39fff41 100644 --- a/cmd/restic/Makefile +++ b/cmd/restic/Makefile @@ -14,7 +14,7 @@ all: restic restic: $(wildcard *.go) $(wildcard ../../*.go) $(wildcard ../../*/*.go) go build $(TAGS) -ldflags "$(LDFLAGS)" -debug: TAGS=-tags debug_cmd +debug: TAGS=-tags "debug debug_cmd" debug: restic clean: diff --git a/tree.go b/tree.go index 1fe48cf97..ac27ab679 100644 --- a/tree.go +++ b/tree.go @@ -1,6 +1,7 @@ package restic import ( + "encoding/json" "errors" "fmt" "os" @@ -367,6 +368,28 @@ func (node Node) SameContent(olderNode *Node) bool { return true } +func (node Node) MarshalJSON() ([]byte, error) { + type nodeJSON Node + nj := nodeJSON(node) + name := strconv.Quote(node.Name) + nj.Name = name[1 : len(name)-1] + + return json.Marshal(nj) +} + +func (node *Node) UnmarshalJSON(data []byte) error { + type nodeJSON Node + var nj *nodeJSON = (*nodeJSON)(node) + + err := json.Unmarshal(data, nj) + if err != nil { + return err + } + + nj.Name, err = strconv.Unquote(`"` + nj.Name + `"`) + return err +} + func (b Blob) Free() { if b.ID != nil { b.ID.Free() diff --git a/tree_test.go b/tree_test.go index bd1ba191c..c0b8f7c7b 100644 --- a/tree_test.go +++ b/tree_test.go @@ -1,10 +1,13 @@ package restic_test import ( + "encoding/json" "io/ioutil" "os" "path/filepath" "testing" + + "github.com/restic/restic" ) var testFiles = []struct { @@ -50,3 +53,26 @@ func TestTree(t *testing.T) { } }() } + +var testNodes = []restic.Node{ + restic.Node{Name: "normal"}, + restic.Node{Name: "with backslashes \\zzz"}, + restic.Node{Name: "test utf-8 föbärß"}, + restic.Node{Name: "test invalid \x00\x01\x02\x03\x04"}, + restic.Node{Name: "test latin1 \x75\x6d\x6c\xe4\xfc\x74\xf6\x6e\xdf\x6e\x6c\x6c"}, +} + +func TestNodeMarshal(t *testing.T) { + for i, n := range testNodes { + data, err := json.Marshal(&n) + ok(t, err) + + var node restic.Node + err = json.Unmarshal(data, &node) + ok(t, err) + + if n.Name != node.Name { + t.Fatalf("Node %d: Names are not equal, want: %q got: %q", i, n.Name, node.Name) + } + } +}