Skip to content

Commit 21f1bb3

Browse files
authored
Merge pull request #2093 from hermit-os/fs-mem-lseek
fix(mem/fs): improve lseek errors
2 parents dfff928 + d319643 commit 21f1bb3

File tree

1 file changed

+28
-28
lines changed

1 file changed

+28
-28
lines changed

src/fs/mem.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -90,25 +90,23 @@ impl ObjectInterface for RomFileInterface {
9090
let guard = self.inner.read().await;
9191
let mut pos_guard = self.pos.lock().await;
9292

93-
let new_pos: isize = if whence == SeekWhence::Set {
94-
if offset < 0 {
95-
return Err(Errno::Inval);
96-
}
97-
98-
offset
99-
} else if whence == SeekWhence::End {
100-
guard.data.len() as isize + offset
101-
} else if whence == SeekWhence::Cur {
102-
(*pos_guard as isize) + offset
103-
} else {
104-
return Err(Errno::Inval);
93+
// NOTE: Allocations can never be larger than `isize::MAX` bytes.
94+
let data_len = guard.data.len() as isize;
95+
96+
let new_pos = match whence {
97+
SeekWhence::Set => offset,
98+
SeekWhence::Cur => (*pos_guard as isize)
99+
.checked_add(offset)
100+
.ok_or(Errno::Overflow)?,
101+
SeekWhence::End => data_len.checked_add(offset).ok_or(Errno::Overflow)?,
102+
_ => return Err(Errno::Inval),
105103
};
106104

107-
if new_pos <= isize::try_from(guard.data.len()).unwrap() {
108-
*pos_guard = new_pos.try_into().unwrap();
105+
if (0..=data_len).contains(&new_pos) {
106+
*pos_guard = new_pos as usize;
109107
Ok(new_pos)
110108
} else {
111-
Err(Errno::Badf)
109+
Err(Errno::Inval)
112110
}
113111
}
114112

@@ -222,25 +220,27 @@ impl ObjectInterface for RamFileInterface {
222220
let mut guard = self.inner.write().await;
223221
let mut pos_guard = self.pos.lock().await;
224222

225-
let new_pos: isize = if whence == SeekWhence::Set {
226-
if offset < 0 {
227-
return Err(Errno::Inval);
228-
}
223+
// NOTE: Allocations can never be larger than `isize::MAX` bytes.
224+
let data_len = guard.data.len() as isize;
229225

230-
offset
231-
} else if whence == SeekWhence::End {
232-
guard.data.len() as isize + offset
233-
} else if whence == SeekWhence::Cur {
234-
(*pos_guard as isize) + offset
235-
} else {
236-
return Err(Errno::Inval);
226+
let new_pos = match whence {
227+
SeekWhence::Set => offset,
228+
SeekWhence::Cur => (*pos_guard as isize)
229+
.checked_add(offset)
230+
.ok_or(Errno::Overflow)?,
231+
SeekWhence::End => data_len.checked_add(offset).ok_or(Errno::Overflow)?,
232+
_ => return Err(Errno::Inval),
237233
};
238234

239-
if new_pos > isize::try_from(guard.data.len()).unwrap() {
235+
if new_pos < 0 {
236+
return Err(Errno::Inval);
237+
}
238+
239+
if new_pos > data_len {
240240
guard.data.resize(new_pos.try_into().unwrap(), 0);
241241
guard.attr.st_size = guard.data.len().try_into().unwrap();
242242
}
243-
*pos_guard = new_pos.try_into().unwrap();
243+
*pos_guard = new_pos as usize;
244244

245245
Ok(new_pos)
246246
}

0 commit comments

Comments
 (0)