Skip to content

Commit

Permalink
ui/termstatus: Quote funny filenames
Browse files Browse the repository at this point in the history
Fixes #2260, #4191.
  • Loading branch information
greatroar committed Apr 14, 2023
1 parent 49fa8fe commit 9412f37
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 8 deletions.
13 changes: 13 additions & 0 deletions changelog/unreleased/issue-2260
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Bugfix: Exotic filenames no longer break restic backup's status output

Restic backup shows the names of files that it is working on. In previous
versions of restic, those names were printed without first sanitizing them,
so that filenames containing newlines or terminal control characters could
mess up restic backup's output or even change the state of a terminal.

Filenames are now checked and quoted if they contain non-printable or
non-Unicode characters.

https://github.com/restic/restic/issues/2260
https://github.com/restic/restic/issues/4191
https://github.com/restic/restic/pull/4192
2 changes: 2 additions & 0 deletions internal/ui/backup/text.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ func (b *TextProgress) Error(item string, err error) error {
// CompleteItem is the status callback function for the archiver when a
// file/dir has been saved successfully.
func (b *TextProgress) CompleteItem(messageType, item string, previous, current *restic.Node, s archiver.ItemStats, d time.Duration) {
item = termstatus.Quote(item)

switch messageType {
case "dir new":
b.VV("new %v, saved in %.3fs (%v added, %v stored, %v metadata)",
Expand Down
29 changes: 22 additions & 7 deletions internal/ui/termstatus/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"os"
"strconv"
"strings"
"unicode"

Expand Down Expand Up @@ -325,6 +326,7 @@ func wideRune(r rune) bool {
}

// SetStatus updates the status lines.
// The lines should not contain newlines; this method adds them.
func (t *Terminal) SetStatus(lines []string) {
if len(lines) == 0 {
return
Expand All @@ -341,21 +343,34 @@ func (t *Terminal) SetStatus(lines []string) {
}
}

// make sure that all lines have a line break and are not too long
// Sanitize lines and truncate them if they're too long.
for i, line := range lines {
line = strings.TrimRight(line, "\n")
line = Quote(line)
if width > 0 {
line = Truncate(line, width-2)
}
lines[i] = line + "\n"
if i < len(lines)-1 { // Last line gets no line break.
lines[i] = line + "\n"
}
}

// make sure the last line does not have a line break
last := len(lines) - 1
lines[last] = strings.TrimRight(lines[last], "\n")

select {
case t.status <- status{lines: lines}:
case <-t.closed:
}
}

// Quote lines with funny characters in them, meaning control chars, newlines,
// tabs, anything else non-printable and invalid UTF-8.
//
// This is intended to produce a string that does not mess up the terminal
// rather than produce an unambiguous quoted string.
func Quote(line string) string {
for _, r := range line {
// The replacement character usually means the input is not UTF-8.
if r == unicode.ReplacementChar || !unicode.IsPrint(r) {
return strconv.Quote(line)
}
}
return line
}
32 changes: 31 additions & 1 deletion internal/ui/termstatus/status_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
package termstatus

import "testing"
import (
"strconv"
"testing"

rtest "github.com/restic/restic/internal/test"
)

func TestQuote(t *testing.T) {
for _, c := range []struct {
in string
needQuote bool
}{
{"foo.bar/baz", false},
{"föó_bàŕ-bãẑ", false},
{" foo ", false},
{"foo bar", false},
{"foo\nbar", true},
{"foo\rbar", true},
{"foo\abar", true},
{"\xff", true},
{`c:\foo\bar`, false},
// Issue #2260: terminal control characters.
{"\x1bm_red_is_beautiful", true},
} {
if c.needQuote {
rtest.Equals(t, strconv.Quote(c.in), Quote(c.in))
} else {
rtest.Equals(t, c.in, Quote(c.in))
}
}
}

func TestTruncate(t *testing.T) {
var tests = []struct {
Expand Down

0 comments on commit 9412f37

Please sign in to comment.