/*
Copyright (C) 1996-1997 Id Software, Inc.
+Copyright (C) 2000-2020 DarkPlaces contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
============================================================================
*/
+/* Casting to unsigned when shifting by 24 bits here is necessary to prevent UB
+ * caused by shifting outside the range of int on platforms where int is 32 bits.
+ */
float BuffBigFloat (const unsigned char *buffer)
{
unsigned int i;
}
u;
- u.i = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+ u.i = ((unsigned)buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
return u.f;
}
int BuffBigLong (const unsigned char *buffer)
{
- return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+ return ((unsigned)buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
}
short BuffBigShort (const unsigned char *buffer)
unsigned int i;
}
u;
- u.i = (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
+ u.i = ((unsigned)buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
return u.f;
}
int BuffLittleLong (const unsigned char *buffer)
{
- return (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
+ return ((unsigned)buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
}
short BuffLittleShort (const unsigned char *buffer)
void MSG_WriteCoord13i (sizebuf_t *sb, float f)
{
- if (f >= 0)
- MSG_WriteShort (sb, (int)(f * 8.0 + 0.5));
- else
- MSG_WriteShort (sb, (int)(f * 8.0 - 0.5));
+ MSG_WriteShort (sb, Q_rint(f*8));
}
void MSG_WriteCoord16i (sizebuf_t *sb, float f)
{
- if (f >= 0)
- MSG_WriteShort (sb, (int)(f + 0.5));
- else
- MSG_WriteShort (sb, (int)(f - 0.5));
+ MSG_WriteShort (sb, Q_rint(f));
}
void MSG_WriteCoord32f (sizebuf_t *sb, float f)
// LadyHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
void MSG_WriteAngle8i (sizebuf_t *sb, float f)
{
- if (f >= 0)
- MSG_WriteByte (sb, (int)(f*(256.0/360.0) + 0.5) & 255);
- else
- MSG_WriteByte (sb, (int)(f*(256.0/360.0) - 0.5) & 255);
+ MSG_WriteByte (sb, (int)Q_rint(f*(256.0/360.0)) & 255);
}
void MSG_WriteAngle16i (sizebuf_t *sb, float f)
{
- if (f >= 0)
- MSG_WriteShort (sb, (int)(f*(65536.0/360.0) + 0.5) & 65535);
- else
- MSG_WriteShort (sb, (int)(f*(65536.0/360.0) - 0.5) & 65535);
+ MSG_WriteShort (sb, (int)Q_rint(f*(65536.0/360.0)) & 65535);
}
void MSG_WriteAngle32f (sizebuf_t *sb, float f)
return -1;
}
sb->readcount += 4;
- return sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | (sb->data[sb->readcount-1]<<24);
+ return sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | ((unsigned)sb->data[sb->readcount-1]<<24);
}
int MSG_ReadBigLong (sizebuf_t *sb)
return -1;
}
sb->readcount += 4;
- return (sb->data[sb->readcount-4]<<24) + (sb->data[sb->readcount-3]<<16) + (sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1];
+ return ((unsigned)sb->data[sb->readcount-4]<<24) + (sb->data[sb->readcount-3]<<16) + (sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1];
}
float MSG_ReadLittleFloat (sizebuf_t *sb)
return -1;
}
sb->readcount += 4;
- dat.l = sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | (sb->data[sb->readcount-1]<<24);
+ dat.l = sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | ((unsigned)sb->data[sb->readcount-1]<<24);
return dat.f;
}
return -1;
}
sb->readcount += 4;
- dat.l = (sb->data[sb->readcount-4]<<24) | (sb->data[sb->readcount-3]<<16) | (sb->data[sb->readcount-2]<<8) | sb->data[sb->readcount-1];
+ dat.l = ((unsigned)sb->data[sb->readcount-4]<<24) | (sb->data[sb->readcount-3]<<16) | (sb->data[sb->readcount-2]<<8) | sb->data[sb->readcount-1];
return dat.f;
}
char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring)
{
- int c;
size_t l = 0;
+
// read string into sbfer, but only store as many characters as will fit
- while ((c = MSG_ReadByte(sb)) > 0)
- if (l < maxstring - 1)
- string[l++] = c;
- string[l] = 0;
+ // if dest buffer is full sb->readcount will still be advanced to end of message string
+ while ((string[l] = MSG_ReadByte_opt(sb)) != '\0')
+ if (l < maxstring)
+ ++l;
return string;
}
+size_t MSG_ReadString_len (sizebuf_t *sb, char *string, size_t maxstring)
+{
+ size_t l = 0;
+
+ // read string into sbfer, but only store as many characters as will fit
+ // if dest buffer is full sb->readcount will still be advanced to end of message string
+ while ((string[l] = MSG_ReadByte_opt(sb)) != '\0')
+ if (l < maxstring)
+ ++l;
+ return l;
+}
-int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out)
+size_t MSG_ReadBytes (sizebuf_t *sb, size_t numbytes, unsigned char *out)
{
- int l, c;
- for (l = 0;l < numbytes && (c = MSG_ReadByte(sb)) != -1;l++)
- out[l] = c;
+ size_t l = 0;
+
+ // when numbytes have been read sb->readcount won't be advanced any further
+ while (l < numbytes && !sb->badread)
+ out[l++] = MSG_ReadByte_opt(sb);
return l;
}
return MSG_ReadAngle8i (sb);
else
return MSG_ReadAngle16i (sb);
-}
\ No newline at end of file
+}