Skip to content

Commit db774ff

Browse files
committed
Add support for leading BOM when reading import CSV files
1 parent 09d91bf commit db774ff

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"category": "configure",
3+
"type": "enhancement",
4+
"description": "Add support for importing CSV credential files that have leading UTF-8 BOM. Fixes `#7721 <https://github.com/aws/aws-cli/issues/7721>`__."
5+
}

awscli/customizations/configure/importer.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
# language governing permissions and limitations under the License.
1313
import os
1414
import sys
15+
import codecs
1516

16-
from awscli.compat import compat_open
1717
from awscli.customizations.utils import uni_print
1818
from awscli.customizations.commands import BasicCommand
1919
from awscli.customizations.configure.writer import ConfigFileWriter
@@ -115,6 +115,9 @@ def __init__(self, strict=True):
115115
self.strict = strict
116116

117117
def _format_header(self, header):
118+
# Remove leading UTF BOM character if present
119+
if header.startswith(codecs.BOM_UTF8.decode()):
120+
header = header[1:]
118121
return header.lower().strip()
119122

120123
def _parse_csv_headers(self, header):

tests/unit/customizations/configure/test_importer.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ def test_csv_parser_simple(self):
109109
)
110110
self.assert_parse_matches_expected(contents)
111111

112+
def test_csv_parser_with_bom(self):
113+
contents = (
114+
u'\ufeffUser name,Access key ID,Secret access key\n'
115+
'PROFILENAME,AKID,SAK\n'
116+
)
117+
self.assert_parse_matches_expected(contents)
118+
112119
def test_csv_parser_multiple_entries(self):
113120
contents = (
114121
'User name,Access key ID,Secret access key\n'
@@ -121,6 +128,18 @@ def test_csv_parser_multiple_entries(self):
121128
]
122129
self.assert_parse_matches_expected(contents)
123130

131+
def test_csv_parser_multiple_entries_bom(self):
132+
contents = (
133+
u'\ufeffUser name,Access key ID,Secret access key\n'
134+
'PROFILENAME1,AKID1,SAK1\n'
135+
'PROFILENAME2,AKID2,SAK2\n'
136+
)
137+
self.expected_credentials = [
138+
('PROFILENAME1', 'AKID1', 'SAK1'),
139+
('PROFILENAME2', 'AKID2', 'SAK2'),
140+
]
141+
self.assert_parse_matches_expected(contents)
142+
124143
def test_csv_parser_multiple_entries_with_bad_entries(self):
125144
self.parser.strict = False
126145
contents = (

0 commit comments

Comments
 (0)