diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index e0b896985..171a146be 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -1237,7 +1237,10 @@ def _insert_docs(docs, tracker=None): csv_reader_args["delimiter"] = delimiter if 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) if no_headers: headers = ["untitled_{}".format(i + 1) for i in range(len(first_row))] diff --git a/tests/test_cli_insert.py b/tests/test_cli_insert.py index df6f80c62..c4e25d9e9 100644 --- a/tests/test_cli_insert.py +++ b/tests/test_cli_insert.py @@ -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( "input,args", (