Skip to content

Commit 46c4b47

Browse files
committed
avoid os.stat() int overflow on smallint-only builds
1 parent cabc30e commit 46c4b47

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

extmod/vfs_fat.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -345,24 +345,29 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
345345
} else {
346346
mode |= MP_S_IFREG;
347347
}
348-
mp_uint_t seconds = timeutils_seconds_since_epoch(
348+
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
349+
// On non-longint builds, the number of seconds since 1970 (epoch) is too
350+
// large to fit in a smallint, so just return 31-DEC-1999 (0).
351+
mp_obj_t seconds = MP_OBJ_NEW_SMALL_INT(946684800);
352+
#else
353+
mp_obj_t seconds = mp_obj_new_int_from_uint(timeutils_seconds_since_epoch(
349354
1980 + ((fno.fdate >> 9) & 0x7f),
350355
(fno.fdate >> 5) & 0x0f,
351356
fno.fdate & 0x1f,
352357
(fno.ftime >> 11) & 0x1f,
353358
(fno.ftime >> 5) & 0x3f,
354359
2 * (fno.ftime & 0x1f)
355-
);
360+
#endif
356361
t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
357362
t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
358363
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
359364
t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
360365
t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
361366
t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
362367
t->items[6] = mp_obj_new_int_from_uint(fno.fsize); // st_size
363-
t->items[7] = mp_obj_new_int_from_uint(seconds); // st_atime
364-
t->items[8] = mp_obj_new_int_from_uint(seconds); // st_mtime
365-
t->items[9] = mp_obj_new_int_from_uint(seconds); // st_ctime
368+
t->items[7] = seconds; // st_atime
369+
t->items[8] = seconds; // st_mtime
370+
t->items[9] = seconds; // st_ctime
366371

367372
return MP_OBJ_FROM_PTR(t);
368373
}

shared-bindings/os/__init__.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
143143
//|
144144
//| Get the status of a file or directory.
145145
//|
146+
//| .. note:: On builds without long integers, the number of seconds
147+
//| for contemporary dates will not fit in a small integer.
148+
//| So the time fields return 946684800,
149+
//| which is the number of seconds corresponding to 1999-12-31.
150+
//|
146151
mp_obj_t os_stat(mp_obj_t path_in) {
147152
const char *path = mp_obj_str_get_str(path_in);
148153
return common_hal_os_stat(path);

0 commit comments

Comments
 (0)