diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 0af351fd..6b5b01f9 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -2324,7 +2324,7 @@ static void CL_HandleTestPacket( netadr_t from, sizebuf_t *msg ) } // reading test buffer - MSG_ReadBytes( msg, recv_buf, realsize ); + MSG_ReadBytes( msg, recv_buf, sizeof( recv_buf ), realsize ); // procssing the CRC CRC32_ProcessBuffer( &crcValue2, recv_buf, realsize ); @@ -2543,16 +2543,16 @@ static void CL_ServerList( netadr_t from, sizebuf_t *msg ) if( NET_NetadrType( &from ) == NA_IP6 ) // IPv6 master server only sends IPv6 addresses { - MSG_ReadBytes( msg, addr, sizeof( addr )); + MSG_ReadBytes( msg, addr, sizeof( addr ), sizeof( addr )); NET_IP6BytesToNetadr( &servadr, addr ); NET_NetadrSetType( &servadr, NA_IP6 ); } else { - MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP + MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip ), sizeof( servadr.ip )); // 4 bytes for IP NET_NetadrSetType( &servadr, NA_IP ); } - MSG_ReadBytes( msg, &servadr.port, sizeof( servadr.port )); // 2 bytes for Port, in network byte order + MSG_ReadBytes( msg, &servadr.port, sizeof( servadr.port ), sizeof( servadr.port )); // 2 bytes for Port, in network byte order // list is ends here if( !servadr.port ) diff --git a/engine/client/cl_steam.c b/engine/client/cl_steam.c index ef4e8b97..00298900 100644 --- a/engine/client/cl_steam.c +++ b/engine/client/cl_steam.c @@ -220,7 +220,7 @@ static qboolean SteamBroker_ProcessFrame( void ) // verify frame header char header[SBRK_FRAME_HEADER_SIZE]; - if( !MSG_ReadBytes( &sb, header, SBRK_FRAME_HEADER_SIZE )) + if( !MSG_ReadBytes( &sb, header, sizeof( header ), SBRK_FRAME_HEADER_SIZE )) return false; if( memcmp( header, SBRK_FRAME_HEADER, SBRK_FRAME_HEADER_SIZE ) != 0 ) @@ -237,7 +237,7 @@ static qboolean SteamBroker_ProcessFrame( void ) return false; // need more data char response_header[SBRK_RESPONSE_HEADER_SIZE]; - if( MSG_ReadBytes( &sb, response_header, SBRK_RESPONSE_HEADER_SIZE )) + if( MSG_ReadBytes( &sb, response_header, sizeof( response_header ), SBRK_RESPONSE_HEADER_SIZE )) { if( memcmp( response_header, SBRK_RESPONSE_HEADER, SBRK_RESPONSE_HEADER_SIZE ) == 0 ) { @@ -249,7 +249,7 @@ static qboolean SteamBroker_ProcessFrame( void ) else { uint64_t steam_id; - MSG_ReadBytes( &sb, &steam_id, sizeof( steam_id )); + MSG_ReadBytes( &sb, &steam_id, sizeof( steam_id ), sizeof( steam_id )); uint32_t ticket_size = MSG_ReadDword( &sb ); uint8_t ticket_data[SBRK_TICKET_SIZE_MAX]; @@ -257,7 +257,7 @@ static qboolean SteamBroker_ProcessFrame( void ) { Con_Printf( S_ERROR "%s: ticket size exceeds limit (%u)\n", __func__, ticket_size ); } - else if( MSG_ReadBytes( &sb, ticket_data, ticket_size )) + else if( MSG_ReadBytes( &sb, ticket_data, sizeof( ticket_data ), ticket_size )) { Con_Printf( "%s: SteamID: %"PRIu64", ticket: [%d, %d, %d, %d...]\n", __func__, steam_id, ticket_data[0], ticket_data[1], ticket_data[2], ticket_data[3] ); diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index b07da8ec..95c85f7c 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -1865,7 +1865,7 @@ void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto ) } // parse user message into buffer - MSG_ReadBytes( msg, msg_data, iSize ); + MSG_ReadBytes( msg, msg_data, sizeof( msg_data ), iSize ); // init a safe tempbuffer MSG_Init( &buf, "TempEntity", msg_data, iSize ); diff --git a/engine/client/parse/cl_parse.c b/engine/client/parse/cl_parse.c index 35b1d519..1f3d2c1f 100644 --- a/engine/client/parse/cl_parse.c +++ b/engine/client/parse/cl_parse.c @@ -107,8 +107,8 @@ static void CL_ParseSoundPacket( sizebuf_t *msg, qboolean restore ) wordIndex = MSG_ReadByte( msg ); // 16 bytes here - MSG_ReadBytes( msg, &samplePos, sizeof( samplePos )); - MSG_ReadBytes( msg, &forcedEnd, sizeof( forcedEnd )); + MSG_ReadBytes( msg, &samplePos, sizeof( samplePos ), sizeof( samplePos )); + MSG_ReadBytes( msg, &forcedEnd, sizeof( forcedEnd ), sizeof( forcedEnd )); } if( !cl.audio_prepped ) @@ -617,7 +617,7 @@ static void CL_ParseCustomization( sizebuf_t *msg ) pRes->pNext = pRes->pPrev = NULL; if( FBitSet( pRes->ucFlags, RES_CUSTOM )) - MSG_ReadBytes( msg, pRes->rgucMD5_hash, 16 ); + MSG_ReadBytes( msg, pRes->rgucMD5_hash, sizeof( pRes->rgucMD5_hash ), 16 ); pRes->playernum = i; if( !cl_allow_download.value ) @@ -814,7 +814,7 @@ static void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto ) byte clientdllmd5[16]; const char *s; - MSG_ReadBytes( msg, clientdllmd5, sizeof( clientdllmd5 )); + MSG_ReadBytes( msg, clientdllmd5, sizeof( clientdllmd5 ), sizeof( clientdllmd5 )); cl.maxclients = MSG_ReadByte( msg ); cl.playernum = MSG_ReadByte( msg ); COM_UnMunge3((byte *)&cl.checksum, sizeof( cl.checksum ), ( 0xff - cl.playernum ) & 0xff ); @@ -1334,7 +1334,7 @@ static void CL_RegisterUserMessage( sizebuf_t *msg, connprotocol_t proto ) char *pszName; if( proto == PROTO_GOLDSRC ) { - MSG_ReadBytes( msg, szName, sizeof( szName ) - 1 ); + MSG_ReadBytes( msg, szName, sizeof( szName ), sizeof( szName ) - 1 ); szName[16] = 0; pszName = szName; } @@ -1381,7 +1381,7 @@ static void CL_UpdateUserinfo( sizebuf_t *msg, connprotocol_t proto ) player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" )); player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" )); player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" )); - MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey )); + MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ), sizeof( player->hashedcdkey )); if( proto == PROTO_GOLDSRC && ( COM_StringEmpty( player->userinfo ) || COM_StringEmpty( player->name ))) active = false; @@ -1421,10 +1421,10 @@ void CL_ParseResource( sizebuf_t *msg ) pResource->ucFlags = MSG_ReadUBitLong( msg, 3 ) & ~RES_WASMISSING; if( FBitSet( pResource->ucFlags, RES_CUSTOM )) - MSG_ReadBytes( msg, pResource->rgucMD5_hash, sizeof( pResource->rgucMD5_hash )); + MSG_ReadBytes( msg, pResource->rgucMD5_hash, sizeof( pResource->rgucMD5_hash ), sizeof( pResource->rgucMD5_hash )); if( MSG_ReadOneBit( msg )) - MSG_ReadBytes( msg, pResource->rguc_reserved, sizeof( pResource->rguc_reserved )); + MSG_ReadBytes( msg, pResource->rguc_reserved, sizeof( pResource->rguc_reserved ), sizeof( pResource->rguc_reserved )); if( pResource->type == t_sound && pResource->nIndex >= MAX_SOUNDS ) { @@ -1836,10 +1836,10 @@ void CL_ParseResourceList( sizebuf_t *msg, connprotocol_t proto ) pResource->ucFlags = MSG_ReadUBitLong( msg, 3 ) & ~RES_WASMISSING; if( FBitSet( pResource->ucFlags, RES_CUSTOM )) - MSG_ReadBytes( msg, pResource->rgucMD5_hash, sizeof( pResource->rgucMD5_hash )); + MSG_ReadBytes( msg, pResource->rgucMD5_hash, sizeof( pResource->rgucMD5_hash ), sizeof( pResource->rgucMD5_hash )); if( MSG_ReadOneBit( msg )) - MSG_ReadBytes( msg, pResource->rguc_reserved, sizeof( pResource->rguc_reserved )); + MSG_ReadBytes( msg, pResource->rguc_reserved, sizeof( pResource->rguc_reserved ), sizeof( pResource->rguc_reserved )); CL_AddToResourceList( pResource, &cl.resourcesneeded ); } @@ -1908,7 +1908,7 @@ static void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto ) if ( !size ) return; - MSG_ReadBytes( msg, received, size ); + MSG_ReadBytes( msg, received, sizeof( received ), size ); Voice_AddIncomingData( idx, received, size, frames ); } @@ -1988,7 +1988,7 @@ static void CL_ParseDirector( sizebuf_t *msg ) byte pbuf[256]; // parse user message into buffer - MSG_ReadBytes( msg, pbuf, iSize ); + MSG_ReadBytes( msg, pbuf, sizeof( pbuf ), iSize ); clgame.dllFuncs.pfnDirectorMessage( iSize, pbuf ); } @@ -2272,7 +2272,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num, connprotocol_t proto ) } // parse user message into buffer - MSG_ReadBytes( msg, pbuf, iSize ); + MSG_ReadBytes( msg, pbuf, sizeof( pbuf ), iSize ); if( cl_trace_messages.value ) { diff --git a/engine/common/net_buffer.c b/engine/common/net_buffer.c index 539ddbf8..57c6715e 100644 --- a/engine/common/net_buffer.c +++ b/engine/common/net_buffer.c @@ -615,41 +615,43 @@ uint MSG_ReadUBitLong( sizebuf_t *sb, int numbits ) return ret; } -qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits ) +qboolean MSG_ReadBits( sizebuf_t *sb, void *out, size_t maxBytes, int bits ) { - byte *pOut = (byte *)pOutData; - int nBitsLeft = nBits; + byte *p = (byte *)out; + int left = bits; + + if((size_t)bits > ( maxBytes << 3 )) + return false; // get output dword-aligned. - while((( uintptr_t )pOut & 3) != 0 && nBitsLeft >= 8 ) + while((( uintptr_t )p & 3) != 0 && left >= 8 ) { - *pOut = (byte)MSG_ReadUBitLong( sb, 8 ); - ++pOut; - nBitsLeft -= 8; + *p = (byte)MSG_ReadUBitLong( sb, 8 ); + ++p; + left -= 8; } // read dwords. - while( nBitsLeft >= 32 ) + while( left >= 32 ) { uint32_t dword = MSG_ReadUBitLong( sb, 32 ); - *((uint32_t *)pOut) = LittleLong( dword ); - pOut += sizeof( uint32_t ); - nBitsLeft -= 32; + dword = LittleLong( dword ); + memcpy( p, &dword, sizeof( dword )); + p += sizeof( dword ); + left -= 32; } // read the remaining bytes. - while( nBitsLeft >= 8 ) + while( left >= 8 ) { - *pOut = MSG_ReadUBitLong( sb, 8 ); - ++pOut; - nBitsLeft -= 8; + *p = MSG_ReadUBitLong( sb, 8 ); + ++p; + left -= 8; } // read the remaining bits. - if( nBitsLeft ) - { - *pOut = MSG_ReadUBitLong( sb, nBitsLeft ); - } + if( left ) + *p = MSG_ReadUBitLong( sb, left ); return !sb->bOverflow; } @@ -792,9 +794,9 @@ float MSG_ReadFloat( sizebuf_t *sb ) return UintAsFloat( MSG_ReadUBitLong( sb, sizeof( float ) << 3 )); } -qboolean MSG_ReadBytes( sizebuf_t *sb, void *pOut, int nBytes ) +qboolean MSG_ReadBytes( sizebuf_t *sb, void *out, size_t maxBytes, int bytes ) { - return MSG_ReadBits( sb, pOut, nBytes << 3 ); + return MSG_ReadBits( sb, out, maxBytes, bytes << 3 ); } static char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine ) @@ -932,7 +934,7 @@ static void Test_Buffer_Read( void ) TASSERT_EQp( sb.pData, (void *)g_testbuf ); TASSERT_EQi( sb.bOverflow, false ); - MSG_ReadBytes( &sb, buf, 4 ); + MSG_ReadBytes( &sb, buf, sizeof( buf ), 4 ); TASSERT( !memcmp( buf, "asdf", 4 )); TASSERT_EQi( sb.iCurBit, 32 ); TASSERT_EQi( sb.bOverflow, false ); diff --git a/engine/common/net_buffer.h b/engine/common/net_buffer.h index e6373936..9164bd40 100644 --- a/engine/common/net_buffer.h +++ b/engine/common/net_buffer.h @@ -235,7 +235,7 @@ qboolean MSG_WriteBytes( sizebuf_t *sb, const void *pBuf, int nBytes ); // Bit-read functions int MSG_ReadOneBit( sizebuf_t *sb ); -qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits ); +qboolean MSG_ReadBits( sizebuf_t *sb, void *out, size_t maxBytes, int bits ); float MSG_ReadBitAngle( sizebuf_t *sb, int numbits ); int MSG_ReadSBitLong( sizebuf_t *sb, int numbits ); uint MSG_ReadUBitLong( sizebuf_t *sb, int numbits ); @@ -257,6 +257,6 @@ void MSG_ReadVec3Coord( sizebuf_t *sb, vec3_t fa ); void MSG_ReadVec3Angles( sizebuf_t *sb, vec3_t fa ); char *MSG_ReadString( sizebuf_t *sb ) RETURNS_NONNULL; char *MSG_ReadStringLine( sizebuf_t *sb ) RETURNS_NONNULL; -qboolean MSG_ReadBytes( sizebuf_t *sb, void *pOut, int nBytes ); +qboolean MSG_ReadBytes( sizebuf_t *sb, void *out, size_t maxBytes, int bytes ); #endif//NET_BUFFER_H diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 9d071167..16ac37e0 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -1911,7 +1911,7 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg ) MSG_Clear( &pbuf->frag_message ); MSG_StartReading( &temp, msg->pData, MSG_GetMaxBytes( msg ), size, -1 ); - MSG_ReadBits( &temp, buffer, bits ); + MSG_ReadBits( &temp, buffer, sizeof( buffer ), bits ); MSG_WriteBits( &pbuf->frag_message, buffer, bits ); } diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index c0d1fafa..8e6243d5 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -3445,7 +3445,7 @@ static void SV_ParseResourceList( sv_client_t *cl, sizebuf_t *msg ) ClearBits( resource->ucFlags, RES_WASMISSING ); if( FBitSet( resource->ucFlags, RES_CUSTOM )) - MSG_ReadBytes( msg, resource->rgucMD5_hash, 16 ); + MSG_ReadBytes( msg, resource->rgucMD5_hash, sizeof( resource->rgucMD5_hash ), 16 ); if( resource->type > t_world || resource->nDownloadSize > 1024 * 1024 * 1024 ) { @@ -3569,7 +3569,7 @@ static void SV_ParseVoiceData( sv_client_t *cl, sizebuf_t *msg ) return; } - MSG_ReadBytes( msg, received, size ); + MSG_ReadBytes( msg, received, sizeof( received ), size ); if( !sv_voiceenable.value || cl->state != cs_spawned ) return; diff --git a/engine/server/sv_custom.c b/engine/server/sv_custom.c index 38cc8b71..f0908ec2 100644 --- a/engine/server/sv_custom.c +++ b/engine/server/sv_custom.c @@ -124,8 +124,8 @@ void SV_ParseConsistencyResponse( sv_client_t *cl, sizebuf_t *msg ) byte resbuffer[32]; FORCE_TYPE ft; - MSG_ReadBytes( msg, cmins, sizeof( cmins )); - MSG_ReadBytes( msg, cmaxs, sizeof( cmaxs )); + MSG_ReadBytes( msg, cmins, sizeof( cmins ), sizeof( cmins )); + MSG_ReadBytes( msg, cmaxs, sizeof( cmaxs ), sizeof( cmaxs )); memcpy( resbuffer, r->rguc_reserved, 32 ); ft = resbuffer[0];