mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-23 12:32:14 +00:00
fixed bitstream string parsing not reading the last byte of max length strings ("q3msgboom")
This commit is contained in:
parent
55ae7645b1
commit
2f70685fa3
2 changed files with 40 additions and 57 deletions
|
@ -16,6 +16,8 @@ add: /toggle can now accept a value sequence (2 or more entries) to loop through
|
||||||
|
|
||||||
chg: on Windows, the upper limit of open stdio file handles was raised from 512 to 2048
|
chg: on Windows, the upper limit of open stdio file handles was raised from 512 to 2048
|
||||||
|
|
||||||
|
fix: the last byte of a maximum length bitstream string wasn't parsed ("q3msgboom")
|
||||||
|
|
||||||
fix: aborting demo playback would crash when the "nextdemo" cvar was set to play a demo
|
fix: aborting demo playback would crash when the "nextdemo" cvar was set to play a demo
|
||||||
|
|
||||||
fix: no longer feeding cs commands that came from a previous gamestate to cgame
|
fix: no longer feeding cs commands that came from a previous gamestate to cgame
|
||||||
|
|
|
@ -336,86 +336,67 @@ int MSG_ReadLong( msg_t *msg )
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Notes about the MSG_Read*String* functions
|
||||||
|
//
|
||||||
|
// If N is the string buffer size, then:
|
||||||
|
// - the max. string length is N-1 because
|
||||||
|
// the NULL-terminator is part of the buffer
|
||||||
|
// - the loop can call MSG_ReadByte at most N times
|
||||||
|
// - the loop can write at most N-1 chars
|
||||||
|
// to leave space for the NULL terminator
|
||||||
|
//
|
||||||
|
// The "q3msgboom" bug was happening because a string
|
||||||
|
// of length >= N-1 was invoking MSG_ReadByte N-1 times
|
||||||
|
// instead of N times, leaving the bit stream in an
|
||||||
|
// invalid state and later leading to the
|
||||||
|
// "Illegible server message" drop error.
|
||||||
|
//
|
||||||
|
|
||||||
char *MSG_ReadString( msg_t *msg ) {
|
char *MSG_ReadString( msg_t *msg ) {
|
||||||
static char string[MAX_STRING_CHARS];
|
static char string[MAX_STRING_CHARS];
|
||||||
int l,c;
|
|
||||||
|
|
||||||
l = 0;
|
int l = 0;
|
||||||
do {
|
for (;;) {
|
||||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
const int c = MSG_ReadByte(msg);
|
||||||
if ( c == -1 || c == 0 ) {
|
if (c <= 0 || l >= sizeof(string) - 1)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
// translate all fmt spec to avoid crash bugs
|
|
||||||
if ( c == '%' ) {
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
// don't allow higher ascii values
|
|
||||||
if ( c > 127 ) {
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
string[l] = c;
|
string[l++] = c == '%' || c > 127 ? '.' : c;
|
||||||
l++;
|
}
|
||||||
} while (l < sizeof(string)-1);
|
string[l] = '\0';
|
||||||
|
|
||||||
string[l] = 0;
|
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *MSG_ReadBigString( msg_t *msg ) {
|
char *MSG_ReadBigString( msg_t *msg ) {
|
||||||
static char string[BIG_INFO_STRING];
|
static char string[BIG_INFO_STRING];
|
||||||
int l,c;
|
|
||||||
|
|
||||||
l = 0;
|
int l = 0;
|
||||||
do {
|
for (;;) {
|
||||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
const int c = MSG_ReadByte(msg);
|
||||||
if ( c == -1 || c == 0 ) {
|
if (c <= 0 || l >= sizeof(string) - 1)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
// translate all fmt spec to avoid crash bugs
|
|
||||||
if ( c == '%' ) {
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
// don't allow higher ascii values
|
|
||||||
if ( c > 127 ) {
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
string[l] = c;
|
string[l++] = c == '%' || c > 127 ? '.' : c;
|
||||||
l++;
|
}
|
||||||
} while (l < sizeof(string)-1);
|
string[l] = '\0';
|
||||||
|
|
||||||
string[l] = 0;
|
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *MSG_ReadStringLine( msg_t *msg ) {
|
char *MSG_ReadStringLine( msg_t *msg ) {
|
||||||
static char string[MAX_STRING_CHARS];
|
static char string[MAX_STRING_CHARS];
|
||||||
int l,c;
|
|
||||||
|
|
||||||
l = 0;
|
int l = 0;
|
||||||
do {
|
for (;;) {
|
||||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
const int c = MSG_ReadByte(msg);
|
||||||
if (c == -1 || c == 0 || c == '\n') {
|
if (c <= 0 || c == '\n' || l >= sizeof(string) - 1)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
// translate all fmt spec to avoid crash bugs
|
|
||||||
if ( c == '%' ) {
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
// don't allow higher ascii values
|
|
||||||
if ( c > 127 ) {
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
string[l] = c;
|
string[l++] = c == '%' || c > 127 ? '.' : c;
|
||||||
l++;
|
}
|
||||||
} while (l < sizeof(string)-1);
|
string[l] = '\0';
|
||||||
|
|
||||||
string[l] = 0;
|
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue