Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/xmodem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ bool XModemAdapter::isValidFilename(const char *name)
{
if (!name || name[0] == '\0')
return false;
if (name[1] == ':')
return false;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
// Reject any ".." path component. Absolute paths and subdirectories are fine; they stay within
// the filesystem root, so only traversal out of it needs blocking.
for (const char *seg = name; *seg;) {
const char *slash = strchr(seg, '/');
const char *slash = strpbrk(seg, "/\\");
const size_t len = slash ? (size_t)(slash - seg) : strlen(seg);
if (len == 2 && seg[0] == '.' && seg[1] == '.')
return false;
Expand Down
18 changes: 18 additions & 0 deletions test/test_xmodem/test_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ void test_xmodem_rejects_dotdot_traversal(void)
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("/.."));
}

void test_xmodem_rejects_backslash_traversal(void)
{
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("..\\secret"));
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("..\\..\\Windows\\System32\\drivers\\etc\\hosts"));
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("dir\\..\\..\\x"));
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("dir/..\\x"));
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("dir\\.."));
}

void test_xmodem_rejects_drive_qualified(void)
{
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("C:\\Windows\\System32\\x"));
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("C:/Windows/System32/x"));
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("c:relative.txt"));
}

void test_xmodem_rejects_empty(void)
{
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename(""));
Expand All @@ -46,6 +62,8 @@ void setup()
UNITY_BEGIN();
#ifdef FSCom
RUN_TEST(test_xmodem_rejects_dotdot_traversal);
RUN_TEST(test_xmodem_rejects_backslash_traversal);
RUN_TEST(test_xmodem_rejects_drive_qualified);
RUN_TEST(test_xmodem_rejects_empty);
RUN_TEST(test_xmodem_allows_legit_paths);
#endif
Expand Down
Loading