mirror of
https://github.com/go-gitea/gitea
synced 2025-09-10 02:38:28 +00:00
Disable Field count validation of CSV viewer (#35228)
Default behaviour rejected all rows (Records) with more or fewer columns (Fields) than the first row, preventing them from parsing at all and silently hiding them. While RFC4180 section 2.4 says each line _should_ contain the same number of fields, enforcing this on the viewer is unhelpful. This pull request disables that validation, allowing the viewer to render lines with fewer columns than the maximum number within the file. As it's a simple HTML table, this works without additional changes (i.e. no need to manually determine the maximum number of columns), but the default appearance of rows with fewer columns may be undesirable to some people, especially when using CSS that has `td {border-right: none}`. <img width="1408" height="156" alt="Screenshot without cell right borders" src="https://github.com/user-attachments/assets/d4c19bbc-3fd2-4fd1-83a6-1125e953e95b" /> <img width="1397" height="158" alt="Screenshot with cell right borders" src="https://github.com/user-attachments/assets/86aaafcb-d7e8-4228-99a8-7527c823a07c" /> Fixes #16559, #30358. Unfortunately, retaining empty lines is less trivial, so the line numbers on the leftmost column will still not match the source file whenever those are present, though a future PR could address that.
This commit is contained in:
@@ -30,6 +30,8 @@ func CreateReader(input io.Reader, delimiter rune) *stdcsv.Reader {
|
||||
// thus would change `\t\t` to just `\t` or ` ` (two spaces) to just ` ` (single space)
|
||||
rd.TrimLeadingSpace = true
|
||||
}
|
||||
// Don't force validation of every row to have the same number of entries as the first row.
|
||||
rd.FieldsPerRecord = -1
|
||||
return rd
|
||||
}
|
||||
|
||||
|
@@ -94,6 +94,24 @@ j, ,\x20
|
||||
},
|
||||
expectedDelimiter: ',',
|
||||
},
|
||||
// case 3 - every delimiter used, default to comma and handle differing number of fields per record
|
||||
{
|
||||
csv: `col1,col2
|
||||
a;b
|
||||
c@e
|
||||
f g
|
||||
h|i
|
||||
jkl`,
|
||||
expectedRows: [][]string{
|
||||
{"col1", "col2"},
|
||||
{"a;b"},
|
||||
{"c@e"},
|
||||
{"f g"},
|
||||
{"h|i"},
|
||||
{"jkl"},
|
||||
},
|
||||
expectedDelimiter: ',',
|
||||
},
|
||||
}
|
||||
|
||||
for n, c := range cases {
|
||||
@@ -119,21 +137,6 @@ func TestDetermineDelimiterShortBufferError(t *testing.T) {
|
||||
assert.Nil(t, rd, "CSV reader should be mnil")
|
||||
}
|
||||
|
||||
func TestDetermineDelimiterReadAllError(t *testing.T) {
|
||||
rd, err := CreateReaderAndDetermineDelimiter(nil, strings.NewReader(`col1,col2
|
||||
a;b
|
||||
c@e
|
||||
f g
|
||||
h|i
|
||||
jkl`))
|
||||
assert.NoError(t, err, "CreateReaderAndDetermineDelimiter() shouldn't throw error")
|
||||
assert.NotNil(t, rd, "CSV reader should not be mnil")
|
||||
rows, err := rd.ReadAll()
|
||||
assert.Error(t, err, "RaadAll() should throw error")
|
||||
assert.ErrorIs(t, err, csv.ErrFieldCount)
|
||||
assert.Empty(t, rows, "rows should be empty")
|
||||
}
|
||||
|
||||
func TestDetermineDelimiter(t *testing.T) {
|
||||
cases := []struct {
|
||||
csv string
|
||||
|
Reference in New Issue
Block a user