Project

General

Profile

Defect #41434 » 0001-CSV-import-fails-with-error-for-quoted-fields-contai.patch

Go MAEDA, 2026-02-16 14:48

View differences:

app/models/import.rb
72 72
        content = read_file_head
73 73

  
74 74
        separator = [',', ';'].max_by {|sep| content.count(sep)}
75
        newline = content.index("\r\n") ? "\r\n" : '' # blank means auto
75 76
        wrapper = ['"', "'"].max_by {|quote_char| content.count(quote_char)}
76 77

  
77 78
        guessed_encoding = Redmine::CodesetUtil.guess_encoding(content)
......
89 90

  
90 91
    self.settings.merge!(
91 92
      'separator' => separator,
93
      'newline' => newline,
92 94
      'wrapper' => wrapper,
93 95
      'encoding' => encoding,
94 96
      'date_format' => date_format,
......
272 274
    csv_options[:encoding] = 'bom|UTF-8' if csv_options[:encoding] == 'UTF-8'
273 275
    separator = settings['separator'].to_s
274 276
    csv_options[:col_sep] = separator if separator.size == 1
277
    newline = settings['newline'].to_s
278
    csv_options[:row_sep] = newline unless newline.empty?
275 279
    wrapper = settings['wrapper'].to_s
276 280
    csv_options[:quote_char] = wrapper if wrapper.size == 1
277 281

  
test/fixtures/files/import_crlf_with_newline_in_quoted_header.csv
1
plain_header,"quoted_header
2
contains_LF"
3
foo,bar
test/functional/imports_controller_test.rb
187 187
    assert_select 'div#flash_error', /The file is not a CSV file or does not match the settings below \([[:print:]]+\)/
188 188
  end
189 189

  
190
  def test_post_settings_with_crlf_and_newline_in_quoted_header_should_not_fail
191
    import = new_record(Import) do
192
      post(
193
        :create,
194
        :params => {
195
          :type => 'IssueImport',
196
          :file => uploaded_test_file('import_crlf_with_newline_in_quoted_header.csv', 'text/csv')
197
        }
198
      )
199
      assert_response :found
200
    end
201
    assert_equal "\r\n", import.settings['newline']
202

  
203
    post(
204
      :settings,
205
      :params => {
206
        :id => import.to_param,
207
        :import_settings => {
208
          :separator => ',',
209
          :wrapper => '"',
210
          :encoding => 'UTF-8'
211
        }
212
      }
213
    )
214
    assert_response :found
215
    import.reload
216
    assert_equal 1, import.total_items
217
  end
218

  
190 219
  def test_post_settings_with_no_data_row_should_display_error
191 220
    import = generate_import('import_issues_no_data_row.csv')
192 221

  
(5-5/5)