fix(libc): check dirname result length

Find the directory component before checking the result buffer limit, matching FreeBSD 11.4. Preserve input and guest errno on success; overlong directory results still report ENAMETOOLONG.

AI-assisted: yes
This commit is contained in:
QRMOE 2026-10-11 16:23:53 +02:00 committed by GitHub
parent a11c8f7f70
commit f133aaa4b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 8 additions and 10 deletions

View File

@ -46,27 +46,25 @@ char* APS5_VABI dirname_nid_postfix(const char* path) {
}
auto length = std::strlen(path);
if (length >= sizeof(buffer)) {
errno = 63;
return nullptr;
}
std::memcpy(buffer, path, length + 1);
while (length > 0 && buffer[length - 1] == '/') --length;
while (length > 0 && path[length - 1] == '/') --length;
if (length == 0) {
buffer[0] = '/';
buffer[1] = '\0';
return buffer;
}
buffer[length] = '\0';
auto separator = length;
while (separator > 0 && buffer[separator - 1] != '/') --separator;
while (separator > 0 && path[separator - 1] != '/') --separator;
if (separator == 0) {
buffer[0] = '.';
buffer[1] = '\0';
return buffer;
}
while (separator > 1 && buffer[separator - 1] == '/') --separator;
while (separator > 1 && path[separator - 1] == '/') --separator;
if (separator >= sizeof(buffer)) {
errno = 63;
return nullptr;
}
std::memcpy(buffer, path, separator);
buffer[separator] = '\0';
return buffer;
}