commit 953390185b209ae9115228e09215cac61c008711 from: Markus Uhlin via: GitHub date: Sat Aug 16 22:30:30 2025 UTC Potential fix for code scanning alert no. 6: Uncontrolled data used in path expression Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> commit - 84735034ed87be9473fe2fadbe6ad11a6b4e13bc commit + 953390185b209ae9115228e09215cac61c008711 blob - ad307549dfe244aead8140664d85dc8694246a09 blob + 1981c1422ee6ed11f45624514978c8a92fb8204e --- FICS/gamedb.c +++ FICS/gamedb.c @@ -1626,11 +1626,21 @@ OldestHistGame(char *login) char pFile[MAX_FILENAME_SIZE] = { '\0' }; long int when; - /* Validate login to prevent path traversal */ - if (strstr(login, "..") || strchr(login, '/') || strchr(login, '\\')) { + /* Validate login to prevent path traversal and restrict to safe characters */ + if (login == NULL || login[0] == '\0' || + strstr(login, "..") || strchr(login, '/') || strchr(login, '\\')) { warnx("%s: invalid login value: '%s'", __func__, login); return 0L; } + for (const char *p = login; *p; ++p) { + if (!((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + warnx("%s: invalid character in login: '%s'", __func__, login); + return 0L; + } + } msnprintf(pFile, sizeof pFile, "%s/player_data/%c/%s.%s", stats_dir, login[0], login, STATS_GAMES);