mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-09 18:14:09 +02:00
Strip NUL bytes from CSV input to prevent crash
When a CSV file contains NUL bytes the csv module raises _csv.Error: line contains NUL, crashing the insert command without a useful error message. Stripping \x00 from each line before passing it to the reader preserves all meaningful data while matching the behaviour users expect. Fixes #582.
This commit is contained in:
parent
a947dc6739
commit
e1d0fba30f
2 changed files with 21 additions and 1 deletions
|
|
@ -1237,7 +1237,10 @@ def insert_upsert_implementation(
|
||||||
csv_reader_args["delimiter"] = delimiter
|
csv_reader_args["delimiter"] = delimiter
|
||||||
if quotechar:
|
if quotechar:
|
||||||
csv_reader_args["quotechar"] = quotechar
|
csv_reader_args["quotechar"] = quotechar
|
||||||
reader = csv_std.reader(decoded, **csv_reader_args) # type: ignore
|
reader = csv_std.reader( # type: ignore
|
||||||
|
(line.replace("\x00", "") for line in decoded),
|
||||||
|
**csv_reader_args,
|
||||||
|
)
|
||||||
first_row = next(reader)
|
first_row = next(reader)
|
||||||
if no_headers:
|
if no_headers:
|
||||||
headers = ["untitled_{}".format(i + 1) for i in range(len(first_row))]
|
headers = ["untitled_{}".format(i + 1) for i in range(len(first_row))]
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,23 @@ def test_insert_csv_empty_null(db_path, empty_null):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_insert_csv_nul_bytes(db_path, tmpdir):
|
||||||
|
# Regression test for https://github.com/simonw/sqlite-utils/issues/582
|
||||||
|
# CSV files containing NUL bytes should be imported without crashing.
|
||||||
|
file_path = str(tmpdir / "nul.csv")
|
||||||
|
with open(file_path, "wb") as fp:
|
||||||
|
fp.write(b"id,name\n1,Al\x00ice\n2,Bob\n")
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
cli.cli,
|
||||||
|
["insert", db_path, "data", file_path, "--csv", "--no-detect-types"],
|
||||||
|
catch_exceptions=False,
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
db = Database(db_path)
|
||||||
|
rows = list(db["data"].rows)
|
||||||
|
assert rows == [{"id": "1", "name": "Alice"}, {"id": "2", "name": "Bob"}]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"input,args",
|
"input,args",
|
||||||
(
|
(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue