Cap preview cols to prevent stall when csv is parsed with the wrong delimiter (#3786)

* cap csv import preview table at 1000 columns

* add fluent message

* show warning when preview table columns have been truncated

* simplify fluent message ($count will almost always be a big num)

* _tr -> tr
This commit is contained in:
llama 2025-02-06 15:23:43 +08:00 committed by GitHub
parent dd93691b9c
commit 2cbcd79a84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 2 deletions

View file

@ -67,6 +67,12 @@ importing-packaged-anki-deckcollection-apkg-colpkg-zip = Packaged Anki Deck/Coll
importing-pauker-18-lesson-paugz = Pauker 1.8 Lesson (*.pau.gz) importing-pauker-18-lesson-paugz = Pauker 1.8 Lesson (*.pau.gz)
# the '|' character # the '|' character
importing-pipe = Pipe importing-pipe = Pipe
# Warning displayed when the csv import preview table is clipped (some columns were hidden)
# $count is intended to be a large number (1000 and above)
importing-preview-truncated =
{ $count ->
*[other] Only the first { $count } columns are shown. If this doesn't seem right, try changing the field separator.
}
importing-rows-had-num1d-fields-expected-num2d = '{ $row }' had { $found } fields, expected { $expected } importing-rows-had-num1d-fields-expected-num2d = '{ $row }' had { $found } fields, expected { $expected }
importing-selected-file-was-not-in-utf8 = Selected file was not in UTF-8 format. Please see the importing section of the manual. importing-selected-file-was-not-in-utf8 = Selected file was not in UTF-8 format. Please see the importing section of the manual.
importing-semicolon = Semicolon importing-semicolon = Semicolon

View file

@ -3,12 +3,34 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="ts"> <script lang="ts">
import Warning from "../deck-options/Warning.svelte";
import { type ImportCsvState } from "./lib"; import { type ImportCsvState } from "./lib";
import * as tr from "@generated/ftl";
export let state: ImportCsvState; export let state: ImportCsvState;
export let maxColumns = 1000;
const metadata = state.metadata; const metadata = state.metadata;
const columnOptions = state.columnOptions; const columnOptions = state.columnOptions;
let rows: string[][];
let truncated = false;
function sanitisePreview(preview: typeof $metadata.preview) {
let truncated = false;
const rows = preview.map((x) => {
if (x.vals.length > maxColumns) {
truncated = true;
return x.vals.slice(0, maxColumns);
}
return x.vals;
});
return { rows, truncated };
}
$: ({ rows, truncated } = sanitisePreview($metadata.preview));
$: warning = truncated ? tr.importingPreviewTruncated({ count: maxColumns }) : "";
</script> </script>
<div class="outer"> <div class="outer">
@ -23,9 +45,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#each $metadata.preview as row} {#each rows as row}
<tr> <tr>
{#each row.vals as cell} {#each row as cell}
<td>{cell}</td> <td>{cell}</td>
{/each} {/each}
</tr> </tr>
@ -33,10 +55,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</tbody> </tbody>
</table> </table>
</div> </div>
<Warning {warning} />
<style lang="scss"> <style lang="scss">
.outer { .outer {
overflow: auto; overflow: auto;
margin-bottom: 0.5rem;
} }
.preview { .preview {