-
Notifications
You must be signed in to change notification settings - Fork 117
fix: replace strcpy with strlcpy and update length assertion #1796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: replace strcpy with strlcpy and update length assertion #1796
Conversation
Skyaero42
commented
Nov 4, 2025
- Split from: fix: Replace strcpy with strlcpy for robustness #1712
| strlcpy(w3d_name, start, min(W3D_NAME_LEN, num_chars)); | ||
| size_t num_chars = end - start; | ||
| const size_t nameLen = strlcpy(w3d_name, start, W3D_NAME_LEN); | ||
| (void)nameLen; WWASSERT(nameLen < num_chars); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const size_t strLen = end - start;
WWASSERT(strLen < ARRAY_SIZE(w3d_name));
strlcpy(w3d_name, start, min(ARRAY_SIZE(w3d_name), strLen+1));I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ARRAY_SIZE doesn't work with w3d_name because it is a pointer, using W3D_NAME_LEN instead
I removed the min because it is superfluous (the assert fires when ARRAY_SIZE(w3d_name) > strLen+1). In case the assert is disabled (retail), the min risks buffer overflow. Hence I used W3D_NAME_LEN here as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see this function gets a buffer and then assumes it is large enough to write. This is bad. According to web search this Get_W3D_Name function is never used. Can we remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strlcpy(w3d_name, start, W3D_NAME_LEN); is definitely wrong, because it means it will stop copying start at null terminator, and not at end where it is supposed to end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've undone the changes and will address it in a separate PR. I'm pretty sure we can remove the entire function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try this
static void Get_W3D_Name (const char *filename, char *w3d_name, size_t w3d_name_size)
{
assert(filename);
assert(w3d_name);
// Figure out the first character of the name of the file
// (bypass the path if it was given).
const char *start = strrchr(filename, '\\');
if (start)
++start; // point to first character after the last backslash
else
start = filename; // point to the start of the filename
// We don't want to copy the .w3d extension. Find where
// it occurs.
const char *end = strrchr(start, '.');
if (!end)
end = start + strlen(start); // point to the null character
// Copy all characters from start to end (excluding 'end')
// into the w3d_name buffer. Then capitalize the string.
size_t num_chars = end - start;
WWASSERT(num_chars < w3d_name_size);
strlcpy(w3d_name, start, min(w3d_name_size, num_chars));
strupr(w3d_name);
}a39d5c6 to
3e3c309
Compare