From 0de0389c6f83860826c5a3340d41256966f3ac08 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 20 Nov 2024 17:30:18 -0600 Subject: [PATCH 1/9] paths: Reworked test_paths to cover more corner cases This should be a superset of the previous test_paths test suite, while covering a couple more things (more APIs, more path synonyms, utf8, non-printable ascii, non-utf8, etc). Not yet tested are some corner cases with known bugs, mainly around trailing slashes. --- tests/test_paths.toml | 4354 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 4179 insertions(+), 175 deletions(-) diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 97a519ea..89fb89e9 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -1,237 +1,2207 @@ # simple path test -[cases.test_paths_normal] +[cases.test_paths_simple] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - - lfs_mkdir(&lfs, "/milk") => 0; - lfs_stat(&lfs, "/milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_stat(&lfs, "milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "coffee/drip", + "espresso/espresso") => 0; + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano") => 0; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato") => 0; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte") => 0; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino") => 0; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "espresso/espresso") => 0; + lfs_remove(&lfs, "espresso/americano") => 0; + lfs_remove(&lfs, "espresso/macchiato") => 0; + lfs_remove(&lfs, "espresso/latte") => 0; + lfs_remove(&lfs, "espresso/cappuccino") => 0; + lfs_remove(&lfs, "espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# absolute path test +# +# littlefs does not provide cd, so these are the same as relative paths +[cases.test_paths_absolute] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "/coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/turkish") => 0; + lfs_mkdir(&lfs, "/coffee/tubruk") => 0; + lfs_mkdir(&lfs, "/coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "/coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "/coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "coffee/drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "coffee/coldbrew", + "/espresso/americano") => 0; + lfs_rename(&lfs, + "/coffee/turkish", + "espresso/macchiato") => 0; + lfs_rename(&lfs, + "/coffee/tubruk", + "espresso/latte") => 0; + lfs_rename(&lfs, + "/coffee/vietnamese", + "/espresso/cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "/espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "/espresso/americano") => 0; + lfs_remove(&lfs, "/espresso/macchiato") => 0; + lfs_remove(&lfs, "/espresso/latte") => 0; + lfs_remove(&lfs, "/espresso/cappuccino") => 0; + lfs_remove(&lfs, "/espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' # redundant slashes [cases.test_paths_redundant_slashes] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "//coffee//coldbrew") => 0; + lfs_mkdir(&lfs, "///coffee///turkish") => 0; + lfs_mkdir(&lfs, "////coffee////tubruk") => 0; + lfs_mkdir(&lfs, "/////coffee/////vietnamese") => 0; + lfs_mkdir(&lfs, "//////coffee//////thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "/tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "//tea//hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "///tea///hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - - lfs_mkdir(&lfs, "////milk") => 0; - lfs_stat(&lfs, "////milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_stat(&lfs, "milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); + lfs_stat(&lfs, "//////coffee//////drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/////coffee/////coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "////coffee////turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "///coffee///tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "//coffee//vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "//coffee//coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "///coffee///turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "////coffee////tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/////coffee/////vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "//////coffee//////thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "//coffee//coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "///coffee///turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "////coffee////tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/////coffee/////vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "//////coffee//////thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "//////coffee//////drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "/////coffee/////coldbrew", + "//espresso//americano") => 0; + lfs_rename(&lfs, + "////coffee////turkish", + "///espresso///macchiato") => 0; + lfs_rename(&lfs, + "///coffee///tubruk", + "////espresso////latte") => 0; + lfs_rename(&lfs, + "//coffee//vietnamese", + "/////espresso/////cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "//////espresso//////mocha") => 0; + + // stat paths + lfs_stat(&lfs, "//////espresso//////espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/////espresso/////americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "////espresso////macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "///espresso///latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "//espresso//cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "//////coffee//////drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/////coffee/////coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "////coffee////turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "///coffee///tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "//coffee//vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "//espresso//americano") => 0; + lfs_remove(&lfs, "///espresso///macchiato") => 0; + lfs_remove(&lfs, "////espresso////latte") => 0; + lfs_remove(&lfs, "/////espresso/////cappuccino") => 0; + lfs_remove(&lfs, "//////espresso//////mocha") => 0; + + // stat paths + lfs_stat(&lfs, "//////espresso//////espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/////espresso/////americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "////espresso////macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "///espresso///latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "//espresso//cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' -# dot path test -[cases.test_paths_dot] +# TODO test trailing slashes + +# dot path tests +[cases.test_paths_dots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "/./coffee/./coldbrew") => 0; + lfs_mkdir(&lfs, "/././coffee/././turkish") => 0; + lfs_mkdir(&lfs, "/./././coffee/./././tubruk") => 0; + lfs_mkdir(&lfs, "/././././coffee/././././vietnamese") => 0; + lfs_mkdir(&lfs, "/./././././coffee/./././././thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "./tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/./tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/././tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/./tea/./hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - - lfs_mkdir(&lfs, "/./milk") => 0; - lfs_stat(&lfs, "/./milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_stat(&lfs, "milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); + lfs_stat(&lfs, "/./././././coffee/./././././drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././././coffee/././././coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./././coffee/./././turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././coffee/././tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./coffee/./vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/./coffee/./coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/././coffee/././turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/./././coffee/./././tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/././././coffee/././././vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/./././././coffee/./././././thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/./coffee/./coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/././coffee/././turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/./././coffee/./././tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/././././coffee/././././vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/./././././coffee/./././././thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/./././././coffee/./././././drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "/././././coffee/././././coldbrew", + "/./espresso/./americano") => 0; + lfs_rename(&lfs, + "/./././coffee/./././turkish", + "/././espresso/././macchiato") => 0; + lfs_rename(&lfs, + "/././coffee/././tubruk", + "/./././espresso/./././latte") => 0; + lfs_rename(&lfs, + "/./coffee/./vietnamese", + "/././././espresso/././././cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "/./././././espresso/./././././mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/./././././espresso/./././././espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././././espresso/././././americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./././espresso/./././macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././espresso/././latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./espresso/./cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/./././././coffee/./././././drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././././coffee/././././coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./././coffee/./././turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././coffee/././tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./coffee/./vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "/./espresso/./americano") => 0; + lfs_remove(&lfs, "/././espresso/././macchiato") => 0; + lfs_remove(&lfs, "/./././espresso/./././latte") => 0; + lfs_remove(&lfs, "/././././espresso/././././cappuccino") => 0; + lfs_remove(&lfs, "/./././././espresso/./././././mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/./././././espresso/./././././espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././././espresso/././././americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./././espresso/./././macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././espresso/././latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./espresso/./cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' -# dot dot path test -[cases.test_paths_dot_dot] +# TODO test trailing dots + +# dot dot path tests +[cases.test_paths_dotdots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + + // create paths + lfs_mkdir(&lfs, "no") => 0; + lfs_mkdir(&lfs, "no/no") => 0; lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + lfs_mkdir(&lfs, "coffee/no") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "/no/../coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/no/../turkish") => 0; + lfs_mkdir(&lfs, "/no/no/../../coffee/tubruk") => 0; + lfs_mkdir(&lfs, "/no/no/../../coffee/no/../vietnamese") => 0; + lfs_mkdir(&lfs, "/no/no/../../no/no/../../coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + // stat paths struct lfs_info info; - lfs_stat(&lfs, "coffee/../tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/coldtea/../hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "coffee/coldcoffee/../../tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "coffee/../coffee/../tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - - lfs_mkdir(&lfs, "coffee/../milk") => 0; - lfs_stat(&lfs, "coffee/../milk", &info) => 0; - strcmp(info.name, "milk") => 0; - lfs_stat(&lfs, "milk", &info) => 0; - strcmp(info.name, "milk") => 0; + lfs_stat(&lfs, "/no/no/../../no/no/../../coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../coffee/no/../coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/no/../tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/no/../turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/no/../vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/../../no/no/../../coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/no/../turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/no/../vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/../../no/no/../../coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/no/no/../../no/no/../../coffee/drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "/no/no/../../coffee/no/../coldbrew", + "/no/../espresso/americano") => 0; + lfs_rename(&lfs, + "/no/no/../../coffee/turkish", + "/espresso/no/../macchiato") => 0; + lfs_rename(&lfs, + "/coffee/no/../tubruk", + "/no/no/../../espresso/latte") => 0; + lfs_rename(&lfs, + "/no/../coffee/vietnamese", + "/no/no/../../espresso/no/../cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "/no/no/../../no/no/../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/no/../../no/no/../../espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../espresso/no/../americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/no/../latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/no/no/../../no/no/../../coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../coffee/no/../coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/no/../tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "/no/../espresso/americano") => 0; + lfs_remove(&lfs, "/espresso/no/../macchiato") => 0; + lfs_remove(&lfs, "/no/no/../../espresso/latte") => 0; + lfs_remove(&lfs, "/no/no/../../espresso/no/../cappuccino") => 0; + lfs_remove(&lfs, "/no/no/../../no/no/../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/no/../../no/no/../../espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../espresso/no/../americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/no/../latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' -# trailing dot path test -[cases.test_paths_trailing_dot] +# TODO test trailing dotdots + +# dot dot dot path tests +[cases.test_paths_dotdotdots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + lfs_mkdir(&lfs, "coffee/...") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/.../drip") => 0; + lfs_mkdir(&lfs, "/coffee/.../coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/.../turkish") => 0; + lfs_mkdir(&lfs, "/coffee/.../tubruk") => 0; + lfs_mkdir(&lfs, "/coffee/.../vietnamese") => 0; + lfs_mkdir(&lfs, "/coffee/.../thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "tea/hottea/", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/hottea/.", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/hottea/./.", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/hottea/..", &info) => 0; - assert(strcmp(info.name, "tea") == 0); - lfs_stat(&lfs, "tea/hottea/../.", &info) => 0; - assert(strcmp(info.name, "tea") == 0); + lfs_stat(&lfs, "/coffee/.../drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.../drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.../drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_mkdir(&lfs, "espresso/...") => 0; + lfs_rename(&lfs, + "/coffee/.../drip", + "/espresso/.../espresso") => 0; + lfs_rename(&lfs, + "/coffee/.../coldbrew", + "/espresso/.../americano") => 0; + lfs_rename(&lfs, + "/coffee/.../turkish", + "/espresso/.../macchiato") => 0; + lfs_rename(&lfs, + "/coffee/.../tubruk", + "/espresso/.../latte") => 0; + lfs_rename(&lfs, + "/coffee/.../vietnamese", + "/espresso/.../cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/.../thai", + "/espresso/.../mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.../espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/.../drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/.../espresso") => 0; + lfs_remove(&lfs, "/espresso/.../americano") => 0; + lfs_remove(&lfs, "/espresso/.../macchiato") => 0; + lfs_remove(&lfs, "/espresso/.../latte") => 0; + lfs_remove(&lfs, "/espresso/.../cappuccino") => 0; + lfs_remove(&lfs, "/espresso/.../mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.../espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' # leading dot path test -[cases.test_paths_leading_dot] +[cases.test_paths_leading_dots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, ".milk") => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/.drip") => 0; + lfs_mkdir(&lfs, "/coffee/..coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/...turkish") => 0; + lfs_mkdir(&lfs, "/coffee/....tubruk") => 0; + lfs_mkdir(&lfs, "/coffee/.....vietnamese") => 0; + lfs_mkdir(&lfs, "/coffee/......thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, ".milk", &info) => 0; - strcmp(info.name, ".milk") => 0; - lfs_stat(&lfs, "tea/.././.milk", &info) => 0; - strcmp(info.name, ".milk") => 0; + lfs_stat(&lfs, "/coffee/.drip", &info) => 0; + assert(strcmp(info.name, ".drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/..coldbrew", &info) => 0; + assert(strcmp(info.name, "..coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/...turkish", &info) => 0; + assert(strcmp(info.name, "...turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/....tubruk", &info) => 0; + assert(strcmp(info.name, "....tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.....vietnamese", &info) => 0; + assert(strcmp(info.name, ".....vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/......thai", &info) => 0; + assert(strcmp(info.name, "......thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/..coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/...turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/....tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.....vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/......thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/..coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/...turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/....tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.....vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/......thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/coffee/.drip", + "/espresso/.espresso") => 0; + lfs_rename(&lfs, + "/coffee/..coldbrew", + "/espresso/..americano") => 0; + lfs_rename(&lfs, + "/coffee/...turkish", + "/espresso/...macchiato") => 0; + lfs_rename(&lfs, + "/coffee/....tubruk", + "/espresso/....latte") => 0; + lfs_rename(&lfs, + "/coffee/.....vietnamese", + "/espresso/.....cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/......thai", + "/espresso/......mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.espresso", &info) => 0; + assert(strcmp(info.name, ".espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/..americano", &info) => 0; + assert(strcmp(info.name, "..americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/...macchiato", &info) => 0; + assert(strcmp(info.name, "...macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/....latte", &info) => 0; + assert(strcmp(info.name, "....latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.....cappuccino", &info) => 0; + assert(strcmp(info.name, ".....cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/......mocha", &info) => 0; + assert(strcmp(info.name, "......mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/.drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/..coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/...turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/....tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.....vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/......thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/.espresso") => 0; + lfs_remove(&lfs, "/espresso/..americano") => 0; + lfs_remove(&lfs, "/espresso/...macchiato") => 0; + lfs_remove(&lfs, "/espresso/....latte") => 0; + lfs_remove(&lfs, "/espresso/.....cappuccino") => 0; + lfs_remove(&lfs, "/espresso/......mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/..americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/...macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/....latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.....cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/......mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' # root dot dot path test -[cases.test_paths_root_dot_dot] +[cases.test_paths_root_dotdots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + + // create paths + lfs_mkdir(&lfs, "no") => 0; lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/../coffee/drip") => 0; + lfs_mkdir(&lfs, "/../../coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "/../../../coffee/turkish") => 0; + lfs_mkdir(&lfs, "/no/../../coffee/tubruk") => 0; + lfs_mkdir(&lfs, "/no/../../../coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "/no/../../../../coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + // stat paths struct lfs_info info; - lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0; - strcmp(info.name, "hottea") => 0; - - lfs_mkdir(&lfs, "coffee/../../../../../../milk") => 0; - lfs_stat(&lfs, "coffee/../../../../../../milk", &info) => 0; - strcmp(info.name, "milk") => 0; - lfs_stat(&lfs, "milk", &info) => 0; - strcmp(info.name, "milk") => 0; + lfs_stat(&lfs, "/no/../../../../coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../../coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../../coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/../coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/../../coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/../../../coffee/turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../../coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../../../coffee/vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../../../../coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/../coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/../../coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/../../../coffee/turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../../coffee/vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../../../coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/no/../../../../coffee/drip", + "/../espresso/espresso") => 0; + lfs_rename(&lfs, + "/no/../../../coffee/coldbrew", + "/../../espresso/americano") => 0; + lfs_rename(&lfs, + "/no/../../coffee/turkish", + "/../../../espresso/macchiato") => 0; + lfs_rename(&lfs, + "/../../../coffee/tubruk", + "/no/../../espresso/latte") => 0; + lfs_rename(&lfs, + "/../../coffee/vietnamese", + "/no/../../../espresso/cappuccino") => 0; + lfs_rename(&lfs, + "/../coffee/thai", + "/no/../../../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/../../../../espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../../espresso/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../../espresso/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/no/../../../../coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../../coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../../coffee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/../espresso/espresso") => 0; + lfs_remove(&lfs, "/../../espresso/americano") => 0; + lfs_remove(&lfs, "/../../../espresso/macchiato") => 0; + lfs_remove(&lfs, "/no/../../espresso/latte") => 0; + lfs_remove(&lfs, "/no/../../../espresso/cappuccino") => 0; + lfs_remove(&lfs, "/no/../../../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/../../../../espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../../espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../../espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../espresso/mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' -# invalid path tests -[cases.test_paths_invalid] +# trailing noent tests +[cases.test_paths_noent] +defines.DIR = [false, true] code = ''' lfs_t lfs; - lfs_format(&lfs, cfg); + lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "dirt", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "dirt/ground", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "dirt/ground/earth", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/_rip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/c_ldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tu_kish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tub_uk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/_vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai_", &info) => LFS_ERR_NOENT; - lfs_remove(&lfs, "dirt") => LFS_ERR_NOENT; - lfs_remove(&lfs, "dirt/ground") => LFS_ERR_NOENT; - lfs_remove(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT; + // file open paths, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/_rip", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tu_kish", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tub_uk", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/_vietnamese", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai_", + LFS_O_RDONLY) => LFS_ERR_NOENT; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/_rip") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/c_ldbrew") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tu_kish") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tub_uk") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/_vietnamese") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/thai_") => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "coffee/_rip", + "espresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew", + "espresso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish", + "espresso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk", + "espresso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese", + "espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_", + "espresso/mocha") => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "coffee/_rip") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/c_ldbrew") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tu_kish") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tub_uk") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/_vietnamese") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/thai_") => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' + +# parent noent tests +[cases.test_paths_noent_parent] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "dirt/ground") => LFS_ERR_NOENT; + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "_offee/drip") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "co_fee/turkish") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee_/thai") => LFS_ERR_NOENT; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "_offee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "c_ffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "co_fee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "cof_ee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee_/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + } + + // ok, actually create paths + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "_offee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c_ffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "co_fee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "cof_ee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "_coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee_/thai", &info) => LFS_ERR_NOENT; + + // file open paths, only works on files! lfs_file_t file; - lfs_file_open(&lfs, &file, "dirt/ground", LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT; - lfs_file_open(&lfs, &file, "dirt/ground/earth", LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_offee/drip", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "c_ffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "co_fee/turkish", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "cof_ee/tubruk", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee_/thai", + LFS_O_RDONLY) => LFS_ERR_NOENT; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "_offee/drip") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "co_fee/turkish") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee_/thai") => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "_offee/drip", + "espresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "c_ffee/coldbrew", + "espresso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "co_fee/turkish", + "espresso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "cof_ee/tubruk", + "espresso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "_coffee/vietnamese", + "espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee_/thai", + "espresso/mocha") => LFS_ERR_NOENT; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "_spresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/coldbrew", + "e_presso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/turkish", + "es_resso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tubruk", + "esp_esso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/vietnamese", + "_espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai", + "espresso_/mocha") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "_offee/drip", + "_spresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "c_ffee/coldbrew", + "e_presso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "co_fee/turkish", + "es_resso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "cof_ee/tubruk", + "esp_esso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "_coffee/vietnamese", + "_espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee_/thai", + "espresso_/mocha") => LFS_ERR_NOENT; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "_offee/drip", + "_offee/drip") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "c_ffee/coldbrew", + "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "co_fee/turkish", + "co_fee/turkish") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "cof_ee/tubruk", + "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "_coffee/vietnamese", + "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee_/thai", + "coffee_/thai") => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "_offee/drip") => LFS_ERR_NOENT; + lfs_remove(&lfs, "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_remove(&lfs, "co_fee/turkish") => LFS_ERR_NOENT; + lfs_remove(&lfs, "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_remove(&lfs, "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee_/thai") => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' + +# parent notdir tests +[cases.test_paths_notdir_parent] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_file_t file; + lfs_file_open(&lfs, &file, "drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + + if (DIR) { + lfs_mkdir(&lfs, "drip/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "coldbrew/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "turkish/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "tubruk/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "vietnamese/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "thai/coffee") => LFS_ERR_NOTDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "drip/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coldbrew/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "turkish/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "tubruk/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "vietnamese/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "thai/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "drip/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coldbrew/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "turkish/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "tubruk/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "vietnamese/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "thai/coffee", &info) => LFS_ERR_NOTDIR; + + // file open paths, only works on files! + lfs_file_open(&lfs, &file, "drip/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coldbrew/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "turkish/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "tubruk/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "vietnamese/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "thai/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "drip/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coldbrew/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "turkish/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "tubruk/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "vietnamese/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "thai/coffee") => LFS_ERR_NOTDIR; + + // make some normal paths so we have something to rename + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "drip/coffee", + "espresso/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coldbrew/coffee", + "espresso/americano") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "turkish/coffee", + "espresso/macchiato") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "tubruk/coffee", + "espresso/latte") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "vietnamese/coffee", + "espresso/cappuccino") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "thai/coffee", + "espresso/mocha") => LFS_ERR_NOTDIR; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "drip/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew", + "coldbrew/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish", + "turkish/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk", + "tubruk/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese", + "vietnamese/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai", + "thai/espresso") => LFS_ERR_NOTDIR; + + // bad source and bad destination + lfs_rename(&lfs, + "drip/coffee", + "drip/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coldbrew/coffee", + "coldbrew/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "turkish/coffee", + "turkish/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "tubruk/coffee", + "tubruk/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "vietnamese/coffee", + "vietnamese/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "thai/coffee", + "thai/espresso") => LFS_ERR_NOTDIR; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "drip/coffee", + "drip/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coldbrew/coffee", + "coldbrew/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "turkish/coffee", + "turkish/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "tubruk/coffee", + "tubruk/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "vietnamese/coffee", + "vietnamese/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "thai/coffee", + "thai/coffee") => LFS_ERR_NOTDIR; + + // remove paths + lfs_stat(&lfs, "drip/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coldbrew/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "turkish/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "tubruk/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "vietnamese/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "thai/espresso", &info) => LFS_ERR_NOTDIR; + + // stat paths + lfs_stat(&lfs, "drip/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coldbrew/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "turkish/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "tubruk/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "vietnamese/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "thai/espresso", &info) => LFS_ERR_NOTDIR; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_unmount(&lfs) => 0; ''' # root operations [cases.test_paths_root] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; struct lfs_info info; + + // create root, this should error + if (DIR) { + lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + } + + // stat root lfs_stat(&lfs, "/", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; + // file open root, only works on files! lfs_file_t file; - lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + + // dir open root, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/") => 0; + lfs_dir_close(&lfs, &dir) => 0; + + // rename root, this should error + lfs_rename(&lfs, "/", "coffee") => LFS_ERR_INVAL; + + lfs_mkdir(&lfs, "coffee") => 0; + lfs_rename(&lfs, "coffee", "/") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee") => 0; + + lfs_rename(&lfs, "/", "/") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + // remove root, this should error lfs_remove(&lfs, "/") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_unmount(&lfs) => 0; ''' -# root representations -[cases.test_paths_root_reprs] +# other root representations +[cases.test_paths_root_aliases] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; struct lfs_info info; + + // create root, this should error + if (DIR) { + lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, ".") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "./") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "/.") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "//") => LFS_ERR_EXIST; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, ".", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "./", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + } + + // stat root lfs_stat(&lfs, "/", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); @@ -244,93 +2214,2127 @@ code = ''' lfs_stat(&lfs, "..", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "./", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "/.", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, "//", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); + + // file open root, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "/", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, ".", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "./", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + + // dir open root, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, ".") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "./") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "//") => 0; + lfs_dir_close(&lfs, &dir) => 0; + + // rename root, this should error + lfs_rename(&lfs, "/", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, ".", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "..", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "./", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "/.", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "//", "coffee") => LFS_ERR_INVAL; + + lfs_mkdir(&lfs, "coffee") => 0; + lfs_rename(&lfs, "coffee", "/") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", ".") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "..") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "./") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "/.") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "//") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee") => 0; + + lfs_rename(&lfs, "/", "/") => LFS_ERR_INVAL; + lfs_rename(&lfs, "", "") => LFS_ERR_INVAL; + lfs_rename(&lfs, ".", ".") => LFS_ERR_INVAL; + lfs_rename(&lfs, "..", "..") => LFS_ERR_INVAL; + lfs_rename(&lfs, "./", "./") => LFS_ERR_INVAL; + lfs_rename(&lfs, "/.", "/.") => LFS_ERR_INVAL; + lfs_rename(&lfs, "//", "//") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, ".", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, "./", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "/.", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "//", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + + // remove root, this should error + lfs_remove(&lfs, "/") => LFS_ERR_INVAL; + lfs_remove(&lfs, "") => LFS_ERR_INVAL; + lfs_remove(&lfs, ".") => LFS_ERR_INVAL; + lfs_remove(&lfs, "..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "./") => LFS_ERR_INVAL; + lfs_remove(&lfs, "/.") => LFS_ERR_INVAL; + lfs_remove(&lfs, "//") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, ".", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "./", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "/.", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "//", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_unmount(&lfs) => 0; ''' -# superblock conflict test -[cases.test_paths_superblock_conflict] +# superblock magic shouldn't appear as a file +[cases.test_paths_magic_noent] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; + + // stat littlefs, which shouldn't exist struct lfs_info info; lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT; + + // dir open littlefs, which shouldn't exist + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "littlefs") => LFS_ERR_NOENT; + + // rename littlefs, which shouldn't exist + lfs_rename(&lfs, "littlefs", "coffee") => LFS_ERR_NOENT; + + // remove littlefs, which shouldn't exist lfs_remove(&lfs, "littlefs") => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "littlefs") => 0; + // stat littlefs, which shouldn't exist + lfs_stat(&lfs, "coffee", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# superblock magic shouldn't conflict with files, that would be silly +[cases.test_paths_magic_conflict] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create littlefs + if (DIR) { + lfs_mkdir(&lfs, "littlefs") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat littlefs + struct lfs_info info; lfs_stat(&lfs, "littlefs", &info) => 0; assert(strcmp(info.name, "littlefs") == 0); - assert(info.type == LFS_TYPE_DIR); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open littlefs, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open littlefs, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "littlefs") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "littlefs") => LFS_ERR_NOTDIR; + } + + // rename littlefs + lfs_rename(&lfs, "littlefs", "coffee") => 0; + lfs_rename(&lfs, "coffee", "littlefs") => 0; + + // stat littlefs + lfs_stat(&lfs, "littlefs", &info) => 0; + assert(strcmp(info.name, "littlefs") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee", &info) => LFS_ERR_NOENT; + + // remove littlefs lfs_remove(&lfs, "littlefs") => 0; + + // stat littlefs lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' -# max path test -[cases.test_paths_max] +# test name too long +[cases.test_paths_nametoolong] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + char a_name[512]; + memset(a_name, 'a', LFS_NAME_MAX+1); + a_name[LFS_NAME_MAX+1] = '\0'; + + // create names that are too long, should error char path[1024]; - memset(path, 'w', LFS_NAME_MAX+1); - path[LFS_NAME_MAX+1] = '\0'; - lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG; + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + sprintf(path, "coffee/%s", a_name); + lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG; + } else { + lfs_file_t file; + sprintf(path, "coffee/%s", a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NAMETOOLONG; + } + + // stat paths + struct lfs_info info; + sprintf(path, "coffee/%s", a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + + // file open paths, only works on files! lfs_file_t file; - lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NAMETOOLONG; - - memcpy(path, "coffee/", strlen("coffee/")); - memset(path+strlen("coffee/"), 'w', LFS_NAME_MAX+1); - path[strlen("coffee/")+LFS_NAME_MAX+1] = '\0'; - lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG; - lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NAMETOOLONG; + sprintf(path, "coffee/%s", a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_NOENT; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + sprintf(path, "coffee/%s", a_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + sprintf(path, "coffee/%s", a_name); + lfs_rename(&lfs, path, "espresso/espresso") => LFS_ERR_NOENT; + + // renaming with too long a destination is tricky! + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + sprintf(path, "espresso/%s", a_name); + lfs_rename(&lfs, "coffee/drip", path) => LFS_ERR_NAMETOOLONG; + + // stat paths + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + sprintf(path, "espresso/%s", a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + + // remove paths + sprintf(path, "espresso/%s", a_name); + lfs_remove(&lfs, path) => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + sprintf(path, "espresso/%s", a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' -# really big path test -[cases.test_paths_really_big] +# test name really long but not too long +[cases.test_paths_namejustlongenough] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + char a_name[512]; + memset(a_name, 'a', LFS_NAME_MAX); + a_name[LFS_NAME_MAX] = '\0'; + char b_name[512]; + memset(b_name, 'b', LFS_NAME_MAX); + b_name[LFS_NAME_MAX] = '\0'; + char c_name[512]; + memset(c_name, 'c', LFS_NAME_MAX); + c_name[LFS_NAME_MAX] = '\0'; + char d_name[512]; + memset(d_name, 'd', LFS_NAME_MAX); + d_name[LFS_NAME_MAX] = '\0'; + char e_name[512]; + memset(e_name, 'e', LFS_NAME_MAX); + e_name[LFS_NAME_MAX] = '\0'; + char f_name[512]; + memset(f_name, 'f', LFS_NAME_MAX); + f_name[LFS_NAME_MAX] = '\0'; + char g_name[512]; + memset(g_name, 'g', LFS_NAME_MAX); + g_name[LFS_NAME_MAX] = '\0'; + char h_name[512]; + memset(h_name, 'h', LFS_NAME_MAX); + h_name[LFS_NAME_MAX] = '\0'; + char i_name[512]; + memset(i_name, 'i', LFS_NAME_MAX); + i_name[LFS_NAME_MAX] = '\0'; + char j_name[512]; + memset(j_name, 'j', LFS_NAME_MAX); + j_name[LFS_NAME_MAX] = '\0'; + char k_name[512]; + memset(k_name, 'k', LFS_NAME_MAX); + k_name[LFS_NAME_MAX] = '\0'; + char l_name[512]; + memset(l_name, 'l', LFS_NAME_MAX); + l_name[LFS_NAME_MAX] = '\0'; + + // create names that aren't too long + lfs_mkdir(&lfs, c_name) => 0; char path[1024]; - memset(path, 'w', LFS_NAME_MAX); - path[LFS_NAME_MAX] = '\0'; - lfs_mkdir(&lfs, path) => 0; + if (DIR) { + sprintf(path, "%s/%s", c_name, a_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_mkdir(&lfs, path) => 0; + } else { + lfs_file_t file; + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + sprintf(path, "%s/%s", c_name, a_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, a_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, b_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, b_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, c_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, c_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, d_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, d_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, e_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, e_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, f_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, f_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + sprintf(path, "%s/%s", c_name, a_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + sprintf(path, "%s/%s", c_name, a_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, b_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, c_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, d_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, e_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, f_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, e_name) => 0; + char path_[1024]; + sprintf(path, "%s/%s", c_name, a_name); + sprintf(path_, "%s/%s", e_name, g_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, b_name); + sprintf(path_, "%s/%s", e_name, h_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, c_name); + sprintf(path_, "%s/%s", e_name, i_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, d_name); + sprintf(path_, "%s/%s", e_name, j_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, e_name); + sprintf(path_, "%s/%s", e_name, k_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, f_name); + sprintf(path_, "%s/%s", e_name, l_name); + lfs_rename(&lfs, path, path_) => 0; + + // stat paths + sprintf(path, "%s/%s", e_name, g_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, g_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, h_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, h_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, i_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, i_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, j_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, j_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, k_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, k_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, l_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, l_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + sprintf(path, "%s/%s", c_name, a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, b_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, c_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, d_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, e_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, f_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + + // remove paths + sprintf(path, "%s/%s", e_name, g_name); lfs_remove(&lfs, path) => 0; - lfs_file_t file; - lfs_file_open(&lfs, &file, path, - LFS_O_WRONLY | LFS_O_CREAT) => 0; - lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", e_name, h_name); lfs_remove(&lfs, path) => 0; - - memcpy(path, "coffee/", strlen("coffee/")); - memset(path+strlen("coffee/"), 'w', LFS_NAME_MAX); - path[strlen("coffee/")+LFS_NAME_MAX] = '\0'; - lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", e_name, i_name); lfs_remove(&lfs, path) => 0; - lfs_file_open(&lfs, &file, path, - LFS_O_WRONLY | LFS_O_CREAT) => 0; - lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", e_name, j_name); lfs_remove(&lfs, path) => 0; + sprintf(path, "%s/%s", e_name, k_name); + lfs_remove(&lfs, path) => 0; + sprintf(path, "%s/%s", e_name, l_name); + lfs_remove(&lfs, path) => 0; + + // stat paths + sprintf(path, "%s/%s", e_name, g_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, h_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, i_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, j_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, k_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, l_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# a quick utf8 test, though utf8 is easy to support +[cases.test_paths_utf8] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/dripcoffee") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/türkkahvesi") => 0; + lfs_mkdir(&lfs, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") => 0; + lfs_mkdir(&lfs, "coffee/càphêđá") => 0; + lfs_mkdir(&lfs, "coffee/โอเลี้ยง") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "coffee/dripcoffee", &info) => 0; + assert(strcmp(info.name, "dripcoffee") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/türkkahvesi", &info) => 0; + assert(strcmp(info.name, "türkkahvesi") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", &info) => 0; + assert(strcmp(info.name, "ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/càphêđá", &info) => 0; + assert(strcmp(info.name, "càphêđá") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/โอเลี้ยง", &info) => 0; + assert(strcmp(info.name, "โอเลี้ยง") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/dripcoffee") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/türkkahvesi") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/càphêđá") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/โอเลี้ยง") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/dripcoffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/türkkahvesi") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/càphêđá") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/โอเลี้ยง") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "caffè") => 0; + lfs_rename(&lfs, + "coffee/dripcoffee", + "caffè/espresso") => 0; + lfs_rename(&lfs, + "coffee/coldbrew", + "caffè/americano") => 0; + lfs_rename(&lfs, + "coffee/türkkahvesi", + "caffè/macchiato") => 0; + lfs_rename(&lfs, + "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + "caffè/latte") => 0; + lfs_rename(&lfs, + "coffee/càphêđá", + "caffè/cappuccino") => 0; + lfs_rename(&lfs, + "coffee/โอเลี้ยง", + "caffè/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "caffè/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/dripcoffee", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/türkkahvesi", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/càphêđá", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/โอเลี้ยง", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "caffè/espresso") => 0; + lfs_remove(&lfs, "caffè/americano") => 0; + lfs_remove(&lfs, "caffè/macchiato") => 0; + lfs_remove(&lfs, "caffè/latte") => 0; + lfs_remove(&lfs, "caffè/cappuccino") => 0; + lfs_remove(&lfs, "caffè/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "caffè/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/mocha", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# more utf8 tests +[cases.test_paths_utf8_ipa] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "ˈkɔ.fi") => 0; + if (DIR) { + lfs_mkdir(&lfs, "ˈkɔ.fi/dɹɪpˈkɔ.fi") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/koʊldbɹuː") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/tyɾckɑhvɛˈsi") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "ˈkɔ.fi/dɹɪpˈkɔ.fi", &info) => 0; + assert(strcmp(info.name, "dɹɪpˈkɔ.fi") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/koʊldbɹuː", &info) => 0; + assert(strcmp(info.name, "koʊldbɹuː") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/tyɾckɑhvɛˈsi", &info) => 0; + assert(strcmp(info.name, "tyɾckɑhvɛˈsi") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", &info) => 0; + assert(strcmp(info.name, "ˈko.piˈt̪up̚.rʊk̚") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", &info) => 0; + assert(strcmp(info.name, "kaː˨˩fe˧˧ɗaː˧˥") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", &info) => 0; + assert(strcmp(info.name, "ʔoː˧.lia̯ŋ˦˥") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/dɹɪpˈkɔ.fi") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/koʊldbɹuː") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/tyɾckɑhvɛˈsi") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/dɹɪpˈkɔ.fi") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/koʊldbɹuː") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/tyɾckɑhvɛˈsi") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "kafˈfɛ") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/dɹɪpˈkɔ.fi", + "kafˈfɛ/eˈsprɛsso") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/koʊldbɹuː", + "kafˈfɛ/ameriˈkano") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/tyɾckɑhvɛˈsi", + "kafˈfɛ/makˈkjato") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + "kafˈfɛ/ˈlat.te") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + "kafˈfɛ/kapputˈt͡ʃino") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + "kafˈfɛ/ˈmoʊkə") => 0; + + // stat paths + lfs_stat(&lfs, "kafˈfɛ/eˈsprɛsso", &info) => 0; + assert(strcmp(info.name, "eˈsprɛsso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/ameriˈkano", &info) => 0; + assert(strcmp(info.name, "ameriˈkano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/makˈkjato", &info) => 0; + assert(strcmp(info.name, "makˈkjato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/ˈlat.te", &info) => 0; + assert(strcmp(info.name, "ˈlat.te") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/kapputˈt͡ʃino", &info) => 0; + assert(strcmp(info.name, "kapputˈt͡ʃino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/ˈmoʊkə", &info) => 0; + assert(strcmp(info.name, "ˈmoʊkə") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "ˈkɔ.fi/dɹɪpˈkɔ.fi", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/koʊldbɹuː", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/tyɾckɑhvɛˈsi", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "kafˈfɛ/eˈsprɛsso") => 0; + lfs_remove(&lfs, "kafˈfɛ/ameriˈkano") => 0; + lfs_remove(&lfs, "kafˈfɛ/makˈkjato") => 0; + lfs_remove(&lfs, "kafˈfɛ/ˈlat.te") => 0; + lfs_remove(&lfs, "kafˈfɛ/kapputˈt͡ʃino") => 0; + lfs_remove(&lfs, "kafˈfɛ/ˈmoʊkə") => 0; + + // stat paths + lfs_stat(&lfs, "kafˈfɛ/eˈsprɛsso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/ameriˈkano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/makˈkjato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/ˈlat.te", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/kapputˈt͡ʃino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/ˈmoʊkə", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test spaces have no problems +[cases.test_paths_spaces] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "c o f f e e") => 0; + if (DIR) { + lfs_mkdir(&lfs, "c o f f e e/d r i p") => 0; + lfs_mkdir(&lfs, "c o f f e e/c o l d b r e w") => 0; + lfs_mkdir(&lfs, "c o f f e e/t u r k i s h") => 0; + lfs_mkdir(&lfs, "c o f f e e/t u b r u k") => 0; + lfs_mkdir(&lfs, "c o f f e e/v i e t n a m e s e") => 0; + lfs_mkdir(&lfs, "c o f f e e/t h a i") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "c o f f e e/d r i p", &info) => 0; + assert(strcmp(info.name, "d r i p") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/c o l d b r e w", &info) => 0; + assert(strcmp(info.name, "c o l d b r e w") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/t u r k i s h", &info) => 0; + assert(strcmp(info.name, "t u r k i s h") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/t u b r u k", &info) => 0; + assert(strcmp(info.name, "t u b r u k") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/v i e t n a m e s e", &info) => 0; + assert(strcmp(info.name, "v i e t n a m e s e") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/t h a i", &info) => 0; + assert(strcmp(info.name, "t h a i") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "c o f f e e/d r i p") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/c o l d b r e w") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u r k i s h") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u b r u k") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/v i e t n a m e s e") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/t h a i") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "c o f f e e/d r i p") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/c o l d b r e w") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u r k i s h") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u b r u k") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/v i e t n a m e s e") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/t h a i") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "e s p r e s s o") => 0; + lfs_rename(&lfs, + "c o f f e e/d r i p", + "e s p r e s s o/e s p r e s s o") => 0; + lfs_rename(&lfs, + "c o f f e e/c o l d b r e w", + "e s p r e s s o/a m e r i c a n o") => 0; + lfs_rename(&lfs, + "c o f f e e/t u r k i s h", + "e s p r e s s o/m a c c h i a t o") => 0; + lfs_rename(&lfs, + "c o f f e e/t u b r u k", + "e s p r e s s o/l a t t e") => 0; + lfs_rename(&lfs, + "c o f f e e/v i e t n a m e s e", + "e s p r e s s o/c a p p u c c i n o") => 0; + lfs_rename(&lfs, + "c o f f e e/t h a i", + "e s p r e s s o/m o c h a") => 0; + + // stat paths + lfs_stat(&lfs, "e s p r e s s o/e s p r e s s o", &info) => 0; + assert(strcmp(info.name, "e s p r e s s o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/a m e r i c a n o", &info) => 0; + assert(strcmp(info.name, "a m e r i c a n o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/m a c c h i a t o", &info) => 0; + assert(strcmp(info.name, "m a c c h i a t o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/l a t t e", &info) => 0; + assert(strcmp(info.name, "l a t t e") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/c a p p u c c i n o", &info) => 0; + assert(strcmp(info.name, "c a p p u c c i n o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/m o c h a", &info) => 0; + assert(strcmp(info.name, "m o c h a") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "c o f f e e/d r i p", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/c o l d b r e w", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/t u r k i s h", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/t u b r u k", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/v i e t n a m e s e", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/t h a i", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "e s p r e s s o/e s p r e s s o") => 0; + lfs_remove(&lfs, "e s p r e s s o/a m e r i c a n o") => 0; + lfs_remove(&lfs, "e s p r e s s o/m a c c h i a t o") => 0; + lfs_remove(&lfs, "e s p r e s s o/l a t t e") => 0; + lfs_remove(&lfs, "e s p r e s s o/c a p p u c c i n o") => 0; + lfs_remove(&lfs, "e s p r e s s o/m o c h a") => 0; + + // stat paths + lfs_stat(&lfs, "e s p r e s s o/e s p r e s s o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/a m e r i c a n o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/m a c c h i a t o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/l a t t e", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/c a p p u c c i n o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/m o c h a", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with only spaces +# +# please don't do this +[cases.test_paths_oopsallspaces] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, " ") => 0; + if (DIR) { + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, " ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + + // stat paths + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + + // stat paths + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with only ascii control characters +# +# littlefs only cares about "./" and NULL +[cases.test_paths_nonprintable] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\x0c") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\x0c/\x01") => 0; + lfs_mkdir(&lfs, "\x0c/\x02") => 0; + lfs_mkdir(&lfs, "\x0c/\x03") => 0; + lfs_mkdir(&lfs, "\x0c/\x04") => 0; + lfs_mkdir(&lfs, "\x0c/\x05") => 0; + lfs_mkdir(&lfs, "\x0c/\x06") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\x0c/\x01", &info) => 0; + assert(strcmp(info.name, "\x01") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x02", &info) => 0; + assert(strcmp(info.name, "\x02") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x03", &info) => 0; + assert(strcmp(info.name, "\x03") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x04", &info) => 0; + assert(strcmp(info.name, "\x04") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x05", &info) => 0; + assert(strcmp(info.name, "\x05") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x06", &info) => 0; + assert(strcmp(info.name, "\x06") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x0c/\x01") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x02") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x03") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x04") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x05") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x06") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x0c/\x01") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x02") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x03") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x04") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x05") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x06") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\x0e") => 0; + lfs_rename(&lfs, + "\x0c/\x01", + "\x0e/\x1a") => 0; + lfs_rename(&lfs, + "\x0c/\x02", + "\x0e/\x1b") => 0; + lfs_rename(&lfs, + "\x0c/\x03", + "\x0e/\x1c") => 0; + lfs_rename(&lfs, + "\x0c/\x04", + "\x0e/\x1d") => 0; + lfs_rename(&lfs, + "\x0c/\x05", + "\x0e/\x1e") => 0; + lfs_rename(&lfs, + "\x0c/\x06", + "\x0e/\x1f") => 0; + + // stat paths + lfs_stat(&lfs, "\x0e/\x1a", &info) => 0; + assert(strcmp(info.name, "\x1a") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1b", &info) => 0; + assert(strcmp(info.name, "\x1b") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1c", &info) => 0; + assert(strcmp(info.name, "\x1c") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1d", &info) => 0; + assert(strcmp(info.name, "\x1d") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1e", &info) => 0; + assert(strcmp(info.name, "\x1e") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1f", &info) => 0; + assert(strcmp(info.name, "\x1f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\x0c/\x01", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x02", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x03", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x04", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x05", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x06", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\x0e/\x1a") => 0; + lfs_remove(&lfs, "\x0e/\x1b") => 0; + lfs_remove(&lfs, "\x0e/\x1c") => 0; + lfs_remove(&lfs, "\x0e/\x1d") => 0; + lfs_remove(&lfs, "\x0e/\x1e") => 0; + lfs_remove(&lfs, "\x0e/\x1f") => 0; + + // stat paths + lfs_stat(&lfs, "\x0e/\x1a", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1b", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1c", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1d", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1e", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1f", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with only ascii DELs +# +# I don't know why you'd do this +[cases.test_paths_oopsalldels] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\x7f") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\x7f/\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\x7f/\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + + // stat paths + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\x7f/\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + + // stat paths + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with invalid utf8 sequences +# +# Don't do this! These filenames are not utf8 and will probably break +# external tools. +# +[cases.test_paths_nonutf8] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\xc0") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\xc0/\xa0") => 0; + lfs_mkdir(&lfs, "\xc0/\xb0") => 0; + lfs_mkdir(&lfs, "\xc0/\xc0") => 0; + lfs_mkdir(&lfs, "\xc0/\xd0") => 0; + lfs_mkdir(&lfs, "\xc0/\xe0") => 0; + lfs_mkdir(&lfs, "\xc0/\xf0") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\xc0/\xa0", &info) => 0; + assert(strcmp(info.name, "\xa0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xb0", &info) => 0; + assert(strcmp(info.name, "\xb0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xc0", &info) => 0; + assert(strcmp(info.name, "\xc0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xd0", &info) => 0; + assert(strcmp(info.name, "\xd0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xe0", &info) => 0; + assert(strcmp(info.name, "\xe0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xf0", &info) => 0; + assert(strcmp(info.name, "\xf0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xc0/\xa0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xb0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xc0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xd0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xe0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xf0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xc0/\xa0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xb0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xc0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xd0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xe0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xf0") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\xe0") => 0; + lfs_rename(&lfs, + "\xc0/\xa0", + "\xe0/\xaf") => 0; + lfs_rename(&lfs, + "\xc0/\xb0", + "\xe0/\xbf") => 0; + lfs_rename(&lfs, + "\xc0/\xc0", + "\xe0/\xcf") => 0; + lfs_rename(&lfs, + "\xc0/\xd0", + "\xe0/\xdf") => 0; + lfs_rename(&lfs, + "\xc0/\xe0", + "\xe0/\xef") => 0; + lfs_rename(&lfs, + "\xc0/\xf0", + "\xe0/\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xe0/\xaf", &info) => 0; + assert(strcmp(info.name, "\xaf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xbf", &info) => 0; + assert(strcmp(info.name, "\xbf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xcf", &info) => 0; + assert(strcmp(info.name, "\xcf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xdf", &info) => 0; + assert(strcmp(info.name, "\xdf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xef", &info) => 0; + assert(strcmp(info.name, "\xef") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xff", &info) => 0; + assert(strcmp(info.name, "\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\xc0/\xa0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xb0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xc0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xd0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xe0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xf0", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\xe0/\xaf") => 0; + lfs_remove(&lfs, "\xe0/\xbf") => 0; + lfs_remove(&lfs, "\xe0/\xcf") => 0; + lfs_remove(&lfs, "\xe0/\xdf") => 0; + lfs_remove(&lfs, "\xe0/\xef") => 0; + lfs_remove(&lfs, "\xe0/\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xe0/\xaf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xbf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xcf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xdf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xef", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xff", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' +# test with only "\xff" characters +# +# Don't do this! These filenames are not utf8 and will probably break +# external tools. +# +[cases.test_paths_oopsallffs] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\xff") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\xff/\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff\xff\xff\xff") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\xff/\xff", &info) => 0; + assert(strcmp(info.name, "\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xff/\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xff/\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff\xff") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\xff/\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' From 232e736aae99dda27a0a6f3b37e94c3c7c7e61cb Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 20 Nov 2024 18:38:23 -0600 Subject: [PATCH 2/9] paths: Added trailing slashes and dots tests As expected these are failing and will need some work to pass. The issue with lfs_file_open allowing trailing slashes was found by rob-zeno, and the issue with lfs_mkdir disallowing trailing slashes was found by XinStellaris, PoppaChubby, pavel-kirienko, inf265, Xywzel, steverpalmer, and likely others. --- tests/test_paths.toml | 946 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 943 insertions(+), 3 deletions(-) diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 89fb89e9..8ffb2658 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -568,7 +568,311 @@ code = ''' lfs_unmount(&lfs) => 0; ''' -# TODO test trailing slashes +# test trailing slashes +# +# trailing slashes are only allowed on directories +[cases.test_paths_trailing_slashes] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip/") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew//") => 0; + lfs_mkdir(&lfs, "coffee/turkish///") => 0; + lfs_mkdir(&lfs, "coffee/tubruk////") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese/////") => 0; + lfs_mkdir(&lfs, "coffee/thai//////") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew//", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish///", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai//////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + + // still create so we have something to test + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + if (DIR) { + lfs_stat(&lfs, "coffee/drip//////", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/coldbrew/////", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/turkish////", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/tubruk///", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/vietnamese//", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/thai/", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == LFS_TYPE_DIR); + } else { + lfs_stat(&lfs, "coffee/drip//////", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/coldbrew/////", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/turkish////", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/tubruk///", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/vietnamese//", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/thai/", &info) => LFS_ERR_NOTDIR; + } + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew//", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish///", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk////", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/////", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai//////", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew//", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/turkish///", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk////", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/////", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/thai//////", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip/") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew//") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/turkish///") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/tubruk////") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/////") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/thai//////") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip/") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew//") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/turkish///") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/tubruk////") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/////") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/thai//////") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + if (DIR) { + lfs_rename(&lfs, + "coffee/drip//////", + "espresso/espresso/") => 0; + lfs_rename(&lfs, + "coffee/coldbrew/////", + "espresso/americano//") => 0; + lfs_rename(&lfs, + "coffee/turkish////", + "espresso/macchiato///") => 0; + lfs_rename(&lfs, + "coffee/tubruk///", + "espresso/latte////") => 0; + lfs_rename(&lfs, + "coffee/vietnamese//", + "espresso/cappuccino/////") => 0; + lfs_rename(&lfs, + "coffee/thai/", + "espresso/mocha//////") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso//////", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/americano/////", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/macchiato////", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/latte///", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/cappuccino//", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/mocha/", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == LFS_TYPE_DIR); + + lfs_stat(&lfs, "coffee/drip//////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/coldbrew/////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/turkish////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tubruk///", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/vietnamese//", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai/", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "espresso/espresso/") => 0; + lfs_remove(&lfs, "espresso/americano//") => 0; + lfs_remove(&lfs, "espresso/macchiato///") => 0; + lfs_remove(&lfs, "espresso/latte////") => 0; + lfs_remove(&lfs, "espresso/cappuccino/////") => 0; + lfs_remove(&lfs, "espresso/mocha//////") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso//////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano/////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte///", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino//", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha/", &info) => LFS_ERR_NOENT; + + } else { + // bad source + lfs_rename(&lfs, + "coffee/drip//////", + "espresso/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew/////", + "espresso/americano") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish////", + "espresso/macchiato") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk///", + "espresso/latte") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese//", + "espresso/cappuccino") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai/", + "espresso/mocha") => LFS_ERR_NOTDIR; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "espresso/espresso/") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano//") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato///") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte////") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino/////") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha//////") => LFS_ERR_NOTDIR; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/drip//////", + "espresso/espresso/") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew/////", + "espresso/americano//") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish////", + "espresso/macchiato///") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk///", + "espresso/latte////") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese//", + "espresso/cappuccino/////") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai/", + "espresso/mocha//////") => LFS_ERR_NOTDIR; + + // remove paths + lfs_remove(&lfs, "coffee/drip/") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/coldbrew//") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/turkish///") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/tubruk////") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/vietnamese/////") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/thai//////") => LFS_ERR_NOTDIR; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == LFS_TYPE_REG); + } + + lfs_unmount(&lfs) => 0; +''' # dot path tests [cases.test_paths_dots] @@ -759,7 +1063,325 @@ code = ''' lfs_unmount(&lfs) => 0; ''' -# TODO test trailing dots +# test trailing dots, these get a bit weird +[cases.test_paths_trailing_dots] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip/.") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/coldbrew/./.") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/turkish/././.") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/tubruk/./././.") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/vietnamese/././././.") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/thai/./././././.") => LFS_ERR_NOENT; + + // still create so we have something to test + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/turkish/././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tubruk/./././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/vietnamese/././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai/./././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + + // still create so we have something to test + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + if (DIR) { + lfs_stat(&lfs, "coffee/drip/./././././.", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/coldbrew/././././.", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/turkish/./././.", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/tubruk/././.", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/vietnamese/./.", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/thai/.", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == LFS_TYPE_DIR); + } else { + lfs_stat(&lfs, "coffee/drip/./././././.", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/coldbrew/././././.", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/turkish/./././.", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/tubruk/././.", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/vietnamese/./.", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/thai/.", &info) => LFS_ERR_NOTDIR; + } + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/././.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/./././.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/././././.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai/./././././.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/.", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/././.", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/./././.", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/././././.", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/thai/./././././.", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip/.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew/./.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/turkish/././.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/tubruk/./././.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/././././.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/thai/./././././.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip/.") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew/./.") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/turkish/././.") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/tubruk/./././.") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/././././.") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/thai/./././././.") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + if (DIR) { + // bad source + lfs_rename(&lfs, + "coffee/drip/./././././.", + "espresso/espresso") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/coldbrew/././././.", + "espresso/americano") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/turkish/./././.", + "espresso/macchiato") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tubruk/././.", + "espresso/latte") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/vietnamese/./.", + "espresso/cappuccino") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/thai/.", + "espresso/mocha") => LFS_ERR_INVAL; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "espresso/espresso/.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano/./.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato/././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte/./././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino/././././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha/./././././.") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/drip/./././././.", + "espresso/espresso/.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/coldbrew/././././.", + "espresso/americano/./.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/turkish/./././.", + "espresso/macchiato/././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tubruk/././.", + "espresso/latte/./././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/vietnamese/./.", + "espresso/cappuccino/././././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai/.", + "espresso/mocha/./././././.") => LFS_ERR_NOENT; + + } else { + // bad source + lfs_rename(&lfs, + "coffee/drip/./././././.", + "espresso/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew/././././.", + "espresso/americano") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish/./././.", + "espresso/macchiato") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk/././.", + "espresso/latte") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese/./.", + "espresso/cappuccino") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai/.", + "espresso/mocha") => LFS_ERR_NOTDIR; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "espresso/espresso/.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano/./.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato/././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte/./././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino/././././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha/./././././.") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/drip/./././././.", + "espresso/espresso/.") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew/././././.", + "espresso/americano/./.") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish/./././.", + "espresso/macchiato/././.") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk/././.", + "espresso/latte/./././.") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese/./.", + "espresso/cappuccino/././././.") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai/.", + "espresso/mocha/./././././.") => LFS_ERR_NOTDIR; + } + + // remove paths + if (DIR) { + lfs_remove(&lfs, "coffee/drip/.") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/coldbrew/./.") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/turkish/././.") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/tubruk/./././.") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/vietnamese/././././.") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/thai/./././././.") => LFS_ERR_INVAL; + } else { + lfs_remove(&lfs, "coffee/drip/.") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/coldbrew/./.") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/turkish/././.") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/tubruk/./././.") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/vietnamese/././././.") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/thai/./././././.") => LFS_ERR_NOTDIR; + } + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' # dot dot path tests [cases.test_paths_dotdots] @@ -953,7 +1575,325 @@ code = ''' lfs_unmount(&lfs) => 0; ''' -# TODO test trailing dotdots +# test trailing dot dots, these get really weird +[cases.test_paths_trailing_dotdots] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip/..") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/coldbrew/../..") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/turkish/../../..") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_NOENT; + + // still create so we have something to test + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/turkish/../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + + // still create so we have something to test + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + if (DIR) { + lfs_stat(&lfs, "coffee/drip/../../../../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/coldbrew/../../../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/turkish/../../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/tubruk/../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/vietnamese/../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/thai/..", &info) => 0; + assert(strcmp(info.name, "coffee") == 0); + assert(info.type == LFS_TYPE_DIR); + } else { + lfs_stat(&lfs, "coffee/drip/../../../../../..", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/coldbrew/../../../../..", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/turkish/../../../..", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/tubruk/../../..", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/vietnamese/../..", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coffee/thai/..", &info) => LFS_ERR_NOTDIR; + } + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/..", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/../../..", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip/..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew/../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/turkish/../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/tubruk/../../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/../../../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/thai/../../../../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip/..") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew/../..") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/turkish/../../..") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/tubruk/../../../..") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/../../../../..") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/thai/../../../../../..") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + if (DIR) { + // bad source + lfs_rename(&lfs, + "coffee/drip/../../../../../..", + "espresso/espresso") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/coldbrew/../../../../..", + "espresso/americano") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/turkish/../../../..", + "espresso/macchiato") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tubruk/../../..", + "espresso/latte") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/vietnamese/../..", + "espresso/cappuccino") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/thai/..", + "espresso/mocha") => LFS_ERR_INVAL; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "espresso/espresso/..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano/../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato/../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte/../../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino/../../../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha/../../../../../..") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/drip/../../../../../..", + "espresso/espresso/..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/coldbrew/../../../../..", + "espresso/americano/../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/turkish/../../../..", + "espresso/macchiato/../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tubruk/../../..", + "espresso/latte/../../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/vietnamese/../..", + "espresso/cappuccino/../../../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai/..", + "espresso/mocha/../../../../../..") => LFS_ERR_NOENT; + + } else { + // bad source + lfs_rename(&lfs, + "coffee/drip/../../../../../..", + "espresso/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew/../../../../..", + "espresso/americano") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish/../../../..", + "espresso/macchiato") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk/../../..", + "espresso/latte") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese/../..", + "espresso/cappuccino") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai/..", + "espresso/mocha") => LFS_ERR_NOTDIR; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "espresso/espresso/..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano/../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato/../../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte/../../../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino/../../../../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha/../../../../../..") => LFS_ERR_NOTDIR; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/drip/../../../../../..", + "espresso/espresso/..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew/../../../../..", + "espresso/americano/../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish/../../../..", + "espresso/macchiato/../../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk/../../..", + "espresso/latte/../../../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese/../..", + "espresso/cappuccino/../../../../..") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai/..", + "espresso/mocha/../../../../../..") => LFS_ERR_NOTDIR; + } + + // remove paths + if (DIR) { + lfs_remove(&lfs, "coffee/drip/..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/coldbrew/../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/turkish/../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_INVAL; + } else { + lfs_remove(&lfs, "coffee/drip/..") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/coldbrew/../..") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/turkish/../../..") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_NOTDIR; + lfs_remove(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_NOTDIR; + } + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' # dot dot dot path tests [cases.test_paths_dotdotdots] From a6035071bede7308d30f38c26594b90e5c21395a Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 22 Nov 2024 17:07:51 -0600 Subject: [PATCH 3/9] paths: Fixed/doc trailing slash/dot POSIX incompatibilities - lfs_mkdir now accepts trailing slashes: - before: lfs_mkdir("a/") => LFS_ERR_NOENT - after: lfs_mkdir("a/") => 0 - lfs_stat, lfs_getattr, etc, now reject trailing slashes if the file is not a directory: - before: lfs_stat("reg_a/") => 0 - after: lfs_stat("reg_a/") => LFS_ERR_NOTDIR Note trailing slashes are accepted if the file is a directory: - before: lfs_stat("dir_a/") => 0 - after: lfs_stat("dir_a/") => 0 - lfs_file_open now returns LFS_ERR_NOTDIR if the file exists but the path contains trailing slashes: - before: lfs_file_open("reg_a/") => LFS_ERR_NOENT - after: lfs_file_open("reg_a/") => LFS_ERR_NOTDIR To make these work, the internal lfs_dir_find API required some interesting changes: - lfs_dir_find no longer sets id=0x3ff on not finding a parent entry in the path. Instead, lfs_path_islast can be used to determine if the modified path references a parent entry or child entry based on the remainder of the path string. Note this is only necessary for functions that create new entries (lfs_mkdir, lfs_rename, lfs_file_open). - Trailing slashes mean we can no longer rely on the modified path being NULL-terminated. lfs_path_namelen provides an alternative to strlen that stops at slash or NULL. - lfs_path_isdir also tells you if the modified path must reference a dir (contains trailing slashes). I considered handling this entirely in lfs_dir_find, but the behavior of entry-creating functions is too nuanced. At least lfs_dir_find returns LFS_ERR_NOTDIR if the file exists on disk. Like strlen, lfs_path_namelen/islast/isdir are all O(n) where n is the name length. This isn't great, but if you're using filenames large enough for this to actually matter... uh... open an issue on GitHub and we might improve this in the future. --- There are a couple POSIX incompatibilities that I think are not worth fixing: - Root modifications return EINVAL instead of EBUSY: - littlefs: remove("/") => EINVAL - POSIX: remove("/") => EBUSY Reason: This would be the only use of EBUSY in the system. - We accept modifications of directories with trailing dots: - littlefs: remove("a/.") => 0 - POSIX: remove("a/.") => EBUSY Reason: Not worth implementing. - We do not check for existence of directories followed by dotdots: - littlefs: stat("a/missing/..") => 0 - POSIX: stat("a/missing/..") => ENOENT Reason: Difficult to implement non-recursively. - We accept modifications of directories with trailing dotdots: - littlefs: rename("a/b/..", "c") => 0 - POSIX: rename("a/b/..", "c") => EBUSY Reason: Not worth implementing. These are at least now documented in tests/test_paths.toml, which isn't the greatest location, but it's at least something until a better document is created. Note that these don't really belong in SPEC.md because path parsing is a function of the driver and has no impact on disk. --- lfs.c | 68 ++++-- tests/test_paths.toml | 522 ++++++++++++++++++++---------------------- 2 files changed, 299 insertions(+), 291 deletions(-) diff --git a/lfs.c b/lfs.c index d35d5d6d..db7aae5c 100644 --- a/lfs.c +++ b/lfs.c @@ -282,6 +282,21 @@ static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) { /// Small type-level utilities /// + +// some operations on paths +static inline lfs_size_t lfs_path_namelen(const char *path) { + return strcspn(path, "/"); +} + +static inline bool lfs_path_islast(const char *path) { + lfs_size_t namelen = lfs_path_namelen(path); + return path[namelen + strspn(path + namelen, "/")] == '\0'; +} + +static inline bool lfs_path_isdir(const char *path) { + return path[lfs_path_namelen(path)] != '\0'; +} + // operations on block pairs static inline void lfs_pair_swap(lfs_block_t pair[2]) { lfs_block_t t = pair[0]; @@ -1461,13 +1476,16 @@ static int lfs_dir_find_match(void *data, return LFS_CMP_EQ; } +// lfs_dir_find tries to set path and id even if file is not found +// +// returns: +// - 0 if file is found +// - LFS_ERR_NOENT if file or parent is not found +// - LFS_ERR_NOTDIR if parent is not a dir static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, const char **path, uint16_t *id) { // we reduce path to a single name if we can find it const char *name = *path; - if (id) { - *id = 0x3ff; - } // default to root dir lfs_stag_t tag = LFS_MKTAG(LFS_TYPE_DIR, 0x3ff, 0); @@ -1476,8 +1494,10 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, while (true) { nextname: - // skip slashes - name += strspn(name, "/"); + // skip slashes if we're a directory + if (lfs_tag_type3(tag) == LFS_TYPE_DIR) { + name += strspn(name, "/"); + } lfs_size_t namelen = strcspn(name, "/"); // skip '.' and root '..' @@ -1519,7 +1539,7 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, // update what we've found so far *path = name; - // only continue if we hit a directory + // only continue if we're a directory if (lfs_tag_type3(tag) != LFS_TYPE_DIR) { return LFS_ERR_NOTDIR; } @@ -1539,8 +1559,7 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, tag = lfs_dir_fetchmatch(lfs, dir, dir->tail, LFS_MKTAG(0x780, 0, 0), LFS_MKTAG(LFS_TYPE_NAME, 0, namelen), - // are we last name? - (strchr(name, '/') == NULL) ? id : NULL, + id, lfs_dir_find_match, &(struct lfs_dir_find_match){ lfs, name, namelen}); if (tag < 0) { @@ -2603,12 +2622,12 @@ static int lfs_mkdir_(lfs_t *lfs, const char *path) { cwd.next = lfs->mlist; uint16_t id; err = lfs_dir_find(lfs, &cwd.m, &path, &id); - if (!(err == LFS_ERR_NOENT && id != 0x3ff)) { + if (!(err == LFS_ERR_NOENT && lfs_path_islast(path))) { return (err < 0) ? err : LFS_ERR_EXIST; } // check that name fits - lfs_size_t nlen = strlen(path); + lfs_size_t nlen = lfs_path_namelen(path); if (nlen > lfs->name_max) { return LFS_ERR_NAMETOOLONG; } @@ -3057,7 +3076,7 @@ static int lfs_file_opencfg_(lfs_t *lfs, lfs_file_t *file, // allocate entry for file if it doesn't exist lfs_stag_t tag = lfs_dir_find(lfs, &file->m, &path, &file->id); - if (tag < 0 && !(tag == LFS_ERR_NOENT && file->id != 0x3ff)) { + if (tag < 0 && !(tag == LFS_ERR_NOENT && lfs_path_islast(path))) { err = tag; goto cleanup; } @@ -3077,8 +3096,14 @@ static int lfs_file_opencfg_(lfs_t *lfs, lfs_file_t *file, goto cleanup; } + // don't allow trailing slashes + if (lfs_path_isdir(path)) { + err = LFS_ERR_ISDIR; + goto cleanup; + } + // check that name fits - lfs_size_t nlen = strlen(path); + lfs_size_t nlen = lfs_path_namelen(path); if (nlen > lfs->name_max) { err = LFS_ERR_NAMETOOLONG; goto cleanup; @@ -3842,6 +3867,12 @@ static int lfs_stat_(lfs_t *lfs, const char *path, struct lfs_info *info) { return (int)tag; } + // only allow trailing slashes on dirs + if (strchr(path, '/') != NULL + && lfs_tag_type3(tag) != LFS_TYPE_DIR) { + return LFS_ERR_NOTDIR; + } + return lfs_dir_getinfo(lfs, &cwd, lfs_tag_id(tag), info); } @@ -3944,7 +3975,7 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) { uint16_t newid; lfs_stag_t prevtag = lfs_dir_find(lfs, &newcwd, &newpath, &newid); if ((prevtag < 0 || lfs_tag_id(prevtag) == 0x3ff) && - !(prevtag == LFS_ERR_NOENT && newid != 0x3ff)) { + !(prevtag == LFS_ERR_NOENT && lfs_path_islast(newpath))) { return (prevtag < 0) ? (int)prevtag : LFS_ERR_INVAL; } @@ -3955,8 +3986,14 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) { struct lfs_mlist prevdir; prevdir.next = lfs->mlist; if (prevtag == LFS_ERR_NOENT) { + // if we're a file, don't allow trailing slashes + if (lfs_path_isdir(newpath) + && lfs_tag_type3(oldtag) != LFS_TYPE_DIR) { + return LFS_ERR_NOTDIR; + } + // check that name fits - lfs_size_t nlen = strlen(newpath); + lfs_size_t nlen = lfs_path_namelen(newpath); if (nlen > lfs->name_max) { return LFS_ERR_NAMETOOLONG; } @@ -4016,7 +4053,8 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) { {LFS_MKTAG_IF(prevtag != LFS_ERR_NOENT, LFS_TYPE_DELETE, newid, 0), NULL}, {LFS_MKTAG(LFS_TYPE_CREATE, newid, 0), NULL}, - {LFS_MKTAG(lfs_tag_type3(oldtag), newid, strlen(newpath)), newpath}, + {LFS_MKTAG(lfs_tag_type3(oldtag), + newid, lfs_path_namelen(newpath)), newpath}, {LFS_MKTAG(LFS_FROM_MOVE, newid, lfs_tag_id(oldtag)), &oldcwd}, {LFS_MKTAG_IF(samepair, LFS_TYPE_DELETE, newoldid, 0), NULL})); diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 8ffb2658..69f1d7fe 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -1064,6 +1064,14 @@ code = ''' ''' # test trailing dots, these get a bit weird +# +# POSIX deviations: +# +# - We accept modifications of directories with trailing dots: +# - littlefs: remove("a/.") => 0 +# - POSIX: remove("a/.") => EBUSY +# Reason: Not worth implementing. +# [cases.test_paths_trailing_dots] defines.DIR = [false, true] code = ''' @@ -1214,26 +1222,6 @@ code = ''' // rename paths lfs_mkdir(&lfs, "espresso") => 0; if (DIR) { - // bad source - lfs_rename(&lfs, - "coffee/drip/./././././.", - "espresso/espresso") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/coldbrew/././././.", - "espresso/americano") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/turkish/./././.", - "espresso/macchiato") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/tubruk/././.", - "espresso/latte") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/vietnamese/./.", - "espresso/cappuccino") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/thai/.", - "espresso/mocha") => LFS_ERR_INVAL; - // bad destination lfs_rename(&lfs, "coffee/drip", @@ -1274,6 +1262,69 @@ code = ''' "coffee/thai/.", "espresso/mocha/./././././.") => LFS_ERR_NOENT; + // this one works + lfs_rename(&lfs, + "coffee/drip/./././././.", + "espresso/espresso") => 0; + lfs_rename(&lfs, + "coffee/coldbrew/././././.", + "espresso/americano") => 0; + lfs_rename(&lfs, + "coffee/turkish/./././.", + "espresso/macchiato") => 0; + lfs_rename(&lfs, + "coffee/tubruk/././.", + "espresso/latte") => 0; + lfs_rename(&lfs, + "coffee/vietnamese/./.", + "espresso/cappuccino") => 0; + lfs_rename(&lfs, + "coffee/thai/.", + "espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso/./././././.", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/americano/././././.", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/macchiato/./././.", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/latte/././.", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/cappuccino/./.", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "espresso/mocha/.", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == LFS_TYPE_DIR); + + lfs_stat(&lfs, "coffee/drip/./././././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/coldbrew/././././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/turkish/./././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tubruk/././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/vietnamese/./.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai/.", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "espresso/espresso/.") => 0; + lfs_remove(&lfs, "espresso/americano/./.") => 0; + lfs_remove(&lfs, "espresso/macchiato/././.") => 0; + lfs_remove(&lfs, "espresso/latte/./././.") => 0; + lfs_remove(&lfs, "espresso/cappuccino/././././.") => 0; + lfs_remove(&lfs, "espresso/mocha/./././././.") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso/./././././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano/././././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato/./././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte/././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino/./.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha/.", &info) => LFS_ERR_NOENT; + } else { // bad source lfs_rename(&lfs, @@ -1334,51 +1385,42 @@ code = ''' lfs_rename(&lfs, "coffee/thai/.", "espresso/mocha/./././././.") => LFS_ERR_NOTDIR; - } - // remove paths - if (DIR) { - lfs_remove(&lfs, "coffee/drip/.") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/coldbrew/./.") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/turkish/././.") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/tubruk/./././.") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/vietnamese/././././.") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/thai/./././././.") => LFS_ERR_INVAL; - } else { + // remove paths lfs_remove(&lfs, "coffee/drip/.") => LFS_ERR_NOTDIR; lfs_remove(&lfs, "coffee/coldbrew/./.") => LFS_ERR_NOTDIR; lfs_remove(&lfs, "coffee/turkish/././.") => LFS_ERR_NOTDIR; lfs_remove(&lfs, "coffee/tubruk/./././.") => LFS_ERR_NOTDIR; lfs_remove(&lfs, "coffee/vietnamese/././././.") => LFS_ERR_NOTDIR; lfs_remove(&lfs, "coffee/thai/./././././.") => LFS_ERR_NOTDIR; - } - // stat paths - lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "coffee/drip", &info) => 0; - assert(strcmp(info.name, "drip") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; - assert(strcmp(info.name, "coldbrew") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "coffee/turkish", &info) => 0; - assert(strcmp(info.name, "turkish") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "coffee/tubruk", &info) => 0; - assert(strcmp(info.name, "tubruk") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; - assert(strcmp(info.name, "vietnamese") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "coffee/thai", &info) => 0; - assert(strcmp(info.name, "thai") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == LFS_TYPE_REG); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == LFS_TYPE_REG); + } lfs_unmount(&lfs) => 0; ''' @@ -1576,6 +1618,19 @@ code = ''' ''' # test trailing dot dots, these get really weird +# +# POSIX deviations: +# +# - We do not check for existance of directories followed by dotdots: +# - littlefs: stat("a/missing/..") => 0 +# - POSIX: stat("a/missing/..") => ENOENT +# Reason: Difficult to implement non-recursively. +# +# - We accept modifications of directories with trailing dotdots: +# - littlefs: rename("a/b/..", "c") => 0 +# - POSIX: rename("a/b/..", "c") => EBUSY +# Reason: Not worth implementing. +# [cases.test_paths_trailing_dotdots] defines.DIR = [false, true] code = ''' @@ -1586,12 +1641,12 @@ code = ''' // create paths lfs_mkdir(&lfs, "coffee") => 0; if (DIR) { - lfs_mkdir(&lfs, "coffee/drip/..") => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "coffee/coldbrew/../..") => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "coffee/turkish/../../..") => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee/drip/..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "coffee/coldbrew/../..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "coffee/turkish/../../..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_EXIST; // still create so we have something to test lfs_mkdir(&lfs, "coffee/drip") => 0; @@ -1604,17 +1659,17 @@ code = ''' } else { lfs_file_t file; lfs_file_open(&lfs, &file, "coffee/drip/..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; lfs_file_open(&lfs, &file, "coffee/turkish/../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; // still create so we have something to test lfs_file_open(&lfs, &file, "coffee/drip", @@ -1639,231 +1694,138 @@ code = ''' // stat paths struct lfs_info info; - if (DIR) { - lfs_stat(&lfs, "coffee/drip/../../../../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/coldbrew/../../../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/turkish/../../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/tubruk/../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/vietnamese/../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/thai/..", &info) => 0; - assert(strcmp(info.name, "coffee") == 0); - assert(info.type == LFS_TYPE_DIR); - } else { - lfs_stat(&lfs, "coffee/drip/../../../../../..", &info) => LFS_ERR_NOTDIR; - lfs_stat(&lfs, "coffee/coldbrew/../../../../..", &info) => LFS_ERR_NOTDIR; - lfs_stat(&lfs, "coffee/turkish/../../../..", &info) => LFS_ERR_NOTDIR; - lfs_stat(&lfs, "coffee/tubruk/../../..", &info) => LFS_ERR_NOTDIR; - lfs_stat(&lfs, "coffee/vietnamese/../..", &info) => LFS_ERR_NOTDIR; - lfs_stat(&lfs, "coffee/thai/..", &info) => LFS_ERR_NOTDIR; - } + lfs_stat(&lfs, "coffee/drip/../../../../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/coldbrew/../../../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/turkish/../../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/tubruk/../../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/vietnamese/../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/thai/..", &info) => 0; + assert(strcmp(info.name, "coffee") == 0); + assert(info.type == LFS_TYPE_DIR); // file open paths, only works on files! - if (DIR) { - lfs_file_t file; - lfs_file_open(&lfs, &file, "coffee/drip/..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "coffee/turkish/../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - } else { - lfs_file_t file; - lfs_file_open(&lfs, &file, "coffee/drip/..", - LFS_O_RDONLY) => LFS_ERR_NOTDIR; - lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", - LFS_O_RDONLY) => LFS_ERR_NOTDIR; - lfs_file_open(&lfs, &file, "coffee/turkish/../../..", - LFS_O_RDONLY) => LFS_ERR_NOTDIR; - lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", - LFS_O_RDONLY) => LFS_ERR_NOTDIR; - lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", - LFS_O_RDONLY) => LFS_ERR_NOTDIR; - lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", - LFS_O_RDONLY) => LFS_ERR_NOTDIR; - } + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip/..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; // dir open paths, only works on dirs! - if (DIR) { - lfs_dir_t dir; - lfs_dir_open(&lfs, &dir, "coffee/drip/..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/coldbrew/../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/turkish/../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/tubruk/../../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/vietnamese/../../../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/thai/../../../../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - } else { - lfs_dir_t dir; - lfs_dir_open(&lfs, &dir, "coffee/drip/..") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "coffee/coldbrew/../..") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "coffee/turkish/../../..") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "coffee/tubruk/../../../..") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "coffee/vietnamese/../../../../..") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "coffee/thai/../../../../../..") => LFS_ERR_NOTDIR; - } + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip/..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew/../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/turkish/../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/tubruk/../../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/../../../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/thai/../../../../../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; // rename paths lfs_mkdir(&lfs, "espresso") => 0; - if (DIR) { - // bad source - lfs_rename(&lfs, - "coffee/drip/../../../../../..", - "espresso/espresso") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/coldbrew/../../../../..", - "espresso/americano") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/turkish/../../../..", - "espresso/macchiato") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/tubruk/../../..", - "espresso/latte") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/vietnamese/../..", - "espresso/cappuccino") => LFS_ERR_INVAL; - lfs_rename(&lfs, - "coffee/thai/..", - "espresso/mocha") => LFS_ERR_INVAL; + // bad source + lfs_rename(&lfs, + "coffee/drip/../../../../../..", + "espresso/espresso") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/coldbrew/../../../../..", + "espresso/americano") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/turkish/../../../..", + "espresso/macchiato") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tubruk/../../..", + "espresso/latte") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/vietnamese/../..", + "espresso/cappuccino") => LFS_ERR_INVAL; + // this one works + lfs_rename(&lfs, + "coffee/thai/..", + "espresso/mocha") => 0; + lfs_rename(&lfs, + "espresso/mocha", + "coffee") => 0; - // bad destination + // bad destination + if (DIR) { + // this one works lfs_rename(&lfs, "coffee/drip", - "espresso/espresso/..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/coldbrew", - "espresso/americano/../..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/turkish", - "espresso/macchiato/../../..") => LFS_ERR_NOENT; + "espresso/espresso/..") => 0; lfs_rename(&lfs, - "coffee/tubruk", - "espresso/latte/../../../..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/vietnamese", - "espresso/cappuccino/../../../../..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/thai", - "espresso/mocha/../../../../../..") => LFS_ERR_NOENT; - - // bad source and bad destination - lfs_rename(&lfs, - "coffee/drip/../../../../../..", - "espresso/espresso/..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/coldbrew/../../../../..", - "espresso/americano/../..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/turkish/../../../..", - "espresso/macchiato/../../..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/tubruk/../../..", - "espresso/latte/../../../..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/vietnamese/../..", - "espresso/cappuccino/../../../../..") => LFS_ERR_NOENT; - lfs_rename(&lfs, - "coffee/thai/..", - "espresso/mocha/../../../../../..") => LFS_ERR_NOENT; - + "espresso", + "coffee/drip") => 0; } else { - // bad source - lfs_rename(&lfs, - "coffee/drip/../../../../../..", - "espresso/espresso") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/coldbrew/../../../../..", - "espresso/americano") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/turkish/../../../..", - "espresso/macchiato") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/tubruk/../../..", - "espresso/latte") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/vietnamese/../..", - "espresso/cappuccino") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/thai/..", - "espresso/mocha") => LFS_ERR_NOTDIR; - - // bad destination lfs_rename(&lfs, "coffee/drip", - "espresso/espresso/..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/coldbrew", - "espresso/americano/../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/turkish", - "espresso/macchiato/../../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/tubruk", - "espresso/latte/../../../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/vietnamese", - "espresso/cappuccino/../../../../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/thai", - "espresso/mocha/../../../../../..") => LFS_ERR_NOTDIR; - - // bad source and bad destination - lfs_rename(&lfs, - "coffee/drip/../../../../../..", - "espresso/espresso/..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/coldbrew/../../../../..", - "espresso/americano/../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/turkish/../../../..", - "espresso/macchiato/../../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/tubruk/../../..", - "espresso/latte/../../../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/vietnamese/../..", - "espresso/cappuccino/../../../../..") => LFS_ERR_NOTDIR; - lfs_rename(&lfs, - "coffee/thai/..", - "espresso/mocha/../../../../../..") => LFS_ERR_NOTDIR; + "espresso/espresso/..") => LFS_ERR_ISDIR; } + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano/../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato/../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte/../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino/../../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha/../../../../../..") => LFS_ERR_INVAL; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/drip/../../../../../..", + "espresso/espresso/..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/coldbrew/../../../../..", + "espresso/americano/../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/turkish/../../../..", + "espresso/macchiato/../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tubruk/../../..", + "espresso/latte/../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/vietnamese/../..", + "espresso/cappuccino/../../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/thai/..", + "espresso/mocha/../../../../../..") => LFS_ERR_INVAL; // remove paths - if (DIR) { - lfs_remove(&lfs, "coffee/drip/..") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/coldbrew/../..") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/turkish/../../..") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_INVAL; - lfs_remove(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_INVAL; - } else { - lfs_remove(&lfs, "coffee/drip/..") => LFS_ERR_NOTDIR; - lfs_remove(&lfs, "coffee/coldbrew/../..") => LFS_ERR_NOTDIR; - lfs_remove(&lfs, "coffee/turkish/../../..") => LFS_ERR_NOTDIR; - lfs_remove(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_NOTDIR; - lfs_remove(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_NOTDIR; - lfs_remove(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_NOTDIR; - } + lfs_remove(&lfs, "coffee/drip/..") => LFS_ERR_NOTEMPTY; + lfs_remove(&lfs, "coffee/coldbrew/../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/turkish/../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_INVAL; // stat paths lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; @@ -3048,6 +3010,14 @@ code = ''' ''' # root operations +# +# POSIX deviations: +# +# - Root modifications return EINVAL instead of EBUSY: +# - littlefs: remove("/") => EINVAL +# - POSIX: remove("/") => EBUSY +# Reason: This would be the only use of EBUSY in the system. +# [cases.test_paths_root] defines.DIR = [false, true] code = ''' From dc92dec6d3f41213c4d0011c440195c991ef38a4 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 23 Nov 2024 01:23:11 -0600 Subject: [PATCH 4/9] paths: Reject dotdots above root This changes the behavior of paths that attempt to navigate above root to now return LFS_ERR_INVAL: - before: lfs_stat("/../a") => 0 - after: lfs_stat("/../a") => LFS_ERR_INVAL This is a bit of an opinionated change while making other path resolution tweaks. In terms of POSIX-compatibility, it's a bit unclear exactly what dotdots above the root should do. POSIX notes: > As a special case, in the root directory, dot-dot may refer to the > root directory itself. But the word choice of "may" implies it is up to the implementation. I originally implement this as a root-loop simply because that is what my Linux machine does, but I now think that's not the best option. Since we're making other path-related tweaks, we might as well try to adopt behavior that is, in my opinion, safer and less... weird... This should also help make paths more consistent with future theoretical openat-list APIs, where saturating at the current directory is sort of the least expected behavior. --- lfs.c | 10 +- tests/test_paths.toml | 354 +++++++++++++++++++++--------------------- 2 files changed, 182 insertions(+), 182 deletions(-) diff --git a/lfs.c b/lfs.c index db7aae5c..6cef3eed 100644 --- a/lfs.c +++ b/lfs.c @@ -1500,13 +1500,17 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, } lfs_size_t namelen = strcspn(name, "/"); - // skip '.' and root '..' - if ((namelen == 1 && memcmp(name, ".", 1) == 0) || - (namelen == 2 && memcmp(name, "..", 2) == 0)) { + // skip '.' + if (namelen == 1 && memcmp(name, ".", 1) == 0) { name += namelen; goto nextname; } + // error on unmatched '..', trying to go above root? + if (namelen == 2 && memcmp(name, "..", 2) == 0) { + return LFS_ERR_INVAL; + } + // skip if matched by '..' in name const char *suffix = name + namelen; lfs_size_t sufflen; diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 69f1d7fe..9e3a151e 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -1643,10 +1643,10 @@ code = ''' if (DIR) { lfs_mkdir(&lfs, "coffee/drip/..") => LFS_ERR_EXIST; lfs_mkdir(&lfs, "coffee/coldbrew/../..") => LFS_ERR_EXIST; - lfs_mkdir(&lfs, "coffee/turkish/../../..") => LFS_ERR_EXIST; - lfs_mkdir(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_EXIST; - lfs_mkdir(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_EXIST; - lfs_mkdir(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "coffee/turkish/../../..") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "coffee/tubruk/../../../..") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "coffee/vietnamese/../../../../..") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "coffee/thai/../../../../../..") => LFS_ERR_INVAL; // still create so we have something to test lfs_mkdir(&lfs, "coffee/drip") => 0; @@ -1663,13 +1663,13 @@ code = ''' lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; lfs_file_open(&lfs, &file, "coffee/turkish/../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; // still create so we have something to test lfs_file_open(&lfs, &file, "coffee/drip", @@ -1694,18 +1694,10 @@ code = ''' // stat paths struct lfs_info info; - lfs_stat(&lfs, "coffee/drip/../../../../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/coldbrew/../../../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/turkish/../../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "coffee/tubruk/../../..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/drip/../../../../../..", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "coffee/coldbrew/../../../../..", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "coffee/turkish/../../../..", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "coffee/tubruk/../../..", &info) => LFS_ERR_INVAL; lfs_stat(&lfs, "coffee/vietnamese/../..", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); @@ -1720,13 +1712,13 @@ code = ''' lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "coffee/turkish/../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; + LFS_O_RDONLY) => LFS_ERR_INVAL; lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; + LFS_O_RDONLY) => LFS_ERR_INVAL; lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; + LFS_O_RDONLY) => LFS_ERR_INVAL; lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; + LFS_O_RDONLY) => LFS_ERR_INVAL; // dir open paths, only works on dirs! lfs_dir_t dir; @@ -1734,14 +1726,10 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, "coffee/coldbrew/../..") => 0; lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/turkish/../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/tubruk/../../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/vietnamese/../../../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "coffee/thai/../../../../../..") => 0; - lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/turkish/../../..") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "coffee/tubruk/../../../..") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese/../../../../..") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "coffee/thai/../../../../../..") => LFS_ERR_INVAL; // rename paths lfs_mkdir(&lfs, "espresso") => 0; @@ -2249,181 +2237,208 @@ code = ''' lfs_mkdir(&lfs, "no") => 0; lfs_mkdir(&lfs, "coffee") => 0; if (DIR) { - lfs_mkdir(&lfs, "/../coffee/drip") => 0; - lfs_mkdir(&lfs, "/../../coffee/coldbrew") => 0; - lfs_mkdir(&lfs, "/../../../coffee/turkish") => 0; - lfs_mkdir(&lfs, "/no/../../coffee/tubruk") => 0; - lfs_mkdir(&lfs, "/no/../../../coffee/vietnamese") => 0; - lfs_mkdir(&lfs, "/no/../../../../coffee/thai") => 0; + lfs_mkdir(&lfs, "/../coffee/drip") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "/../../coffee/coldbrew") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "/../../../coffee/turkish") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "/no/../../coffee/tubruk") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "/no/../../../coffee/vietnamese") => LFS_ERR_INVAL; + lfs_mkdir(&lfs, "/no/../../../../coffee/thai") => LFS_ERR_INVAL; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + } + + // ok, actually create paths + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + lfs_file_open(&lfs, &file, "coffee/coldbrew", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + lfs_file_open(&lfs, &file, "coffee/turkish", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + lfs_file_open(&lfs, &file, "coffee/tubruk", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + lfs_file_open(&lfs, &file, "coffee/vietnamese", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + lfs_file_open(&lfs, &file, "coffee/thai", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; lfs_file_close(&lfs, &file) => 0; } // stat paths struct lfs_info info; - lfs_stat(&lfs, "/no/../../../../coffee/drip", &info) => 0; - assert(strcmp(info.name, "drip") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/no/../../../coffee/coldbrew", &info) => 0; - assert(strcmp(info.name, "coldbrew") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/no/../../coffee/turkish", &info) => 0; - assert(strcmp(info.name, "turkish") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/../../../coffee/tubruk", &info) => 0; - assert(strcmp(info.name, "tubruk") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/../../coffee/vietnamese", &info) => 0; - assert(strcmp(info.name, "vietnamese") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/../coffee/thai", &info) => 0; - assert(strcmp(info.name, "thai") == 0); - assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../../../coffee/drip", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "/no/../../../coffee/coldbrew", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "/no/../../coffee/turkish", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "/../../../coffee/tubruk", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "/../../coffee/vietnamese", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "/../coffee/thai", &info) => LFS_ERR_INVAL; // file open paths, only works on files! - if (DIR) { - lfs_file_t file; - lfs_file_open(&lfs, &file, "/../coffee/drip", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "/../../../coffee/turkish", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", - LFS_O_RDONLY) => LFS_ERR_ISDIR; - } else { - lfs_file_t file; - lfs_file_open(&lfs, &file, "/../coffee/drip", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/../../../coffee/turkish", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; - lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; - } + lfs_file_t file; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_RDONLY) => LFS_ERR_INVAL; // dir open paths, only works on dirs! - if (DIR) { - lfs_dir_t dir; - lfs_dir_open(&lfs, &dir, "/../coffee/drip") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/../../coffee/coldbrew") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/../../../coffee/turkish") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/no/../../coffee/tubruk") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/no/../../../coffee/vietnamese") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/no/../../../../coffee/thai") => 0; - lfs_dir_close(&lfs, &dir) => 0; - } else { - lfs_dir_t dir; - lfs_dir_open(&lfs, &dir, "/../coffee/drip") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "/../../coffee/coldbrew") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "/../../../coffee/turkish") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "/no/../coffee/tubruk") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "/no/../../coffee/vietnamese") => LFS_ERR_NOTDIR; - lfs_dir_open(&lfs, &dir, "/no/../../../coffee/thai") => LFS_ERR_NOTDIR; - } + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/../coffee/drip") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "/../../coffee/coldbrew") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "/../../../coffee/turkish") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "/no/../../coffee/tubruk") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "/no/../../../coffee/vietnamese") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "/no/../../../../coffee/thai") => LFS_ERR_INVAL; // rename paths lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "/no/../../../../coffee/drip", + "espresso/espresso") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/no/../../../coffee/coldbrew", + "espresso/americano") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/no/../../coffee/turkish", + "espresso/macchiato") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/../../../coffee/tubruk", + "espresso/latte") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/../../coffee/vietnamese", + "espresso/cappuccino") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/../coffee/thai", + "espresso/mocha") => LFS_ERR_INVAL; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "/../espresso/espresso") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/coldbrew", + "/../../espresso/americano") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/turkish", + "/../../../espresso/macchiato") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tubruk", + "/no/../../espresso/latte") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/vietnamese", + "/no/../../../espresso/cappuccino") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/thai", + "/no/../../../../espresso/mocha") => LFS_ERR_INVAL; + + // bad source and bad destination lfs_rename(&lfs, "/no/../../../../coffee/drip", - "/../espresso/espresso") => 0; + "/../espresso/espresso") => LFS_ERR_INVAL; lfs_rename(&lfs, "/no/../../../coffee/coldbrew", - "/../../espresso/americano") => 0; + "/../../espresso/americano") => LFS_ERR_INVAL; lfs_rename(&lfs, "/no/../../coffee/turkish", - "/../../../espresso/macchiato") => 0; + "/../../../espresso/macchiato") => LFS_ERR_INVAL; lfs_rename(&lfs, "/../../../coffee/tubruk", - "/no/../../espresso/latte") => 0; + "/no/../../espresso/latte") => LFS_ERR_INVAL; lfs_rename(&lfs, "/../../coffee/vietnamese", - "/no/../../../espresso/cappuccino") => 0; + "/no/../../../espresso/cappuccino") => LFS_ERR_INVAL; lfs_rename(&lfs, "/../coffee/thai", - "/no/../../../../espresso/mocha") => 0; + "/no/../../../../espresso/mocha") => LFS_ERR_INVAL; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "/../coffee/drip", + "/../espresso/espresso") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/../../coffee/coldbrew", + "/../../espresso/americano") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/../../../coffee/turkish", + "/../../../espresso/macchiato") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/no/../../coffee/tubruk", + "/no/../../espresso/latte") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/no/../../../coffee/vietnamese", + "/no/../../../espresso/cappuccino") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "/no/../../../../coffee/thai", + "/no/../../../../espresso/mocha") => LFS_ERR_INVAL; + + // remove paths + lfs_remove(&lfs, "/../espresso/espresso") => LFS_ERR_INVAL; + lfs_remove(&lfs, "/../../espresso/americano") => LFS_ERR_INVAL; + lfs_remove(&lfs, "/../../../espresso/macchiato") => LFS_ERR_INVAL; + lfs_remove(&lfs, "/no/../../espresso/latte") => LFS_ERR_INVAL; + lfs_remove(&lfs, "/no/../../../espresso/cappuccino") => LFS_ERR_INVAL; + lfs_remove(&lfs, "/no/../../../../espresso/mocha") => LFS_ERR_INVAL; // stat paths - lfs_stat(&lfs, "/no/../../../../espresso/espresso", &info) => 0; - assert(strcmp(info.name, "espresso") == 0); + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/no/../../../espresso/americano", &info) => 0; - assert(strcmp(info.name, "americano") == 0); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/no/../../espresso/macchiato", &info) => 0; - assert(strcmp(info.name, "macchiato") == 0); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/../../../espresso/latte", &info) => 0; - assert(strcmp(info.name, "latte") == 0); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/../../espresso/cappuccino", &info) => 0; - assert(strcmp(info.name, "cappuccino") == 0); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/../espresso/mocha", &info) => 0; - assert(strcmp(info.name, "mocha") == 0); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); - lfs_stat(&lfs, "/no/../../../../coffee/drip", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/no/../../../coffee/coldbrew", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/no/../../coffee/turkish", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/../../../coffee/tubruk", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/../../coffee/vietnamese", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/../coffee/thai", &info) => LFS_ERR_NOENT; - - // remove paths - lfs_remove(&lfs, "/../espresso/espresso") => 0; - lfs_remove(&lfs, "/../../espresso/americano") => 0; - lfs_remove(&lfs, "/../../../espresso/macchiato") => 0; - lfs_remove(&lfs, "/no/../../espresso/latte") => 0; - lfs_remove(&lfs, "/no/../../../espresso/cappuccino") => 0; - lfs_remove(&lfs, "/no/../../../../espresso/mocha") => 0; - - // stat paths - lfs_stat(&lfs, "/no/../../../../espresso/espresso", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/no/../../../espresso/americano", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/no/../../espresso/macchiato", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/../../../espresso/latte", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/../../espresso/cappuccino", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "/../espresso/mocha", &info) => LFS_ERR_NOENT; - lfs_unmount(&lfs) => 0; ''' @@ -3089,7 +3104,6 @@ code = ''' lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; lfs_mkdir(&lfs, "") => LFS_ERR_EXIST; lfs_mkdir(&lfs, ".") => LFS_ERR_EXIST; - lfs_mkdir(&lfs, "..") => LFS_ERR_EXIST; lfs_mkdir(&lfs, "./") => LFS_ERR_EXIST; lfs_mkdir(&lfs, "/.") => LFS_ERR_EXIST; lfs_mkdir(&lfs, "//") => LFS_ERR_EXIST; @@ -3101,8 +3115,6 @@ code = ''' LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, ".", LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "..", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "./", LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/.", @@ -3121,9 +3133,6 @@ code = ''' lfs_stat(&lfs, ".", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, "./", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); @@ -3142,8 +3151,6 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, ".", LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "..", - LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "./", LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/.", @@ -3159,8 +3166,6 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, ".") => 0; lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "..") => 0; - lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, "./") => 0; lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, "/.") => 0; @@ -3172,7 +3177,6 @@ code = ''' lfs_rename(&lfs, "/", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, "", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, ".", "coffee") => LFS_ERR_INVAL; - lfs_rename(&lfs, "..", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, "./", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, "/.", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, "//", "coffee") => LFS_ERR_INVAL; @@ -3181,7 +3185,6 @@ code = ''' lfs_rename(&lfs, "coffee", "/") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", "") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", ".") => LFS_ERR_INVAL; - lfs_rename(&lfs, "coffee", "..") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", "./") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", "/.") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", "//") => LFS_ERR_INVAL; @@ -3205,9 +3208,6 @@ code = ''' lfs_stat(&lfs, ".", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, "./", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); @@ -3222,7 +3222,6 @@ code = ''' lfs_remove(&lfs, "/") => LFS_ERR_INVAL; lfs_remove(&lfs, "") => LFS_ERR_INVAL; lfs_remove(&lfs, ".") => LFS_ERR_INVAL; - lfs_remove(&lfs, "..") => LFS_ERR_INVAL; lfs_remove(&lfs, "./") => LFS_ERR_INVAL; lfs_remove(&lfs, "/.") => LFS_ERR_INVAL; lfs_remove(&lfs, "//") => LFS_ERR_INVAL; @@ -3237,9 +3236,6 @@ code = ''' lfs_stat(&lfs, ".", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "..", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, "./", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); From 815f0d85a53d2ae7fa99ec0be8cf0d86b90dc780 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 23 Nov 2024 01:49:08 -0600 Subject: [PATCH 5/9] paths: Fixed dots followed by dotdots Unlike normal files, dots (".") should not change the depth when attempting to skip dotdot ("..") entries. A weird nuance in the path parser, but at least it had a relatively easy fix. Added test_paths_dot_dotdots to prevent a regression. --- lfs.c | 4 +- tests/test_paths.toml | 192 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/lfs.c b/lfs.c index 6cef3eed..29e2838b 100644 --- a/lfs.c +++ b/lfs.c @@ -1522,7 +1522,9 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, break; } - if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) { + if (sufflen == 1 && memcmp(suffix, ".", 1) == 0) { + // noop + } else if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) { depth -= 1; if (depth == 0) { name = suffix + sufflen; diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 9e3a151e..16430f01 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -1845,6 +1845,198 @@ code = ''' lfs_unmount(&lfs) => 0; ''' +# dot dot dot path tests +[cases.test_paths_dot_dotdots] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "no") => 0; + lfs_mkdir(&lfs, "no/no") => 0; + lfs_mkdir(&lfs, "coffee") => 0; + lfs_mkdir(&lfs, "coffee/no") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "/no/./../coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/no/./../turkish") => 0; + lfs_mkdir(&lfs, "/no/no/./.././../coffee/tubruk") => 0; + lfs_mkdir(&lfs, "/no/no/./.././../coffee/no/./../vietnamese") => 0; + lfs_mkdir(&lfs, "/no/no/./.././../no/no/./.././../coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/./../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/./.././../coffee/no/./../coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/./.././../coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/no/./../tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/./../coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/no/./../turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/./../turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/./../coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/no/./../turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/no/./../vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/./.././../no/no/./.././../coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/./../coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/no/./../turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/no/./../vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/./.././../no/no/./.././../coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/no/no/./.././../no/no/./.././../coffee/drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "/no/no/./.././../coffee/no/./../coldbrew", + "/no/./../espresso/americano") => 0; + lfs_rename(&lfs, + "/no/no/./.././../coffee/turkish", + "/espresso/no/./../macchiato") => 0; + lfs_rename(&lfs, + "/coffee/no/./../tubruk", + "/no/no/./.././../espresso/latte") => 0; + lfs_rename(&lfs, + "/no/./../coffee/vietnamese", + "/no/no/./.././../espresso/no/./../cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "/no/no/./.././../no/no/./.././../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/./.././../espresso/no/./../americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/./.././../espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/no/./../latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/./../espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/./.././../coffee/no/./../coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/./.././../coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/no/./../tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/./../coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "/no/./../espresso/americano") => 0; + lfs_remove(&lfs, "/espresso/no/./../macchiato") => 0; + lfs_remove(&lfs, "/no/no/./.././../espresso/latte") => 0; + lfs_remove(&lfs, "/no/no/./.././../espresso/no/./../cappuccino") => 0; + lfs_remove(&lfs, "/no/no/./.././../no/no/./.././../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/./.././../espresso/no/./../americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/./.././../espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/no/./../latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/./../espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + # dot dot dot path tests [cases.test_paths_dotdotdots] defines.DIR = [false, true] From 80ca1ea300a7a969984ab4b9afd04f276fba40a8 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 23 Nov 2024 18:25:40 -0600 Subject: [PATCH 6/9] paths: Reject empty paths Before this, the empty path ("") was treated as an alias for the root. This was unintentional and just a side-effect of how the path parser worked. Now, the empty path should always result in LFS_ERR_INVAL: - before: lfs_stat("") => 0 - after: lfs_stat("") => LFS_ERR_INVAL --- lfs.c | 7 ++++- tests/test_paths.toml | 72 +++++++++++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/lfs.c b/lfs.c index 29e2838b..94d23f7b 100644 --- a/lfs.c +++ b/lfs.c @@ -1492,6 +1492,11 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, dir->tail[0] = lfs->root[0]; dir->tail[1] = lfs->root[1]; + // empty paths are not allowed + if (*name == '\0') { + return LFS_ERR_INVAL; + } + while (true) { nextname: // skip slashes if we're a directory @@ -1538,7 +1543,7 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, } // found path - if (name[0] == '\0') { + if (*name == '\0') { return tag; } diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 16430f01..aefcd203 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -3216,6 +3216,58 @@ code = ''' lfs_unmount(&lfs) => 0; ''' +# test an empty path, this should error +[cases.test_paths_empty] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + struct lfs_info info; + + // create empty, this should error + if (DIR) { + lfs_mkdir(&lfs, "") => LFS_ERR_INVAL; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + } + + // stat empty + lfs_stat(&lfs, "", &info) => LFS_ERR_INVAL; + + // file open empty, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "", + LFS_O_RDONLY) => LFS_ERR_INVAL; + + // dir open empty, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "") => LFS_ERR_INVAL; + lfs_dir_close(&lfs, &dir) => 0; + + // rename empty, this should error + lfs_rename(&lfs, "", "coffee") => LFS_ERR_INVAL; + + lfs_mkdir(&lfs, "coffee") => 0; + lfs_rename(&lfs, "coffee", "") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee") => 0; + + lfs_rename(&lfs, "", "") => LFS_ERR_INVAL; + + // stat empty + lfs_stat(&lfs, "", &info) => LFS_ERR_INVAL; + + // remove empty, this should error + lfs_remove(&lfs, "") => LFS_ERR_INVAL; + + // stat empty + lfs_stat(&lfs, "", &info) => LFS_ERR_INVAL; + + lfs_unmount(&lfs) => 0; +''' + # root operations # # POSIX deviations: @@ -3294,7 +3346,6 @@ code = ''' // create root, this should error if (DIR) { lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; - lfs_mkdir(&lfs, "") => LFS_ERR_EXIST; lfs_mkdir(&lfs, ".") => LFS_ERR_EXIST; lfs_mkdir(&lfs, "./") => LFS_ERR_EXIST; lfs_mkdir(&lfs, "/.") => LFS_ERR_EXIST; @@ -3303,8 +3354,6 @@ code = ''' lfs_file_t file; lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, ".", LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "./", @@ -3319,9 +3368,6 @@ code = ''' lfs_stat(&lfs, "/", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, ".", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); @@ -3339,8 +3385,6 @@ code = ''' lfs_file_t file; lfs_file_open(&lfs, &file, "/", LFS_O_RDONLY) => LFS_ERR_ISDIR; - lfs_file_open(&lfs, &file, "", - LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, ".", LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "./", @@ -3354,8 +3398,6 @@ code = ''' lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "/") => 0; lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "") => 0; - lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, ".") => 0; lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, "./") => 0; @@ -3367,7 +3409,6 @@ code = ''' // rename root, this should error lfs_rename(&lfs, "/", "coffee") => LFS_ERR_INVAL; - lfs_rename(&lfs, "", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, ".", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, "./", "coffee") => LFS_ERR_INVAL; lfs_rename(&lfs, "/.", "coffee") => LFS_ERR_INVAL; @@ -3375,7 +3416,6 @@ code = ''' lfs_mkdir(&lfs, "coffee") => 0; lfs_rename(&lfs, "coffee", "/") => LFS_ERR_INVAL; - lfs_rename(&lfs, "coffee", "") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", ".") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", "./") => LFS_ERR_INVAL; lfs_rename(&lfs, "coffee", "/.") => LFS_ERR_INVAL; @@ -3383,7 +3423,6 @@ code = ''' lfs_remove(&lfs, "coffee") => 0; lfs_rename(&lfs, "/", "/") => LFS_ERR_INVAL; - lfs_rename(&lfs, "", "") => LFS_ERR_INVAL; lfs_rename(&lfs, ".", ".") => LFS_ERR_INVAL; lfs_rename(&lfs, "..", "..") => LFS_ERR_INVAL; lfs_rename(&lfs, "./", "./") => LFS_ERR_INVAL; @@ -3394,9 +3433,6 @@ code = ''' lfs_stat(&lfs, "/", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, ".", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); @@ -3412,7 +3448,6 @@ code = ''' // remove root, this should error lfs_remove(&lfs, "/") => LFS_ERR_INVAL; - lfs_remove(&lfs, "") => LFS_ERR_INVAL; lfs_remove(&lfs, ".") => LFS_ERR_INVAL; lfs_remove(&lfs, "./") => LFS_ERR_INVAL; lfs_remove(&lfs, "/.") => LFS_ERR_INVAL; @@ -3422,9 +3457,6 @@ code = ''' lfs_stat(&lfs, "/", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_stat(&lfs, "", &info) => 0; - assert(strcmp(info.name, "/") == 0); - assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, ".", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); From 30947054d4a3f59300fc2f7bd66f7727cd911cd8 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 25 Nov 2024 14:26:50 -0600 Subject: [PATCH 7/9] paths: Extended tests to cover open with CREAT/EXCL These flags change the behavior of open quite significantly. It's useful to cover these in our path tests so the behavior is locked down. --- tests/test_paths.toml | 1318 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1294 insertions(+), 24 deletions(-) diff --git a/tests/test_paths.toml b/tests/test_paths.toml index aefcd203..4b9d280c 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -74,6 +74,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "coffee/thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "coffee/drip", @@ -94,6 +120,38 @@ code = ''' lfs_file_open(&lfs, &file, "coffee/thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -265,6 +323,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/coffee/thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/coffee/drip", @@ -285,6 +369,38 @@ code = ''' lfs_file_open(&lfs, &file, "/coffee/thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -454,6 +570,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "//////coffee//////thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/coffee/drip", @@ -474,6 +616,38 @@ code = ''' lfs_file_open(&lfs, &file, "//////coffee//////thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -668,6 +842,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "coffee/thai//////", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/drip/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew//", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish///", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai//////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/drip/", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/coldbrew//", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/turkish///", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/tubruk////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/vietnamese/////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/thai//////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "coffee/drip/", @@ -682,6 +882,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/thai//////", LFS_O_RDONLY) => LFS_ERR_NOTDIR; + + lfs_file_open(&lfs, &file, "coffee/drip/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew//", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/turkish///", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/thai//////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + + lfs_file_open(&lfs, &file, "coffee/drip/", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew//", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/turkish///", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/thai//////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; } // dir open paths, only works on dirs! @@ -949,6 +1175,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/coffee/drip", @@ -969,6 +1221,38 @@ code = ''' lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -1178,8 +1462,34 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "coffee/thai/./././././.", LFS_O_RDONLY) => LFS_ERR_ISDIR; - } else { - lfs_file_t file; + + lfs_file_open(&lfs, &file, "coffee/drip/.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/./././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/././././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai/./././././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/drip/.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/turkish/././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/tubruk/./././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/vietnamese/././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/thai/./././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + } else { + lfs_file_t file; lfs_file_open(&lfs, &file, "coffee/drip/.", LFS_O_RDONLY) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", @@ -1192,6 +1502,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/thai/./././././.", LFS_O_RDONLY) => LFS_ERR_NOTDIR; + + lfs_file_open(&lfs, &file, "coffee/drip/.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/./././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/././././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/thai/./././././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + + lfs_file_open(&lfs, &file, "coffee/drip/.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/./.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk/./././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese/././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coffee/thai/./././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; } // dir open paths, only works on dirs! @@ -1503,6 +1839,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/coffee/drip", @@ -1523,6 +1885,38 @@ code = ''' lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -1720,6 +2114,32 @@ code = ''' lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/drip/..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish/../../..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + + lfs_file_open(&lfs, &file, "coffee/drip/..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/coldbrew/../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/turkish/../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/tubruk/../../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/vietnamese/../../../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/thai/../../../../../..", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + // dir open paths, only works on dirs! lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "coffee/drip/..") => 0; @@ -1923,6 +2343,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/no/./../turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/no/./../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/coffee/drip", @@ -1943,6 +2389,38 @@ code = ''' lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/./../turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/no/./../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -2113,6 +2591,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/coffee/.../thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/coffee/.../drip", @@ -2133,6 +2637,38 @@ code = ''' lfs_file_open(&lfs, &file, "/coffee/.../thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -2303,6 +2839,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "/coffee/......thai", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "/coffee/.drip", @@ -2323,19 +2885,51 @@ code = ''' lfs_file_open(&lfs, &file, "/coffee/......thai", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; - } - // dir open paths, only works on dirs! - if (DIR) { - lfs_dir_t dir; - lfs_dir_open(&lfs, &dir, "/coffee/.drip") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/coffee/..coldbrew") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/coffee/...turkish") => 0; - lfs_dir_close(&lfs, &dir) => 0; - lfs_dir_open(&lfs, &dir, "/coffee/....tubruk") => 0; - lfs_dir_close(&lfs, &dir) => 0; + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/..coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/...turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/....tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, "/coffee/.....vietnamese") => 0; lfs_dir_close(&lfs, &dir) => 0; lfs_dir_open(&lfs, &dir, "/coffee/......thai") => 0; @@ -2505,6 +3099,32 @@ code = ''' lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + // dir open paths, only works on dirs! lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "/../coffee/drip") => LFS_ERR_INVAL; @@ -2852,6 +3472,32 @@ code = ''' lfs_file_open(&lfs, &file, "coffee_/thai", LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_offee/drip", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "c_ffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "co_fee/turkish", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "cof_ee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee_/thai", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + + lfs_file_open(&lfs, &file, "_offee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "c_ffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "co_fee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "cof_ee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee_/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + // dir open paths, only works on dirs! lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "_offee/drip") => LFS_ERR_NOENT; @@ -3056,6 +3702,32 @@ code = ''' lfs_file_open(&lfs, &file, "thai/coffee", LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "drip/coffee", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coldbrew/coffee", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "turkish/coffee", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "tubruk/coffee", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "vietnamese/coffee", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "thai/coffee", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; + + lfs_file_open(&lfs, &file, "drip/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coldbrew/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "turkish/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "tubruk/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "vietnamese/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "thai/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + // dir open paths, only works on dirs! lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "drip/coffee") => LFS_ERR_NOTDIR; @@ -3242,6 +3914,12 @@ code = ''' lfs_file_open(&lfs, &file, "", LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_INVAL; + + lfs_file_open(&lfs, &file, "", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_INVAL; + // dir open empty, only works on dirs! lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "") => LFS_ERR_INVAL; @@ -3304,6 +3982,12 @@ code = ''' lfs_file_open(&lfs, &file, "/", LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + // dir open root, only works on dirs! lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "/") => 0; @@ -3394,6 +4078,28 @@ code = ''' lfs_file_open(&lfs, &file, "//", LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, ".", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "./", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, ".", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "./", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "/.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "//", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + // dir open root, only works on dirs! lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "/") => 0; @@ -3484,6 +4190,11 @@ code = ''' struct lfs_info info; lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT; + // file open littlefs, which shouldn't exist + lfs_file_t file; + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_RDONLY) => LFS_ERR_NOENT; + // dir open littlefs, which shouldn't exist lfs_dir_t dir; lfs_dir_open(&lfs, &dir, "littlefs") => LFS_ERR_NOENT; @@ -3530,11 +4241,24 @@ code = ''' lfs_file_t file; lfs_file_open(&lfs, &file, "littlefs", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "littlefs", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open littlefs, only works on dirs! @@ -3786,6 +4510,44 @@ code = ''' sprintf(path, "%s/%s", c_name, f_name); lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => LFS_ERR_ISDIR; + + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; sprintf(path, "%s/%s", c_name, a_name); @@ -3812,6 +4574,50 @@ code = ''' lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -3943,7 +4749,7 @@ code = ''' lfs_unmount(&lfs) => 0; ''' -# a quick utf8 test, though utf8 is easy to support +# a quick utf8 test, utf8 is easy to support [cases.test_paths_utf8] defines.DIR = [false, true] code = ''' @@ -4018,6 +4824,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "coffee/dripcoffee", @@ -4038,6 +4870,38 @@ code = ''' lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -4207,19 +5071,45 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", LFS_O_RDONLY) => LFS_ERR_ISDIR; - } else { - lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", - LFS_O_RDONLY) => 0; - lfs_file_close(&lfs, &file) => 0; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", - LFS_O_RDONLY) => 0; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", LFS_O_RDONLY) => 0; @@ -4227,6 +5117,38 @@ code = ''' lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -4396,6 +5318,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "c o f f e e/t h a i", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "c o f f e e/d r i p", @@ -4416,6 +5364,38 @@ code = ''' lfs_file_open(&lfs, &file, "c o f f e e/t h a i", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -4587,6 +5567,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, " / ", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, " / ", @@ -4607,6 +5613,38 @@ code = ''' lfs_file_open(&lfs, &file, " / ", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -4778,6 +5816,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "\x0c/\x06", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "\x0c/\x01", @@ -4798,6 +5862,38 @@ code = ''' lfs_file_open(&lfs, &file, "\x0c/\x06", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -4969,6 +6065,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "\x7f/\x7f", @@ -4989,6 +6111,38 @@ code = ''' lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -5162,6 +6316,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "\xc0/\xf0", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "\xc0/\xa0", @@ -5182,6 +6362,38 @@ code = ''' lfs_file_open(&lfs, &file, "\xc0/\xf0", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! @@ -5355,6 +6567,32 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_ISDIR; lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", LFS_O_RDONLY) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } else { lfs_file_t file; lfs_file_open(&lfs, &file, "\xff/\xff", @@ -5375,6 +6613,38 @@ code = ''' lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", LFS_O_RDONLY) => 0; lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_close(&lfs, &file) => 0; + + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; } // dir open paths, only works on dirs! From b735c8fd7f948e4db34f063c52086b802d095f28 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 25 Nov 2024 15:16:01 -0600 Subject: [PATCH 8/9] paths: Added tests over NOENT + trailing slash/dot - test_paths_noent_trailing_slashes - test_paths_noent_trailing_dots - test_paths_noent_trailing_dotdots These managed to slip through our path testing but should be tested, if anything just to know exactly what errors these return. --- tests/test_paths.toml | 682 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 670 insertions(+), 12 deletions(-) diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 4b9d280c..d8ae57f9 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -3198,23 +3198,23 @@ code = ''' // here's a weird one, what happens if our rename is also a noop? lfs_rename(&lfs, - "/../coffee/drip", - "/../espresso/espresso") => LFS_ERR_INVAL; + "/no/../../../../coffee/drip", + "/no/../../../../coffee/drip") => LFS_ERR_INVAL; lfs_rename(&lfs, - "/../../coffee/coldbrew", - "/../../espresso/americano") => LFS_ERR_INVAL; + "/no/../../../coffee/coldbrew", + "/no/../../../coffee/coldbrew") => LFS_ERR_INVAL; lfs_rename(&lfs, - "/../../../coffee/turkish", - "/../../../espresso/macchiato") => LFS_ERR_INVAL; + "/no/../../coffee/turkish", + "/no/../../coffee/turkish") => LFS_ERR_INVAL; lfs_rename(&lfs, - "/no/../../coffee/tubruk", - "/no/../../espresso/latte") => LFS_ERR_INVAL; + "/../../../coffee/tubruk", + "/../../../coffee/tubruk") => LFS_ERR_INVAL; lfs_rename(&lfs, - "/no/../../../coffee/vietnamese", - "/no/../../../espresso/cappuccino") => LFS_ERR_INVAL; + "/../../coffee/vietnamese", + "/../../coffee/vietnamese") => LFS_ERR_INVAL; lfs_rename(&lfs, - "/no/../../../../coffee/thai", - "/no/../../../../espresso/mocha") => LFS_ERR_INVAL; + "/../coffee/thai", + "/../coffee/thai") => LFS_ERR_INVAL; // remove paths lfs_remove(&lfs, "/../espresso/espresso") => LFS_ERR_INVAL; @@ -3347,6 +3347,26 @@ code = ''' "coffee/thai_", "espresso/mocha") => LFS_ERR_NOENT; + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "coffee/_rip", + "coffee/_rip") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew", + "coffee/c_ldbrew") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish", + "coffee/tu_kish") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk", + "coffee/tub_uk") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese", + "coffee/_vietnamese") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_", + "coffee/thai_") => LFS_ERR_NOENT; + // remove paths lfs_remove(&lfs, "coffee/_rip") => LFS_ERR_NOENT; lfs_remove(&lfs, "coffee/c_ldbrew") => LFS_ERR_NOENT; @@ -3888,6 +3908,644 @@ code = ''' lfs_unmount(&lfs) => 0; ''' +# noent tests with trailing slashes +[cases.test_paths_noent_trailing_slashes] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "coffee/_rip//////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/c_ldbrew/////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tu_kish////", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tub_uk///", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/_vietnamese//", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai_/", &info) => LFS_ERR_NOENT; + + // file open paths, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/_rip/", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew//", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tu_kish///", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tub_uk////", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/_vietnamese/////", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai_//////", + LFS_O_RDONLY) => LFS_ERR_NOENT; + + lfs_file_open(&lfs, &file, "coffee/_rip/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew//", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tu_kish///", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tub_uk////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/_vietnamese/////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai_//////", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + + lfs_file_open(&lfs, &file, "coffee/_rip/", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew//", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tu_kish///", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tub_uk////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/_vietnamese/////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai_//////", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/_rip/") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/c_ldbrew//") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tu_kish///") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tub_uk////") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/_vietnamese/////") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/thai_//////") => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "coffee/_rip//////", + "espresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew/////", + "espresso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish////", + "espresso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk///", + "espresso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese//", + "espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_/", + "espresso/mocha") => LFS_ERR_NOENT; + + // bad destination + lfs_rename(&lfs, + "coffee/_rip", + "espresso/espresso/") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew", + "espresso/americano//") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish", + "espresso/macchiato///") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk", + "espresso/latte////") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese", + "espresso/cappuccino/////") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_", + "espresso/mocha//////") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/_rip//////", + "espresso/espresso/") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew/////", + "espresso/americano//") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish////", + "espresso/macchiato///") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk///", + "espresso/latte////") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese//", + "espresso/cappuccino/////") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_/", + "espresso/mocha//////") => LFS_ERR_NOENT; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "coffee/_rip//////", + "coffee/_rip//////") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew/////", + "coffee/c_ldbrew/////") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish////", + "coffee/tu_kish////") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk///", + "coffee/tub_uk///") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese//", + "coffee/_vietnamese//") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_/", + "coffee/thai_/") => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "coffee/_rip/") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/c_ldbrew//") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tu_kish///") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tub_uk////") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/_vietnamese/////") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/thai_//////") => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' + +# noent tests with trailing dots +[cases.test_paths_noent_trailing_dots] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "coffee/_rip/./././././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/c_ldbrew/././././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tu_kish/./././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tub_uk/././.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/_vietnamese/./.", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai_/.", &info) => LFS_ERR_NOENT; + + // file open paths, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/_rip/.", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew/./.", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tu_kish/././.", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tub_uk/./././.", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/_vietnamese/././././.", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai_/./././././.", + LFS_O_RDONLY) => LFS_ERR_NOENT; + + lfs_file_open(&lfs, &file, "coffee/_rip/.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew/./.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tu_kish/././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tub_uk/./././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/_vietnamese/././././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai_/./././././.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOENT; + + lfs_file_open(&lfs, &file, "coffee/_rip/.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew/./.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tu_kish/././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tub_uk/./././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/_vietnamese/././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai_/./././././.", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/_rip/.") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/c_ldbrew/./.") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tu_kish/././.") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tub_uk/./././.") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/_vietnamese/././././.") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/thai_/./././././.") => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "coffee/_rip/./././././.", + "espresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew/././././.", + "espresso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish/./././.", + "espresso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk/././.", + "espresso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese/./.", + "espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_/.", + "espresso/mocha") => LFS_ERR_NOENT; + + // bad destination + lfs_rename(&lfs, + "coffee/_rip", + "espresso/espresso/.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew", + "espresso/americano/./.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish", + "espresso/macchiato/././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk", + "espresso/latte/./././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese", + "espresso/cappuccino/././././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_", + "espresso/mocha/./././././.") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/_rip/./././././.", + "espresso/espresso/.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew/././././.", + "espresso/americano/./.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish/./././.", + "espresso/macchiato/././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk/././.", + "espresso/latte/./././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese/./.", + "espresso/cappuccino/././././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_/.", + "espresso/mocha/./././././.") => LFS_ERR_NOENT; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "coffee/_rip/./././././.", + "coffee/_rip/./././././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew/././././.", + "coffee/c_ldbrew/././././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish/./././.", + "coffee/tu_kish/./././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk/././.", + "coffee/tub_uk/././.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese/./.", + "coffee/_vietnamese/./.") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_/.", + "coffee/thai_/.") => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "coffee/_rip/.") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/c_ldbrew/./.") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tu_kish/././.") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tub_uk/./././.") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/_vietnamese/././././.") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/thai_/./././././.") => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' + +# noent tests with trailing dotdots +[cases.test_paths_noent_trailing_dotdots] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "coffee/_rip/../../../../../..", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "coffee/c_ldbrew/../../../../..", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "coffee/tu_kish/../../../..", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "coffee/tub_uk/../../..", &info) => LFS_ERR_INVAL; + lfs_stat(&lfs, "coffee/_vietnamese/../..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "coffee/thai_/..", &info) => 0; + assert(strcmp(info.name, "coffee") == 0); + assert(info.type == LFS_TYPE_DIR); + + // file open paths, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/_rip/..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew/../..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tu_kish/../../..", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/tub_uk/../../../..", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/_vietnamese/../../../../..", + LFS_O_RDONLY) => LFS_ERR_INVAL; + lfs_file_open(&lfs, &file, "coffee/thai_/../../../../../..", + LFS_O_RDONLY) => LFS_ERR_INVAL; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/_rip/..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/c_ldbrew/../..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/tu_kish/../../..") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "coffee/tub_uk/../../../..") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "coffee/_vietnamese/../../../../..") => LFS_ERR_INVAL; + lfs_dir_open(&lfs, &dir, "coffee/thai_/../../../../../..") => LFS_ERR_INVAL; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "coffee/_rip/../../../../../..", + "espresso/espresso") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/c_ldbrew/../../../../..", + "espresso/americano") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tu_kish/../../../..", + "espresso/macchiato") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tub_uk/../../..", + "espresso/latte") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/_vietnamese/../..", + "espresso/cappuccino") => LFS_ERR_INVAL; + // this one works + lfs_rename(&lfs, + "coffee/thai_/..", + "espresso/mocha") => 0; + lfs_rename(&lfs, + "espresso/mocha", + "coffee") => 0; + + // bad destination + lfs_rename(&lfs, + "coffee/_rip", + "espresso/espresso/..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew", + "espresso/americano/../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish", + "espresso/macchiato/../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk", + "espresso/latte/../../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese", + "espresso/cappuccino/../../../../..") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_", + "espresso/mocha/../../../../../..") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "coffee/_rip/../../../../../..", + "espresso/espresso/..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/c_ldbrew/../../../../..", + "espresso/americano/../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tu_kish/../../../..", + "espresso/macchiato/../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tub_uk/../../..", + "espresso/latte/../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/_vietnamese/../..", + "espresso/cappuccino/../../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/thai_/..", + "espresso/mocha/../../../../../..") => LFS_ERR_INVAL; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "coffee/_rip/../../../../../..", + "coffee/_rip/../../../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/c_ldbrew/../../../../..", + "coffee/c_ldbrew/../../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tu_kish/../../../..", + "coffee/tu_kish/../../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/tub_uk/../../..", + "coffee/tub_uk/../../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/_vietnamese/../..", + "coffee/_vietnamese/../..") => LFS_ERR_INVAL; + lfs_rename(&lfs, + "coffee/thai_/..", + "coffee/thai_/..") => 0; + + // remove paths + lfs_remove(&lfs, "coffee/_rip/..") => LFS_ERR_NOTEMPTY; + lfs_remove(&lfs, "coffee/c_ldbrew/../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/tu_kish/../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/tub_uk/../../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/_vietnamese/../../../../..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee/thai_/../../../../../..") => LFS_ERR_INVAL; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' + # test an empty path, this should error [cases.test_paths_empty] defines.DIR = [false, true] From 999ef6656f13eeaa0de7f7d880ba6d1937aa60dd Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 25 Nov 2024 15:22:33 -0600 Subject: [PATCH 9/9] paths: Changed CREAT with a trailing slash to return NOTDIR - before: lfs_file_open("missing/") => LFS_ERR_ISDIR - after: lfs_file_open("missing/") => LFS_ERR_NOTDIR As noted by bmcdonnell-fb, returning LFS_ERR_ISDIR here was inconsistent with the case where the file exists: case before after lfs_file_open("dir_a") => LFS_ERR_ISDIR LFS_ERR_ISDIR lfs_file_open("dir_a/") => LFS_ERR_ISDIR LFS_ERR_ISDIR lfs_file_open("reg_a/") => LFS_ERR_NOTDIR LFS_ERR_NOTDIR lfs_file_open("missing_a/") => LFS_ERR_ISDIR LFS_ERR_NOTDIR Note this is consistent with the behavior of lfs_stat: lfs_file_open("reg_a/") => LFS_ERR_NOTDIR lfs_stat("reg_a/") => LFS_ERR_NOTDIR And the only other function that can "create" files, lfs_rename: lfs_file_open("missing_a/") => LFS_ERR_NOTDIR lfs_rename("reg_a", "missing_a/") => LFS_ERR_NOTDIR There is some ongoing discussion about if these should return NOTDIR, ISDIR, or INVAL, but this is at least an improvement over the rename/open mismatch. --- lfs.c | 2 +- tests/test_paths.toml | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lfs.c b/lfs.c index 94d23f7b..b46cca5b 100644 --- a/lfs.c +++ b/lfs.c @@ -3109,7 +3109,7 @@ static int lfs_file_opencfg_(lfs_t *lfs, lfs_file_t *file, // don't allow trailing slashes if (lfs_path_isdir(path)) { - err = LFS_ERR_ISDIR; + err = LFS_ERR_NOTDIR; goto cleanup; } diff --git a/tests/test_paths.toml b/tests/test_paths.toml index d8ae57f9..29574fa1 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -764,17 +764,17 @@ code = ''' } else { lfs_file_t file; lfs_file_open(&lfs, &file, "coffee/drip/", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/coldbrew//", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/turkish///", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/tubruk////", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/vietnamese/////", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/thai//////", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; // still create so we have something to test lfs_file_open(&lfs, &file, "coffee/drip", @@ -3972,30 +3972,30 @@ code = ''' LFS_O_RDONLY) => LFS_ERR_NOENT; lfs_file_open(&lfs, &file, "coffee/_rip/", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/c_ldbrew//", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/tu_kish///", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/tub_uk////", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/_vietnamese/////", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/thai_//////", - LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/_rip/", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/c_ldbrew//", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/tu_kish///", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/tub_uk////", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/_vietnamese/////", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; lfs_file_open(&lfs, &file, "coffee/thai_//////", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_ISDIR; + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; // dir open paths, only works on dirs! lfs_dir_t dir;