fix: escape formula characters in contact CSV export (#15334)

## Description

Contact export builds its CSV with the standard library `CSV`, which
writes user-supplied values (name, email, phone, custom attributes)
verbatim. When a cell begins with a formula character (`=`, `+`, `-`,
`@`, and tab/CR), spreadsheet applications interpret it as a formula on
open. This switches the export to `CSVSafe` (the `csv-safe` gem already
used by the v2 report exports), which prefixes such fields so they are
treated as text.

No new dependency, no behavioural change beyond neutralising
formula-leading cells. Note: phone numbers stored with a leading `+` are
now prefixed with a single quote in the exported file, consistent with
how the report exports already behave.

Ref https://linear.app/chatwoot/issue/CW-7473

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

`bundle exec rspec spec/jobs/account/contacts_export_job_spec.rb` —
added a case asserting a formula-leading contact value is neutralised on
export; existing cases updated for the phone-number prefix.

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
This commit is contained in:
Vishnu Narayanan
2026-08-13 18:09:38 +05:30
committed by GitHub
parent 8864f80ab7
commit a929955cc3
2 changed files with 15 additions and 2 deletions

View File

@@ -20,7 +20,7 @@ class Account::ContactsExportJob < ApplicationJob
contacts_to_export = contacts.to_a
preload_contact_labels(contacts_to_export) if headers.include?(LABELS_COLUMN)
csv_data = CSV.generate do |csv|
csv_data = CSVSafe.generate do |csv|
csv << headers
contacts_to_export.each do |contact|
csv << headers.map { |header| value_for_header(contact, header) }