fix(fs): reject negative offsets when seeking from the start (#3633)

In plugins/fs/src/commands.rs seek, `SeekFrom::Start(offset as u64)`
turned -1 into u64::MAX. The offset is now converted with u64::try_from
and a negative one is an error. E2E spec added.
This commit is contained in:
Lucas Fernandes Nogueira authored and GitHub committed 2026-10-09 13:04:44 -03:00
1 parent 5c144e7466
commit 77d00a4f54
3 files changed
+29 -9

No files matched your search

+6
View File
@@ -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.
+13
View File
@@ -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 () => { it('a closed FileHandle cannot be used again', async () => {
const message = await tauriError(async (api, path) => { const message = await tauriError(async (api, path) => {
const baseDir = api.fs.BaseDirectory.AppData const baseDir = api.fs.BaseDirectory.AppData
+10 -9
View File
@@ -888,16 +888,17 @@ pub async fn seek<R: Runtime>(
whence: SeekMode, whence: SeekMode,
) -> CommandResult<u64> { ) -> CommandResult<u64> {
use std::io::{Seek, SeekFrom}; 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<StdFileResource<R>> = webview.resources_table().get(rid)?; let file: std::sync::Arc<StdFileResource<R>> = webview.resources_table().get(rid)?;
StdFileResource::with_lock(&file, |file| { StdFileResource::with_lock(&file, |file| file.seek(position))
file.seek(match whence { .map_err(|e| format!("failed to seek file with error: {e}"))
SeekMode::Start => SeekFrom::Start(offset as u64), .map_err(Into::into)
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)
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]