Skip to content
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

Limit substring length in NiHeader::SetExportInfo #44

Merged
merged 1 commit into from
Aug 4, 2024

Conversation

xmusjackson
Copy link
Contributor

@xmusjackson xmusjackson commented Aug 4, 2024

When calling SetExportInfo with a string shorter than 255 to set only exportInfo1, the function works as expected. However, issues occur when attempting to set each member according to the comment above the declaration or when passing a string larger than 254 characters.

If one passes a string resized to 3 * 256 with the desired export items at position 0, 256, and 512 into SetExportInfo, the header's exportInfo members are set to 256 character strings containing the provided data, which appears correct initially. The issue occurs when NiString::Write is called on the export items; The string length is cast to a uint8_t and stored. The string is resized using the value of that integer, but since the string was set to 256 characters of the source by SetExportInfo and a uint8_t can't be larger than 255, the string is resized to 0. SetNullOutput is called with its default parameter and thus is set to true for these members so the uint8_t is incremented to 1. This is then written to the file along with the null terminator. This results in a nif with valid but empty export info items.

If the input string is set to one character shorter than a multiple of 256, the resulting nif will fail to load since the last exportInfo item to be set has a size of 255 during writing. The length is incremented to account for the null terminator, writing 0 for the size while the full string and null terminator are still written to the file.

Since a null terminated string whose size is stored as an 8-bit integer can only be 254 characters long, not including the null terminator, and since NiString::Write handles this logic by incrementing the size and writing a null terminator, NiHeader::SetExportInfo should only take a maximum of 254 characters from each position in the input string.

Edit: I was referring to SetExportInfo as SetExportItems for some reason

@xmusjackson xmusjackson changed the title Limit substring length in NiHeader::SetExportItems Limit substring length in NiHeader::SetExportInfo Aug 4, 2024
@ousnius
Copy link
Owner

ousnius commented Aug 4, 2024

Hello, thanks for the PR.
The incrementation needs to be adjusted as well. You can see the issue by running the following code: https://pastebin.com/U0Vi4Xha

@xmusjackson
Copy link
Contributor Author

That makes sense. I suppose I was worried about keeping the api stable in the case someone was using this function to set only a single exportInfo item, though I couldn't find any such situation.
The latest push should cover the incrementation change and works in my tests.

@ousnius
Copy link
Owner

ousnius commented Aug 4, 2024

I don't know of anything that makes export info strings that long. The function wasn't made with intentionally appending whitespace or null-bytes to a string for it to appear in the 2nd or 3rd export info fields.

@ousnius ousnius merged commit 1124519 into ousnius:main Aug 4, 2024
3 checks passed
@xmusjackson xmusjackson deleted the fix-setexportinfo branch August 8, 2024 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants