Skip to content

Commit 5e84d9e

Browse files
committed
Strict checks; implement GameID from extra data flags
1 parent 266cf6a commit 5e84d9e

File tree

4 files changed

+67
-32
lines changed

4 files changed

+67
-32
lines changed

SourceQuery/Buffer.class.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,20 @@ public function Remaining( )
7070
*/
7171
public function Get( $Length = -1 )
7272
{
73-
if( $Length == 0 )
73+
if( $Length === 0 )
7474
{
75-
// Why even bother
76-
return "";
75+
return '';
7776
}
7877

7978
$Remaining = $this->Remaining( );
8079

81-
if( $Length == -1 )
80+
if( $Length === -1 )
8281
{
8382
$Length = $Remaining;
8483
}
8584
else if( $Length > $Remaining )
8685
{
87-
return "";
86+
return '';
8887
}
8988

9089
$Data = SubStr( $this->Buffer, $this->Position, $Length );

SourceQuery/Socket.class.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,19 @@ public function Read( $Length = 1400 )
6969
{
7070
$this->Buffer->Set( FRead( $this->Socket, $Length ) );
7171

72-
if( $this->Buffer->Remaining( ) > 0 && $this->Buffer->GetLong( ) == -2 )
72+
if( $this->Buffer->Remaining( ) === 0 )
73+
{
74+
// TODO: Should we throw an exception here?
75+
return;
76+
}
77+
78+
$Header = $this->Buffer->GetLong( );
79+
80+
if( $Header === -1 ) // Single packet
81+
{
82+
// We don't have to do anything
83+
}
84+
else if( $Header === -2 ) // Split packet
7385
{
7486
$Packets = Array( );
7587
$IsCompressed = false;
@@ -91,7 +103,7 @@ public function Read( $Length = 1400 )
91103
}
92104
case SourceQuery :: SOURCE:
93105
{
94-
$IsCompressed = ( $RequestID & 0x80000000 ) != 0;
106+
$IsCompressed = ( $RequestID & 0x80000000 ) !== 0;
95107
$PacketCount = $this->Buffer->GetByte( );
96108
$PacketNumber = $this->Buffer->GetByte( ) + 1;
97109

@@ -129,14 +141,18 @@ public function Read( $Length = 1400 )
129141

130142
$Data = bzdecompress( $Data );
131143

132-
if( CRC32( $Data ) != $PacketChecksum )
144+
if( CRC32( $Data ) !== $PacketChecksum )
133145
{
134146
throw new SourceQueryException( 'CRC32 checksum mismatch of uncompressed packet data.' );
135147
}
136148
}
137149

138150
$this->Buffer->Set( SubStr( $Buffer, 4 ) );
139151
}
152+
else
153+
{
154+
throw new SourceQueryException( 'Socket read: Raw packet header mismatch. (0x' . DecHex( $Header ) . ')' );
155+
}
140156
}
141157

142158
private function Sherlock( $Length )
@@ -150,6 +166,6 @@ private function Sherlock( $Length )
150166

151167
$this->Buffer->Set( $Data );
152168

153-
return $this->Buffer->GetLong( ) == -2;
169+
return $this->Buffer->GetLong( ) === -2;
154170
}
155171
}

SourceQuery/SourceQuery.class.php

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public function Ping( )
191191
$this->Socket->Write( self :: A2S_PING );
192192
$this->Socket->Read( );
193193

194-
return $this->Buffer->GetByte( ) == self :: S2A_PING;
194+
return $this->Buffer->GetByte( ) === self :: S2A_PING;
195195
}
196196

