lib/encoder: fix decoding a trailing character after an escaped quote
This commit is contained in:
1 parent
81d7b6f299
commit
f91c9d2d11
2 files changed
+59
-6
No files matched your search
+21
-6
@@ -682,6 +682,21 @@ func (mask MultiEncoder) Encode(in string) string {
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// quoteLen is the length in bytes of QuoteRune
|
||||
var quoteLen = utf8.RuneLen(QuoteRune)
|
||||
|
||||
// endsWithQuote returns true if in ends with a QuoteRune which quotes
|
||||
// the following character, rather than one which is part of an
|
||||
// escaped QuoteRune (QuoteRune QuoteRune).
|
||||
func endsWithQuote(in string) bool {
|
||||
n := 0
|
||||
for strings.HasSuffix(in, string(QuoteRune)) {
|
||||
in = in[:len(in)-quoteLen]
|
||||
n++
|
||||
}
|
||||
return n%2 == 1
|
||||
}
|
||||
|
||||
// Decode takes a name and undoes any substitutions made by Encode
|
||||
func (mask MultiEncoder) Decode(in string) string {
|
||||
if mask == EncodeRaw {
|
||||
@@ -727,22 +742,22 @@ func (mask MultiEncoder) Decode(in string) string {
|
||||
suffix := ""
|
||||
if r, l := utf8.DecodeLastRuneInString(in); mask.Has(EncodeRightSpace) && r == '␠' { // SYMBOL FOR SPACE
|
||||
in = in[:len(in)-l]
|
||||
if q, l2 := utf8.DecodeLastRuneInString(in); q == QuoteRune {
|
||||
suffix, in = "␠", in[:len(in)-l2]
|
||||
if endsWithQuote(in) {
|
||||
suffix, in = "␠", in[:len(in)-quoteLen]
|
||||
} else {
|
||||
suffix = " "
|
||||
}
|
||||
} else if mask.Has(EncodeRightPeriod) && r == '.' { // FULLWIDTH FULL STOP
|
||||
in = in[:len(in)-l]
|
||||
if q, l2 := utf8.DecodeLastRuneInString(in); q == QuoteRune {
|
||||
suffix, in = ".", in[:len(in)-l2]
|
||||
if endsWithQuote(in) {
|
||||
suffix, in = ".", in[:len(in)-quoteLen]
|
||||
} else {
|
||||
suffix = "."
|
||||
}
|
||||
} else if mask.Has(EncodeRightCrLfHtVt) && (r == '␀'+'\t' || r == '␀'+'\n' || r == '␀'+'\v' || r == '␀'+'\r') {
|
||||
in = in[:len(in)-l]
|
||||
if q, l2 := utf8.DecodeLastRuneInString(in); q == QuoteRune {
|
||||
suffix, in = string(r), in[:len(in)-l2]
|
||||
if endsWithQuote(in) {
|
||||
suffix, in = string(r), in[:len(in)-quoteLen]
|
||||
} else {
|
||||
suffix = string(r - '␀')
|
||||
}
|
||||
|
||||
@@ -255,6 +255,44 @@ func TestDecodeHalf(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeQuoteBeforeRightEdge(t *testing.T) {
|
||||
for i, tc := range []testCase{
|
||||
{
|
||||
mask: EncodeRightSpace,
|
||||
in: "a‛ ",
|
||||
out: "a‛‛␠",
|
||||
}, {
|
||||
mask: EncodeRightSpace,
|
||||
in: "‛‛ ",
|
||||
out: "‛‛‛‛␠",
|
||||
}, {
|
||||
mask: EncodeRightSpace,
|
||||
in: "a‛␠",
|
||||
out: "a‛‛‛␠",
|
||||
}, {
|
||||
mask: EncodeRightPeriod,
|
||||
in: "a‛.",
|
||||
out: "a‛‛.",
|
||||
}, {
|
||||
mask: EncodeRightCrLfHtVt,
|
||||
in: "a‛\t",
|
||||
out: "a‛‛␉",
|
||||
},
|
||||
} {
|
||||
e := tc.mask
|
||||
t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) {
|
||||
got := e.Encode(tc.in)
|
||||
if got != tc.out {
|
||||
t.Errorf("Encode(%q) want %q got %q", tc.in, tc.out, got)
|
||||
}
|
||||
got2 := e.Decode(got)
|
||||
if got2 != tc.in {
|
||||
t.Errorf("Decode(%q) want %q got %q", got, tc.in, got2)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const oneDrive = (Standard |
|
||||
EncodeWin |
|
||||
EncodeBackSlash |
|
||||
|
||||
Reference in new issue
Block a user