8000 py/stream: seek: Consistently handle negative offset for SEEK_SET. · adafruit/circuitpython@e3383e9 · GitHub
[go: up one dir, main page]

Skip to content

Commit e3383e9

Browse files
committed
py/stream: seek: Consistently handle negative offset for SEEK_SET.
Per POSIX, this is EINVAL, so raises OSError(EINVAL).
1 parent 0cd9ab7 commit e3383e9

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

py/stream.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,11 +448,16 @@ STATIC mp_obj_t stream_seek(size_t n_args, const mp_obj_t *args) {
448448
struct mp_stream_seek_t seek_s;
449449
// TODO: Could be uint64
450450
seek_s.offset = mp_obj_get_int(args[1]);
451-
seek_s.whence = 0;
451+
seek_s.whence = SEEK_SET;
452452
if (n_args == 3) {
453453
seek_s.whence = mp_obj_get_int(args[2]);
454454
}
455455

456+
// In POSIX, it's error to seek before end of stream, we enforce it here.
457+
if (seek_s.whence == SEEK_SET && seek_s.offset < 0) {
458+
mp_raise_OSError(MP_EINVAL);
459+
}
460+
456461
int error;
457462
mp_uint_t res = stream_p->ioctl(args[0], MP_STREAM_SEEK, (mp_uint_t)(uintptr_t)&seek_s, &error);
458463
if (res == MP_STREAM_ERROR) {

tests/io/bytesio_ext2.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
try:
2+
import uio as io
3+
except ImportError:
4+
import io
5+
6+
a = io.BytesIO(b"foobar")
7+
try:
8+
a.seek(-10)
9+
except Exception as e:
10+
# CPython throws ValueError, but MicroPython has consistent stream
11+
# interface, so BytesIO raises the same error as a real file, which
12+
# is OSError(EINVAL).
13+
print(repr(e))

tests/io/bytesio_ext2.py.exp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
OSError(22,)

0 commit comments

Comments
 (0)
0