197197
/**
@@ -213,13 +213,13 @@ public function GetInfo( )
213213

214214
$Type = $this->Buffer->GetByte( );
215215

216-
if( $Type == 0 )
216+
if( $Type === 0 )
217217
{
218218
return false;
219219
}
220220

221221
// Old GoldSource protocol, HLTV still uses it
222-
if( $Type == self :: S2A_INFO_OLD && $this->Socket->Engine == self :: GOLDSOURCE )
222+
if( $Type === self :: S2A_INFO_OLD && $this->Socket->Engine === self :: GOLDSOURCE )
223223
{
224224
/**
225225
* If we try to read data again, and we get the result with type S2A_INFO (0x49)
@@ -237,8 +237,8 @@ public function GetInfo( )
237237
$Server[ 'Protocol' ] = $this->Buffer->GetByte( );
238238
$Server[ 'Dedicated' ] = Chr( $this->Buffer->GetByte( ) );
239239
$Server[ 'Os' ] = Chr( $this->Buffer->GetByte( ) );
240-
$Server[ 'Password' ] = $this->Buffer->GetByte( ) == 1;
241-
$Server[ 'IsMod' ] = $this->Buffer->GetByte( ) == 1;
240+
$Server[ 'Password' ] = $this->Buffer->GetByte( ) === 1;
241+
$Server[ 'IsMod' ] = $this->Buffer->GetByte( ) === 1;
242242

243243
if( $Server[ 'IsMod' ] )
244244
{
@@ -247,11 +247,11 @@ public function GetInfo( )
247247
$this->Buffer->Get( 1 ); // NULL byte
248248
$Mod[ 'Version' ] = $this->Buffer->GetLong( );
249249
$Mod[ 'Size' ] = $this->Buffer->GetLong( );
250-
$Mod[ 'ServerSide' ] = $this->Buffer->GetByte( ) == 1;
251-
$Mod[ 'CustomDLL' ] = $this->Buffer->GetByte( ) == 1;
250+
$Mod[ 'ServerSide' ] = $this->Buffer->GetByte( ) === 1;
251+
$Mod[ 'CustomDLL' ] = $this->Buffer->GetByte( ) === 1;
252252
}
253253

254-
$Server[ 'Secure' ] = $this->Buffer->GetByte( ) == 1;
254+
$Server[ 'Secure' ] = $this->Buffer->GetByte( ) === 1;
255255
$Server[ 'Bots' ] = $this->Buffer->GetByte( );
256256

257257
if( isset( $Mod ) )
@@ -262,7 +262,7 @@ public function GetInfo( )
262262
return $Server;
263263
}
264264

265-
if( $Type != self :: S2A_INFO )
265+
if( $Type !== self :: S2A_INFO )
266266
{
267267
throw new SourceQueryException( 'GetInfo: Packet header mismatch. (0x' . DecHex( $Type ) . ')' );
268268
}
@@ -278,11 +278,11 @@ public function GetInfo( )
278278
$Server[ 'Bots' ] = $this->Buffer->GetByte( );
279279
$Server[ 'Dedicated' ] = Chr( $this->Buffer->GetByte( ) );
280280
$Server[ 'Os' ] = Chr( $this->Buffer->GetByte( ) );
281-
$Server[ 'Password' ] = $this->Buffer->GetByte( ) == 1;
282-
$Server[ 'Secure' ] = $this->Buffer->GetByte( ) == 1;
281+
$Server[ 'Password' ] = $this->Buffer->GetByte( ) === 1;
282+
$Server[ 'Secure' ] = $this->Buffer->GetByte( ) === 1;
283283

284-
// The Ship
285-
if( $Server[ 'AppID' ] == 2400 )
284+
// The Ship (they violate query protocol spec by modifying the response)
285+
if( $Server[ 'AppID' ] === 2400 )
286286
{
287287
$Server[ 'GameMode' ] = $this->Buffer->GetByte( );
288288
$Server[ 'WitnessCount' ] = $this->Buffer->GetByte( );
@@ -294,7 +294,7 @@ public function GetInfo( )
294294
// Extra Data Flags
295295
if( $this->Buffer->Remaining( ) > 0 )
296296
{
297-
$Flags = $this->Buffer->GetByte( );
297+
$Server[ 'ExtraDataFlags' ] = $Flags = $this->Buffer->GetByte( );
298298

299299
// The server's game port
300300
if( $Flags & 0x80 )
@@ -305,7 +305,7 @@ public function GetInfo( )
305305
// The server's SteamID - does this serve any purpose?
306306
if( $Flags & 0x10 )
307307
{
308-
$Server[ 'ServerID' ] = $this->Buffer->GetUnsignedLong( ) | ( $this->Buffer->GetUnsignedLong( ) << 32 );
308+
$Server[ 'ServerID' ] = $this->Buffer->GetUnsignedLong( ) | ( $this->Buffer->GetUnsignedLong( ) << 32 ); // TODO: verify this
309309
}
310310

311311
// The spectator port and then the spectator server name
@@ -321,7 +321,16 @@ public function GetInfo( )
321321
$Server[ 'GameTags' ] = $this->Buffer->GetString( );
322322
}
323323

324-
// 0x01 - The server's 64-bit GameID
324+
// GameID -- alternative to AppID?
325+
if( $Flags & 0x01 )
326+
{
327+
$Server[ 'GameID' ] = $this->Buffer->GetUnsignedLong( ) | ( $this->Buffer->GetUnsignedLong( ) << 32 );
328+
}
329+
330+
if( $this->Buffer->Remaining( ) > 0 )
331+
{
332+
throw new SourceQueryException( 'GetInfo: unread data? ' . $this->Buffer->Remaining( ) . ' bytes remaining in the buffer. Please report it to the library developer.' );
333+
}
325334
}
326335

327336
return $Server;
@@ -355,11 +364,11 @@ public function GetPlayers( )
355364

356365
$Type = $this->Buffer->GetByte( );
357366

358-
if( $Type == 0 )
367+
if( $Type === 0 )
359368
{
360369
return false;
361370
}
362-
else if( $Type != self :: S2A_PLAYER )
371+
else if( $Type !== self :: S2A_PLAYER )
363372
{
364373
throw new SourceQueryException( 'GetPlayers: Packet header mismatch. (0x' . DecHex( $Type ) . ')' );
365374
}
@@ -412,11 +421,11 @@ public function GetRules( )
412421

413422
$Type = $this->Buffer->GetByte( );
414423

415-
if( $Type == 0 )
424+
if( $Type === 0 )
416425
{
417426
return false;
418427
}
419-
else if( $Type != self :: S2A_RULES )
428+
else if( $Type !== self :: S2A_RULES )
420429
{
421430
throw new SourceQueryException( 'GetRules: Packet header mismatch. (0x' . DecHex( $Type ) . ')' );
422431
}

View.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<meta charset="utf-8">
4040
<title>Source Query PHP Class</title>
4141

42-
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css">
42+
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
4343
<style type="text/css">
4444
.jumbotron {
4545
margin-top: 30px;
@@ -80,7 +80,7 @@
8080
<table class="table table-bordered table-striped">
8181
<thead>
8282
<tr>
83-
<th colspan="2">Server Info <em>(queried in <?php echo $Timer; ?>s)</em></th>
83+
<th colspan="2">Server Info <span class="label label-<?php echo $Timer > 1.0 ? 'danger' : 'success'; ?>"><?php echo $Timer; ?>s</span></th>
8484
</tr>
8585
</thead>
8686
<tbody>
@@ -97,7 +97,18 @@
9797
}
9898
else
9999
{
100-
echo htmlspecialchars( $InfoValue );
100+
if( $InfoValue === true )
101+
{
102+
echo 'true';
103+
}
104+
else if( $InfoValue === false )
105+
{
106+
echo 'false';
107+
}
108+
else
109+
{
110+
echo htmlspecialchars( $InfoValue );
111+
}
101112
}
102113
?></td>
103114
</tr>

0 commit comments

Comments
 (0)