diff --git a/.changes/fix-fs-seek-negative.md b/.changes/fix-fs-seek-negative.md new file mode 100644 index 000000000..0e46ce23a --- /dev/null +++ b/.changes/fix-fs-seek-negative.md @@ -0,0 +1,6 @@ +--- +fs: patch +fs-js: patch +--- + +`FileHandle.seek` now rejects a negative offset with `SeekMode.Start` instead of seeking to a huge position. diff --git a/packages/api-e2e/test/specs/fs.spec.ts b/packages/api-e2e/test/specs/fs.spec.ts index 790ee9105..68e9f22a3 100644 --- a/packages/api-e2e/test/specs/fs.spec.ts +++ b/packages/api-e2e/test/specs/fs.spec.ts @@ -371,6 +371,19 @@ describePlugin('fs', () => { }) }) + it('FileHandle.seek rejects a negative offset from the start', async () => { + const message = await tauriError(async (api, path) => { + const baseDir = api.fs.BaseDirectory.AppData + const file = await api.fs.create(path, { baseDir }) + try { + await file.seek(-1, api.fs.SeekMode.Start) + } finally { + await file.close() + } + }, `${dir}/seek.txt`) + expect(message).toMatch(/must not be negative/) + }) + it('a closed FileHandle cannot be used again', async () => { const message = await tauriError(async (api, path) => { const baseDir = api.fs.BaseDirectory.AppData diff --git a/plugins/fs/src/commands.rs b/plugins/fs/src/commands.rs index 958e01de3..c66bb0d5a 100644 --- a/plugins/fs/src/commands.rs +++ b/plugins/fs/src/commands.rs @@ -888,16 +888,17 @@ pub async fn seek( whence: SeekMode, ) -> CommandResult { use std::io::{Seek, SeekFrom}; + let position = match whence { + SeekMode::Start => SeekFrom::Start(u64::try_from(offset).map_err(|_| { + format!("invalid seek offset {offset}: it must not be negative with SeekMode.Start") + })?), + SeekMode::Current => SeekFrom::Current(offset), + SeekMode::End => SeekFrom::End(offset), + }; let file: std::sync::Arc> = webview.resources_table().get(rid)?; - StdFileResource::with_lock(&file, |file| { - file.seek(match whence { - SeekMode::Start => SeekFrom::Start(offset as u64), - SeekMode::Current => SeekFrom::Current(offset), - SeekMode::End => SeekFrom::End(offset), - }) - }) - .map_err(|e| format!("failed to seek file with error: {e}")) - .map_err(Into::into) + StdFileResource::with_lock(&file, |file| file.seek(position)) + .map_err(|e| format!("failed to seek file with error: {e}")) + .map_err(Into::into) } #[cfg(target_os = "android")]