Closed Caball009 closed 1 week ago
@Rackover (you told me to ping you).
Thanks for pinging me, I'm not good enough with Huffman to assert of the quality of this implementation, however I see that you did similar work before and I trust that you know what you're doing.
I think I would like to "test" the function by side-by-side executing Game::MSG_ReadBitsCompress and yours (and same for write) and asserting that the outputs are 100% identical. This way even if I don't fully understand it I can at least ensure this will have no undesirable side effects.
Maybe you could include a test function in there that does something like that when iw4x is launched with a -test-huffman
flag.
Here are some project specific notes:
Huffman
or something similar, that does the hooking work of plugging it into MSG_ReadbitsCompress/MSG_WriteBittsCompress. If you need directions or offsets I can look into it and provide them for you :) I've set up a couple of (unfinished) unit tests as part of the new huffman component. Would you still like to have a test flag as well, or is it enough to have a unit test?
I'd like to use unit test 2 to compare the output from the old and new huffman code side by side for compression and decompression. I could use some help with the function stubs, though. I'm not sure if we need them, though currently the new huffman code functions expect a size for the output buffer as well, and the game doesn't provide this so that'll need to be sorted out.
I would also need a way to call the original huffman functions, but I'm not sure if that's possible after installing the hooks.
Looks better! We have not ran any unit tests on IW4x for a while so I don't know if they even pass, but it's indeed a better idea to add this one to the tests - rather than having a single test flag - if they do. I'm gonna look into your hookings and stuff whenever I can, possibly this weekend. thanks again :)
Sounds good, thank you. Feel free to reach out on Discord if you need anything quickly, though I'll try to keep an eye on this draft.
@Rackover Is there any chance you can have a look at it this weekend? I'd like to write the other unit tests and finish this draft.
Hello, sorry I was not sure this was up for review yet. This week end is a bit complicated for me, I can try looking at it monday night if I don't forget :)
Don't worry about pinging me if you feel like I'm not answering in reasonabble delays
@Rackover Could you check the new changes, and check if the code works as intended?
https://github.com/iw4x/iw4x-client/pull/111/commits/8efe997cea458cc9488518b0eccd14c7426740b0 removes the huffman exploit fixes, but maybe that's a bit premature, so I'm just making sure that's not overlooked. It might be nice if it were enabled as a fallback option when the huffman component isn't active, so that there isn't a scenario where the exploits are unpatched.
I have verified that the new huffman implementation is internally consistent; that is, uncompressed -> compressed -> decompressed yields the same data. The two parts that I haven't verified are the game hooks and the part of unit test 1 that compares the results from the two different huffman implementations.
Updated with the requested changes.
4c0933f currently triggers a linker error that I haven't been able to figure out yet. Is it possible that the Utils::Huffman and Components::Huffman files / namespaces are clashing?
Yes maybe, in that case you can just explicitely specify Components::Huffman when adding it to the loader if you want :)
I already tried that, but it makes no difference.
The linker error can be avoided by renaming either the Huffman utility files or the component files btw. If that's the way to solve this, which one should have a different name and what name would that be?
@Rackover Could you check the comments? I don't really like the explicit buffer checks up front, so imo I should get rid of the std::spans and just use the buffers and buffer sizes directly.
So the good thing is that apparently github CI has no problem with your code currently cause it builds & links correctly. I have not tested it myself yet though, and I have not checked the comment yet. Next week I plan to work a little bit on IW4x and catch up on stuff, so I will be looking at your PR, testing it, and hopefully merging it, and releasing :)
Regarding the discussion of span vs ptr+size_t, I'm not a c++ expert and have never used spans, so I don't know. My opinion is that if a size check is to occur it should occur on debug AND release, so assertions is not protection enough for it 🙂
Even though Github managed to get it working, I cannot get the MSVC linker to do the same thing. So just a heads up, if you ran into the same problem, renaming one set of files (module components or utils) should do the trick.
As for the 'std::span' comments, https://github.com/iw4x/iw4x-client/pull/111/commits/45e8f5489e8a5863c05a290d022427a5c6f33506 is how that could look like (the size checks are now part of the for loop conditions, so they're always checked). As far as I can tell (without having tested the game specific parts), the pr is good to go as-is.
^2Huffman decompression out-of-bounds read detected!
^2Huffman decompression out-of-bounds read detected!
0% config string match, 0% config string coverage.
Cannot join a single server with your modification! (I tried three different servers) It is currently not functional, I tested it in debug only but it does not seem to work with existing servers. Could you please install IW4x and test your code too? This way you can probably find out what's wrong more easily than with my descriptions 🙂
Regarding your linker error: maybe you forgot to run Generate.bat after adding a new file! You need to do it to regenerate the solution. I did it on my end and it worked, and this is what Github CI does too.
You're right, I didn't think to re-generate; that fixes it on my end as well. Thank you for that and thanks for testing.
The OOB detection messages are probably expected in debug mode. Just for reference, the game performs 'limited' OOB reads for many, if not most, decompression operations.
What's the meaning of the 3rd logged line, and did you check whether the unit tests and hooks were successful? I'm going to check what's required for me test IW4X live btw.
Hello! I'm available on discord if you need help getting IW4x live. I'm back to work (somewhat) actively on IW4x so I should be able to help you out within reasonable delays if you need anything.
Sounds good. I'll probably contact you at some point on Discord.
FWIW, I haven't given up on this pr, but it'll take me some additional time before I get around to installing IW4X and do live testing.
It's been a while since my last commit, so has there been any progress?
Hello! I'm still there, have you managed to set up IW4x to test your pull request on your end? :) I'm here on discord too if you need help with that. The setup for IW4x is pretty painless so if you can do that and test your PR on live servers to make sure everything works, it's very helpful. If everything runs as it should I will happily merge this in master and draft a new release! 😃
Hello! I'm still there, have you managed to set up IW4x to test your pull request on your end? :) I'm here on discord too if you need help with that. The setup for IW4x is pretty painless so if you can do that and test your PR on live servers to make sure everything works, it's very helpful. If everything runs as it should I will happily merge this in master and draft a new release! 😃
I already did that about two months ago after I fixed some issues with the (de)compression. It worked then and it still works now on my end. So it's ready for you to test.
I can't comment on code quality and usefulness of this PR, but I did some quick testing. The game seems to run absolutely fine, I was able to:
The game had no issue in Release but testing in debug mode, on a custom map, reveals this issue.
Investigating
We already discussed this privately, but I'll put it here as well for posterity.
The game doesn't have these early break checks for its (de)compression functions, so every time you see these debug prints, it's simply showing that the game would've accessed data beyond the size of the buffer. In other words, the print statements are a reflection of the game's implementation and not of this code, and can be removed if so desired.
If you run unit test 3 and step through it, you should be able to see precisely what's going on here.
What does this PR do?
How does this PR change IW4x's behaviour? This pr should not change existing behavior in any way.
Anything else we should know?
Did you check all the boxes?
closes #XXXX
in comment to auto-close issue when PR is merged)