aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/csv
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/csv')
-rw-r--r--src/encoding/csv/reader.go10
-rw-r--r--src/encoding/csv/reader_test.go30
-rw-r--r--src/encoding/csv/writer.go4
3 files changed, 44 insertions, 0 deletions
diff --git a/src/encoding/csv/reader.go b/src/encoding/csv/reader.go
index 00b9bbffee..031ee6cedb 100644
--- a/src/encoding/csv/reader.go
+++ b/src/encoding/csv/reader.go
@@ -88,6 +88,12 @@ var (
ErrFieldCount = errors.New("wrong number of fields")
)
+var errInvalidDelim = errors.New("csv: invalid field or comment delimiter")
+
+func validDelim(r rune) bool {
+ return r != 0 && r != '\r' && r != '\n' && utf8.ValidRune(r) && r != utf8.RuneError
+}
+
// A Reader reads records from a CSV-encoded file.
//
// As returned by NewReader, a Reader expects input conforming to RFC 4180.
@@ -232,6 +238,10 @@ func nextRune(b []byte) rune {
}
func (r *Reader) readRecord(dst []string) ([]string, error) {
+ if r.Comma == r.Comment || !validDelim(r.Comma) || (r.Comment != 0 && !validDelim(r.Comment)) {
+ return nil, errInvalidDelim
+ }
+
// Read line (automatically skipping past empty lines and any comments).
var line, fullLine []byte
var errRead error
diff --git a/src/encoding/csv/reader_test.go b/src/encoding/csv/reader_test.go
index ed7d89dfe0..48efbb6719 100644
--- a/src/encoding/csv/reader_test.go
+++ b/src/encoding/csv/reader_test.go
@@ -9,6 +9,7 @@ import (
"reflect"
"strings"
"testing"
+ "unicode/utf8"
)
func TestRead(t *testing.T) {
@@ -312,6 +313,35 @@ x,,,
Input: `"""""""`,
Output: [][]string{{`"""`}},
LazyQuotes: true,
+ }, {
+ Name: "BadComma1",
+ Comma: '\n',
+ Error: errInvalidDelim,
+ }, {
+ Name: "BadComma2",
+ Comma: '\r',
+ Error: errInvalidDelim,
+ }, {
+ Name: "BadComma3",
+ Comma: utf8.RuneError,
+ Error: errInvalidDelim,
+ }, {
+ Name: "BadComment1",
+ Comment: '\n',
+ Error: errInvalidDelim,
+ }, {
+ Name: "BadComment2",
+ Comment: '\r',
+ Error: errInvalidDelim,
+ }, {
+ Name: "BadComment3",
+ Comment: utf8.RuneError,
+ Error: errInvalidDelim,
+ }, {
+ Name: "BadCommaComment",
+ Comma: 'X',
+ Comment: 'X',
+ Error: errInvalidDelim,
}}
for _, tt := range tests {
diff --git a/src/encoding/csv/writer.go b/src/encoding/csv/writer.go
index 84b7aa1ed1..b23cae4517 100644
--- a/src/encoding/csv/writer.go
+++ b/src/encoding/csv/writer.go
@@ -38,6 +38,10 @@ func NewWriter(w io.Writer) *Writer {
// Writer writes a single CSV record to w along with any necessary quoting.
// A record is a slice of strings with each string being one field.
func (w *Writer) Write(record []string) error {
+ if !validDelim(w.Comma) {
+ return errInvalidDelim
+ }
+
for n, field := range record {
if n > 0 {
if _, err := w.w.WriteRune(w.Comma); err != nil {