unicode/norm: correct use of ErrShortDst
In some cases the ErrShortDst error was
eroneously overriden by ErrShortSrc.
Fixes golang/go#24170.
Change-Id: I07dd160de045474e8e38506b6793a1da0df6283d
Reviewed-on: https://go-review.googlesource.com/c/145558
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ross Light <light@google.com>
diff --git a/unicode/norm/transform.go b/unicode/norm/transform.go
index 9f47efb..a1d366a 100644
--- a/unicode/norm/transform.go
+++ b/unicode/norm/transform.go
@@ -18,7 +18,6 @@
// Users should either catch ErrShortDst and allow dst to grow or have dst be at
// least of size MaxTransformChunkSize to be guaranteed of progress.
func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
- n := 0
// Cap the maximum number of src bytes to check.
b := src
eof := atEOF
@@ -27,13 +26,14 @@
eof = false
b = b[:ns]
}
- i, ok := formTable[f].quickSpan(inputBytes(b), n, len(b), eof)
- n += copy(dst[n:], b[n:i])
+ i, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), eof)
+ n := copy(dst, b[:i])
if !ok {
nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF)
return nDst + n, nSrc + n, err
}
- if n < len(src) && !atEOF {
+
+ if err == nil && n < len(src) && !atEOF {
err = transform.ErrShortSrc
}
return n, n, err
@@ -79,7 +79,7 @@
nSrc += n
nDst += n
if ok {
- if n < rb.nsrc && !atEOF {
+ if err == nil && n < rb.nsrc && !atEOF {
err = transform.ErrShortSrc
}
return nDst, nSrc, err
diff --git a/unicode/norm/transform_test.go b/unicode/norm/transform_test.go
index d596ff3..2690fc3 100644
--- a/unicode/norm/transform_test.go
+++ b/unicode/norm/transform_test.go
@@ -47,6 +47,13 @@
{NFD, "a\u0300", "", false, 4, transform.ErrShortSrc},
{NFC, "ö", "", false, 3, transform.ErrShortSrc},
+ {NFD, "abc", "", false, 1, transform.ErrShortDst},
+ {NFC, "abc", "", false, 1, transform.ErrShortDst},
+ {NFC, "abc", "a", false, 2, transform.ErrShortDst},
+ {NFD, "éfff", "", false, 2, transform.ErrShortDst},
+ {NFC, "e\u0301fffff", "\u00e9fff", false, 6, transform.ErrShortDst},
+ {NFD, "ééééé", "e\u0301e\u0301e\u0301", false, 15, transform.ErrShortDst},
+
{NFC, "a\u0300", "", true, 1, transform.ErrShortDst},
// Theoretically could fit, but won't due to simplified checks.
{NFC, "a\u0300", "", true, 2, transform.ErrShortDst},
@@ -62,14 +69,16 @@
}
b := make([]byte, 100)
for i, tt := range tests {
- nDst, _, err := tt.f.Transform(b[:tt.dstSize], []byte(tt.in), tt.eof)
- out := string(b[:nDst])
- if out != tt.out || err != tt.err {
- t.Errorf("%d: was %+q (%v); want %+q (%v)", i, out, err, tt.out, tt.err)
- }
- if want := tt.f.String(tt.in)[:nDst]; want != out {
- t.Errorf("%d: incorrect normalization: was %+q; want %+q", i, out, want)
- }
+ t.Run(fmt.Sprintf("%d:%s", i, tt.in), func(t *testing.T) {
+ nDst, _, err := tt.f.Transform(b[:tt.dstSize], []byte(tt.in), tt.eof)
+ out := string(b[:nDst])
+ if out != tt.out || err != tt.err {
+ t.Errorf("was %+q (%v); want %+q (%v)", out, err, tt.out, tt.err)
+ }
+ if want := tt.f.String(tt.in)[:nDst]; want != out {
+ t.Errorf("incorrect normalization: was %+q; want %+q", out, want)
+ }
+ })
}
}