libc: add dirent tests#475
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive suite of POSIX-compliant tests for directory operations, including opendir, closedir, readdir, and rewinddir. The feedback identifies critical issues in the test implementation, specifically potential buffer overflows in readdir and closedir due to missing bounds checks and undersized buffers for directory names. Additionally, a redundant test definition was identified in the Makefile.
6ffcd5b to
0bbefdc
Compare
54efad0 to
feaac4b
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive test suite for POSIX dirent.h functions, including opendir, closedir, readdir, and rewinddir. The review identified several critical issues: potential out-of-bounds access and buffer overflows in opendir.c, incorrect process handling after a failed fork() in readdir.c, and a potential NULL pointer dereference during cleanup in test_create_directories. Additionally, improvements were suggested for the d_ino_in helper to avoid false positives when checking inode numbers.
feaac4b to
fb28d68
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive test suite for POSIX.1-2017 dirent.h functions, including opendir(), closedir(), readdir(), and rewinddir(). The tests cover various scenarios such as empty and non-empty directories, permission handling, symlink loops, and thread safety. Review feedback identifies a potential buffer overflow in a test error message, suggests containing test-generated directories within a managed path to ensure proper cleanup, recommends consistent use of assertion macros for directory creation, and proposes expanding CI target coverage to include architectures mentioned in the PR description.
fb28d68 to
5f5a34c
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request adds a comprehensive test suite for POSIX directory functions (opendir, closedir, readdir, and rewinddir) to the Phoenix-RTOS libc, along with helper macros and CI integration. Feedback focuses on improving code safety and readability by suggesting snprintf over sprintf, removing redundant type casts in memory management, and fixing a typo in the source comments.
c3383bd to
69a6434
Compare
69a6434 to
f9e4718
Compare
| #include <string.h> | ||
|
|
||
|
|
||
| #define TEST_MKDIR_ASSERTED(path, mode) TEST_ASSERT_TRUE_MESSAGE(mkdir(path, mode) != -1 || errno == EEXIST, strerror(errno)) |
There was a problem hiding this comment.
Uses EEXIST, but not include <errno.h>
There was a problem hiding this comment.
Good catch. It's now included, thanks
f9e4718 to
61debf2
Compare
| sprintf(dirPath, MAIN_DIR "/%d", i); | ||
|
|
||
| TEST_MKDIR_ASSERTED(dirPath, S_IRUSR); | ||
| } |
There was a problem hiding this comment.
If the assertion fails, the test exits and previously created directories are not removed. TEST_TEAR_DOWN will not remove them since rmdir only removes empty directories. Similar issue in other tests.
| { | ||
| errno = 0; | ||
|
|
||
| TEST_ASSERT_EQUAL_INT(0, test_create_directories(20)); |
There was a problem hiding this comment.
test_create_directories is only called here and that's the only thing this test does. Is there a reason to move the logic to a separate function rather than placing it in the test directly like in other tests?
There was a problem hiding this comment.
Fixed, moved the code to the case where it should've been
| #include <unity.h> | ||
|
|
||
|
|
||
| #define TEST_MKDIR_ASSERTED(path, mode) TEST_ASSERT_TRUE_MESSAGE(mkdir(path, mode) != -1 || errno == EEXIST, strerror(errno)) |
There was a problem hiding this comment.
This will succeed if the path already exists, even if it's not a directory.
There was a problem hiding this comment.
True, now it only passes if the directory is newly made - up for a debate, but I think the strict approach is better
| strcpy(mutualLoop, MAIN_DIR "/D1"); | ||
|
|
||
| /* Create a path to a valid symloop */ | ||
| /* Posix says that symloops up to */ |
|
|
||
| /* Add a few layers of symloops, so it is too deep (selfLoop is not empty at this point) */ | ||
| for (int i = 0; i < symloopMax / 2 - 1; ++i) { | ||
| if (strlen(selfLoop) + 10 >= PATH_MAX || strlen(mutualLoop) + 10 >= PATH_MAX) { |
There was a problem hiding this comment.
It's not clear where the number 10 comes from, maybe use a named constant or add a comment
| TEST_MKDIR_ASSERTED(MAIN_DIR, 0700); | ||
|
|
||
| mkdir(MAIN_DIR "/dir1", S_IRUSR | S_IWUSR | S_IXUSR); | ||
| mkdir(MAIN_DIR "/dir2", S_IRUSR | S_IWUSR | S_IXUSR); | ||
|
|
||
| mkdir(MAIN_DIR "/dir1/nest1", S_IRUSR); | ||
| mkdir(MAIN_DIR "/dir1/nest2", S_IRUSR); | ||
|
|
||
| mkdir(MAIN_DIR "/dir2/nest1", S_IRUSR); | ||
| mkdir(MAIN_DIR "/dir2/nest2", S_IRUSR); | ||
|
|
||
| int files[] = { | ||
| creat(MAIN_DIR "/file1.txt", S_IRUSR), | ||
| creat(MAIN_DIR "/file2.dat", S_IRUSR), | ||
| creat(MAIN_DIR "/file3.json", S_IRUSR) | ||
| }; | ||
|
|
||
| close(files[0]); | ||
| close(files[1]); | ||
| close(files[2]); |
There was a problem hiding this comment.
Success of MAIN_DIR creation is asserted but the rest of the setup my fail silently.
| rewinddir(dp); | ||
|
|
||
| void *ret = readdir(dp); | ||
| (void)ret; |
There was a problem hiding this comment.
Why is the result of readdir after rewinddir not checked?
There was a problem hiding this comment.
It was assumed to be NULL but now I put an assertion in place. Thanks
| errno = 0; | ||
| TEST_MKDIR_ASSERTED(MAIN_DIR, S_IRWXU); | ||
| errno = 0; | ||
| TEST_MKDIR_ASSERTED(MAIN_DIR "/dir1", S_IRUSR); |
There was a problem hiding this comment.
Here errno is set before TEST_MKDIR_ASSERTED while in other test groups it's not. I don't think it's necessary here because the macro is only checking errno if mkdir fails.
61debf2 to
adff8e7
Compare
adff8e7 to
23ce160
Compare
884f938 to
4371302
Compare
79aaff4 to
40f2647
Compare
JIRA: CI-359
Some tests needed refactoring and logic fixes, and proper clean-ups. There were also a couple of gaps in the coverage of the test suite that had to be filled. JIRA: CI-359 Assisted-by: Claude Opus 4.8
40f2647 to
4818906
Compare
Adds a test coverage for
dirent.hfunctions.Description
The coverage includes:
readdir()closedir()opendir()rewinddir()Ensures the functions are POSIX compliant.
Motivation and Context
Ensures a fuller test coverage of libc functions
Types of changes
How Has This Been Tested?
Checklist:
Special treatment