Skip to content

Commit 815f0d8

Browse files
committed
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.
1 parent dc92dec commit 815f0d8

File tree

2 files changed

+195
-1
lines changed

2 files changed

+195
-1
lines changed

lfs.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,9 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
15221522
break;
15231523
}
15241524

1525-
if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) {
1525+
if (sufflen == 1 && memcmp(suffix, ".", 1) == 0) {
1526+
// noop
1527+
} else if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) {
15261528
depth -= 1;
15271529
if (depth == 0) {
15281530
name = suffix + sufflen;

tests/test_paths.toml

+192
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,198 @@ code = '''
18451845
lfs_unmount(&lfs) => 0;
18461846
'''
18471847

1848+
# dot dot dot path tests
1849+
[cases.test_paths_dot_dotdots]
1850+
defines.DIR = [false, true]
1851+
code = '''
1852+
lfs_t lfs;
1853+
lfs_format(&lfs, cfg) => 0;
1854+
lfs_mount(&lfs, cfg) => 0;
1855+
1856+
// create paths
1857+
lfs_mkdir(&lfs, "no") => 0;
1858+
lfs_mkdir(&lfs, "no/no") => 0;
1859+
lfs_mkdir(&lfs, "coffee") => 0;
1860+
lfs_mkdir(&lfs, "coffee/no") => 0;
1861+
if (DIR) {
1862+
lfs_mkdir(&lfs, "/coffee/drip") => 0;
1863+
lfs_mkdir(&lfs, "/no/./../coffee/coldbrew") => 0;
1864+
lfs_mkdir(&lfs, "/coffee/no/./../turkish") => 0;
1865+
lfs_mkdir(&lfs, "/no/no/./.././../coffee/tubruk") => 0;
1866+
lfs_mkdir(&lfs, "/no/no/./.././../coffee/no/./../vietnamese") => 0;
1867+
lfs_mkdir(&lfs, "/no/no/./.././../no/no/./.././../coffee/thai") => 0;
1868+
} else {
1869+
lfs_file_t file;
1870+
lfs_file_open(&lfs, &file, "/coffee/drip",
1871+
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
1872+
lfs_file_close(&lfs, &file) => 0;
1873+
lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew",
1874+
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
1875+
lfs_file_close(&lfs, &file) => 0;
1876+
lfs_file_open(&lfs, &file, "/coffee/no/./../turkish",
1877+
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
1878+
lfs_file_close(&lfs, &file) => 0;
1879+
lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk",
1880+
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
1881+
lfs_file_close(&lfs, &file) => 0;
1882+
lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese",
1883+
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
1884+
lfs_file_close(&lfs, &file) => 0;
1885+
lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai",
1886+
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
1887+
lfs_file_close(&lfs, &file) => 0;
1888+
}
1889+
1890+
// stat paths
1891+
struct lfs_info info;
1892+
lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../coffee/drip", &info) => 0;
1893+
assert(strcmp(info.name, "drip") == 0);
1894+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
1895+
lfs_stat(&lfs, "/no/no/./.././../coffee/no/./../coldbrew", &info) => 0;
1896+
assert(strcmp(info.name, "coldbrew") == 0);
1897+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
1898+
lfs_stat(&lfs, "/no/no/./.././../coffee/turkish", &info) => 0;
1899+
assert(strcmp(info.name, "turkish") == 0);
1900+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
1901+
lfs_stat(&lfs, "/coffee/no/./../tubruk", &info) => 0;
1902+
assert(strcmp(info.name, "tubruk") == 0);
1903+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
1904+
lfs_stat(&lfs, "/no/./../coffee/vietnamese", &info) => 0;
1905+
assert(strcmp(info.name, "vietnamese") == 0);
1906+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
1907+
lfs_stat(&lfs, "/coffee/thai", &info) => 0;
1908+
assert(strcmp(info.name, "thai") == 0);
1909+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
1910+
1911+
// file open paths, only works on files!
1912+
if (DIR) {
1913+
lfs_file_t file;
1914+
lfs_file_open(&lfs, &file, "/coffee/drip",
1915+
LFS_O_RDONLY) => LFS_ERR_ISDIR;
1916+
lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew",
1917+
LFS_O_RDONLY) => LFS_ERR_ISDIR;
1918+
lfs_file_open(&lfs, &file, "/coffee/no/./../turkish",
1919+
LFS_O_RDONLY) => LFS_ERR_ISDIR;
1920+
lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk",
1921+
LFS_O_RDONLY) => LFS_ERR_ISDIR;
1922+
lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese",
1923+
LFS_O_RDONLY) => LFS_ERR_ISDIR;
1924+
lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai",
1925+
LFS_O_RDONLY) => LFS_ERR_ISDIR;
1926+
} else {
1927+
lfs_file_t file;
1928+
lfs_file_open(&lfs, &file, "/coffee/drip",
1929+
LFS_O_RDONLY) => 0;
1930+
lfs_file_close(&lfs, &file) => 0;
1931+
lfs_file_open(&lfs, &file, "/no/./../coffee/coldbrew",
1932+
LFS_O_RDONLY) => 0;
1933+
lfs_file_close(&lfs, &file) => 0;
1934+
lfs_file_open(&lfs, &file, "/coffee/no/./../turkish",
1935+
LFS_O_RDONLY) => 0;
1936+
lfs_file_close(&lfs, &file) => 0;
1937+
lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/tubruk",
1938+
LFS_O_RDONLY) => 0;
1939+
lfs_file_close(&lfs, &file) => 0;
1940+
lfs_file_open(&lfs, &file, "/no/no/./.././../coffee/no/./../vietnamese",
1941+
LFS_O_RDONLY) => 0;
1942+
lfs_file_close(&lfs, &file) => 0;
1943+
lfs_file_open(&lfs, &file, "/no/no/./.././../no/no/./.././../coffee/thai",
1944+
LFS_O_RDONLY) => 0;
1945+
lfs_file_close(&lfs, &file) => 0;
1946+
}
1947+
1948+
// dir open paths, only works on dirs!
1949+
if (DIR) {
1950+
lfs_dir_t dir;
1951+
lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0;
1952+
lfs_dir_close(&lfs, &dir) => 0;
1953+
lfs_dir_open(&lfs, &dir, "/no/./../coffee/coldbrew") => 0;
1954+
lfs_dir_close(&lfs, &dir) => 0;
1955+
lfs_dir_open(&lfs, &dir, "/coffee/no/./../turkish") => 0;
1956+
lfs_dir_close(&lfs, &dir) => 0;
1957+
lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/tubruk") => 0;
1958+
lfs_dir_close(&lfs, &dir) => 0;
1959+
lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/no/./../vietnamese") => 0;
1960+
lfs_dir_close(&lfs, &dir) => 0;
1961+
lfs_dir_open(&lfs, &dir, "/no/no/./.././../no/no/./.././../coffee/thai") => 0;
1962+
lfs_dir_close(&lfs, &dir) => 0;
1963+
} else {
1964+
lfs_dir_t dir;
1965+
lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR;
1966+
lfs_dir_open(&lfs, &dir, "/no/./../coffee/coldbrew") => LFS_ERR_NOTDIR;
1967+
lfs_dir_open(&lfs, &dir, "/coffee/no/./../turkish") => LFS_ERR_NOTDIR;
1968+
lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/tubruk") => LFS_ERR_NOTDIR;
1969+
lfs_dir_open(&lfs, &dir, "/no/no/./.././../coffee/no/./../vietnamese") => LFS_ERR_NOTDIR;
1970+
lfs_dir_open(&lfs, &dir, "/no/no/./.././../no/no/./.././../coffee/thai") => LFS_ERR_NOTDIR;
1971+
}
1972+
1973+
// rename paths
1974+
lfs_mkdir(&lfs, "espresso") => 0;
1975+
lfs_rename(&lfs,
1976+
"/no/no/./.././../no/no/./.././../coffee/drip",
1977+
"/espresso/espresso") => 0;
1978+
lfs_rename(&lfs,
1979+
"/no/no/./.././../coffee/no/./../coldbrew",
1980+
"/no/./../espresso/americano") => 0;
1981+
lfs_rename(&lfs,
1982+
"/no/no/./.././../coffee/turkish",
1983+
"/espresso/no/./../macchiato") => 0;
1984+
lfs_rename(&lfs,
1985+
"/coffee/no/./../tubruk",
1986+
"/no/no/./.././../espresso/latte") => 0;
1987+
lfs_rename(&lfs,
1988+
"/no/./../coffee/vietnamese",
1989+
"/no/no/./.././../espresso/no/./../cappuccino") => 0;
1990+
lfs_rename(&lfs,
1991+
"/coffee/thai",
1992+
"/no/no/./.././../no/no/./.././../espresso/mocha") => 0;
1993+
1994+
// stat paths
1995+
lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../espresso/espresso", &info) => 0;
1996+
assert(strcmp(info.name, "espresso") == 0);
1997+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
1998+
lfs_stat(&lfs, "/no/no/./.././../espresso/no/./../americano", &info) => 0;
1999+
assert(strcmp(info.name, "americano") == 0);
2000+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
2001+
lfs_stat(&lfs, "/no/no/./.././../espresso/macchiato", &info) => 0;
2002+
assert(strcmp(info.name, "macchiato") == 0);
2003+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
2004+
lfs_stat(&lfs, "/espresso/no/./../latte", &info) => 0;
2005+
assert(strcmp(info.name, "latte") == 0);
2006+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
2007+
lfs_stat(&lfs, "/no/./../espresso/cappuccino", &info) => 0;
2008+
assert(strcmp(info.name, "cappuccino") == 0);
2009+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
2010+
lfs_stat(&lfs, "/espresso/mocha", &info) => 0;
2011+
assert(strcmp(info.name, "mocha") == 0);
2012+
assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG));
2013+
2014+
lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../coffee/drip", &info) => LFS_ERR_NOENT;
2015+
lfs_stat(&lfs, "/no/no/./.././../coffee/no/./../coldbrew", &info) => LFS_ERR_NOENT;
2016+
lfs_stat(&lfs, "/no/no/./.././../coffee/turkish", &info) => LFS_ERR_NOENT;
2017+
lfs_stat(&lfs, "/coffee/no/./../tubruk", &info) => LFS_ERR_NOENT;
2018+
lfs_stat(&lfs, "/no/./../coffee/vietnamese", &info) => LFS_ERR_NOENT;
2019+
lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT;
2020+
2021+
// remove paths
2022+
lfs_remove(&lfs, "/espresso/espresso") => 0;
2023+
lfs_remove(&lfs, "/no/./../espresso/americano") => 0;
2024+
lfs_remove(&lfs, "/espresso/no/./../macchiato") => 0;
2025+
lfs_remove(&lfs, "/no/no/./.././../espresso/latte") => 0;
2026+
lfs_remove(&lfs, "/no/no/./.././../espresso/no/./../cappuccino") => 0;
2027+
lfs_remove(&lfs, "/no/no/./.././../no/no/./.././../espresso/mocha") => 0;
2028+
2029+
// stat paths
2030+
lfs_stat(&lfs, "/no/no/./.././../no/no/./.././../espresso/espresso", &info) => LFS_ERR_NOENT;
2031+
lfs_stat(&lfs, "/no/no/./.././../espresso/no/./../americano", &info) => LFS_ERR_NOENT;
2032+
lfs_stat(&lfs, "/no/no/./.././../espresso/macchiato", &info) => LFS_ERR_NOENT;
2033+
lfs_stat(&lfs, "/espresso/no/./../latte", &info) => LFS_ERR_NOENT;
2034+
lfs_stat(&lfs, "/no/./../espresso/cappuccino", &info) => LFS_ERR_NOENT;
2035+
lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT;
2036+
2037+
lfs_unmount(&lfs) => 0;
2038+
'''
2039+
18482040
# dot dot dot path tests
18492041
[cases.test_paths_dotdotdots]
18502042
defines.DIR = [false, true]

0 commit comments

Comments
 (0)