-
Notifications
You must be signed in to change notification settings - Fork 0
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
Possible attempts to read outside array size in OPUNetTransportLayer #96
Comments
The We should change the type for struct PlayerNetID {
std::size_t playerIndex:3;
std::time_t timeStamp:29; // Or whatever the correct type and size is
}; I suspect the two types will need to match for them to share bits in the same byte. As for the error, it looks like the array was declared to have 6 elements for 6 players (0..5), but the bit mask for 3 bits allows for 8 values (0..7). I suppose we could increase the array size, or perhaps extract the Probably easiest to just increase the array size. It's not like it amounts to a whole lot of extra memory. |
Hmm, I would be okay with either proposed solution. Neither is particular elegant though. If we increase the array size, I would be tempted to start error checking to insure it was never set above the 6th index, so I would probably lean toward using a function to error check playerIndex. Thanks for diagnosing. I like the idea of using the bitfield struct proposed for PlayerNetID. |
I tried playing with the struct PlayerNetID idea. I came up with this: struct PlayerNetID
{
PlayerNetID(int value) : value(value)
{
if (GetPlayerIndex() >= 6) {
throw std::runtime_error("Maximum player index is 5");
}
}
inline void Clear() { value = 0; }
inline bool IsEmpty() const { return value == 0; }
inline std::size_t GetPlayerIndex() const { return value & 7; }
inline std::time_t GetTime() const { return value & ~7; }
inline int GetRawValue() const { return value; }
private:
int value;
}; I don't know. Seems maybe off track. |
If you use bitfields, you can eliminate the I probably wouldn't error check in the constructor. The values comes in from over the network, so there's really no guarantee on what they will be. I don't want to burden code deep within the network layer with potential exceptions during value construction. Instead, I would check and possibly Actually, the network structs are effectively overlaid on top of existing memory, so there isn't any construction. The data just is. For that reason, I would recommend sticking to a struct with all public fields, and no constructor. Having an error checking accessor is fine. You'd want to avoid features that would make the type non-POD though. Well, I guess POD is the old name for it, can't quite remember what the concept was split into or which one of them we actually want. Basically we want to be able to cast arbitrary memory to our type, and be able to work with it. |
I can't figure out how to efficiently set the int representation into the proposed bitfield. |
I'm afraid I don't have much context on that. For reading from the network, the bytes are For assignment from an struct PlayerNetID {
union {
struct {
std::size_t playerIndex:3;
std::size_t timeStamp:29;
};
int intValue;
};
}; Or you can set the fields individually: PlayerNetId playerNetId;
playerNetId.playerIndex = 0;
playerNetId.timeStamp = timeGetTime(); |
Setting intValue and then accessing the struct would be considered type punning right? I'm guessing since you are posting the solution you are okay with that? Seems to be mixed opinions about it on the internet. |
I would prefer not doing it, but it may be expedient. You can also break apart an playerNetId.payerIndex = value & 7;
playerNetId.timeStamp = (value & ~7) >> 3; |
I am getting the warning below in many places across the codebase where peerInfo is accessed. I suspect it has to to do with using the line
playerNetID & 7
on all occasions.Warning C6385 Reading invalid data from 'this->peerInfo': the readable size is '168' bytes, but '224' bytes may be read. NetFixClient \NETFIXCLIENT\CLIENT\OPUNETTRANSPORTLAYER.CPP 509
As a side note, it would be nice to explain why we have to apply `& 7' to the playerNetID before accessing the peerInfo array.
https://docs.microsoft.com/en-us/cpp/code-quality/c6385?view=vs-2019
The text was updated successfully, but these errors were encountered: