Skip to content

Commit 52d96ca

Browse files
authored
Merge pull request #2626 from dhalbert/stat-for-shortint
avoid os.stat() int overflow on smallint-only builds
2 parents e0b8529 + e0753c4 commit 52d96ca

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

extmod/vfs_fat.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -345,24 +345,31 @@ 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(
349-
1980 + ((fno.fdate >> 9) & 0x7f),
350-
(fno.fdate >> 5) & 0x0f,
351-
fno.fdate & 0x1f,
352-
(fno.ftime >> 11) & 0x1f,
353-
(fno.ftime >> 5) & 0x3f,
354-
2 * (fno.ftime & 0x1f)
355-
);
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(
354+
timeutils_seconds_since_epoch(
355+
1980 + ((fno.fdate >> 9) & 0x7f),
356+
(fno.fdate >> 5) & 0x0f,
357+
fno.fdate & 0x1f,
358+
(fno.ftime >> 11) & 0x1f,
359+
(fno.ftime >> 5) & 0x3f,
360+
2 * (fno.ftime & 0x1f)
361+
));
362+
#endif
356363
t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
357364
t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
358365
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
359366
t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
360367
t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
361368
t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
362369
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
370+
t->items[7] = seconds; // st_atime
371+
t->items[8] = seconds; // st_mtime
372+
t->items[9] = seconds; // st_ctime
366373

367374
return MP_OBJ_FROM_PTR(t);
368375
}

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)