From 0b3b5113c0bbc62306a0404b235cbdf5a431bf67 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Fri, 1 Dec 2017 11:41:46 -0800 Subject: [PATCH] encoding/csv: truncate carriage returns at EOF This fixes a regression where only CRLF was folded into LF at EOF. Now, we also truncate trailing CR at EOF to preserve the old behavior. Every one of the test cases added exactly matches the behavior of Go1.9, even if the results are somewhat unexpected. Fixes #22937 Change-Id: I1bc6550533163ae489ea77ec1e598163267b7eec Reviewed-on: https://go-review.googlesource.com/81577 Run-TryBot: Joe Tsai TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/encoding/csv/reader.go | 4 ++++ src/encoding/csv/reader_test.go | 38 ++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/encoding/csv/reader.go b/src/encoding/csv/reader.go index 1350f3ebdd..2efc7ad094 100644 --- a/src/encoding/csv/reader.go +++ b/src/encoding/csv/reader.go @@ -224,6 +224,10 @@ func (r *Reader) readLine() ([]byte, error) { } if len(line) > 0 && err == io.EOF { err = nil + // For backwards compatibility, drop trailing \r before EOF. + if line[len(line)-1] == '\r' { + line = line[:len(line)-1] + } } r.numLine++ // Normalize \r\n to \n on all input lines. diff --git a/src/encoding/csv/reader_test.go b/src/encoding/csv/reader_test.go index d62aa77382..1fc69f9ab8 100644 --- a/src/encoding/csv/reader_test.go +++ b/src/encoding/csv/reader_test.go @@ -246,7 +246,43 @@ x,,, }, { Name: "TrailingCR", Input: "field1,field2\r", - Output: [][]string{{"field1", "field2\r"}}, + Output: [][]string{{"field1", "field2"}}, + }, { + Name: "QuotedTrailingCR", + Input: "\"field\"\r", + Output: [][]string{{"field"}}, + }, { + Name: "QuotedTrailingCRCR", + Input: "\"field\"\r\r", + Error: &ParseError{StartLine: 1, Line: 1, Column: 6, Err: ErrQuote}, + }, { + Name: "FieldCR", + Input: "field\rfield\r", + Output: [][]string{{"field\rfield"}}, + }, { + Name: "FieldCRCR", + Input: "field\r\rfield\r\r", + Output: [][]string{{"field\r\rfield\r"}}, + }, { + Name: "FieldCRCRLF", + Input: "field\r\r\nfield\r\r\n", + Output: [][]string{{"field\r"}, {"field\r"}}, + }, { + Name: "FieldCRCRLFCR", + Input: "field\r\r\n\rfield\r\r\n\r", + Output: [][]string{{"field\r"}, {"\rfield\r"}}, + }, { + Name: "FieldCRCRLFCRCR", + Input: "field\r\r\n\r\rfield\r\r\n\r\r", + Output: [][]string{{"field\r"}, {"\r\rfield\r"}, {"\r"}}, + }, { + Name: "MultiFieldCRCRLFCRCR", + Input: "field1,field2\r\r\n\r\rfield1,field2\r\r\n\r\r,", + Output: [][]string{ + {"field1", "field2\r"}, + {"\r\rfield1", "field2\r"}, + {"\r\r", ""}, + }, }, { Name: "NonASCIICommaAndComment", Input: "a£b,c£ \td,e\n€ comment\n", -- 2.50.0