GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Failed
Branch cursor (62f708)
by Charlotte
04:14
created

ProtocolParser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 9
ccs 7
cts 7
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Plasma Driver MySQL component
4
 * Copyright 2018-2019 PlasmaPHP, All Rights Reserved
5
 *
6
 * Website: https://github.com/PlasmaPHP
7
 * License: https://github.com/PlasmaPHP/driver-mysql/blob/master/LICENSE
8
*/
9
10
namespace Plasma\Drivers\MySQL;
11
12
/**
13
 * The MySQL Protocol Parser.
14
 * @internal
15
 */
16
class ProtocolParser implements \Evenement\EventEmitterInterface {
17
    use \Evenement\EventEmitterTrait;
18
    
19
    /**
20
     * @var int
21
     */
22
    const STATE_INIT = 0;
23
    
24
    /**
25
     * @var int
26
     */
27
    const STATE_HANDSHAKE = 1;
28
    
29
    /**
30
     * @var int
31
     */
32
    const STATE_HANDSHAKE_ERROR = 2;
33
    
34
    /**
35
     * @var int
36
     */
37
    const STATE_AUTH = 5;
38
    
39
    /**
40
     * @var int
41
     */
42
    const STATE_AUTH_SENT = 6;
43
    
44
    /**
45
     * @var int
46
     */
47
    const STATE_AUTH_ERROR = 7;
48
    
49
    /**
50
     * @var int
51
     */
52
    const STATE_OK = 9;
53
    
54
    /**
55
     * @var int
56
     */
57
    const CLIENT_CAPABILITIES = (
58
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_FOUND_ROWS |
59
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_LONG_PASSWORD |
60
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_LONG_FLAG |
61
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_LOCAL_FILES |
62
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_INTERACTIVE |
63
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_TRANSACTIONS |
64
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_SECURE_CONNECTION |
65
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_PROTOCOL_41 |
66
        \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_DEPRECATE_EOF
67
    );
68
    
69
    /**
70
     * @var int
71
     */
72
    const CLIENT_MAX_PACKET_SIZE = 0xFFFFFF;
73
    
74
    /**
75
     * @var int
76
     */
77
    const CLIENT_CHARSET_NUMBER = 0x21;
78
    
79
    /**
80
     * @var \Plasma\Drivers\MySQL\Driver
81
     */
82
    protected $driver;
83
    
84
    /**
85
     * @var \React\Socket\ConnectionInterface
86
     */
87
    protected $connection;
88
    
89
    /**
90
     * @var int
91
     */
92
    protected $state = ProtocolParser::STATE_INIT;
93
    
94
    /**
95
     * @var \Plasma\BinaryBuffer
96
     */
97
    protected $buffer;
98
    
99
    /**
100
     * @var \Plasma\BinaryBuffer
101
     */
102
    protected $messageBuffer;
103
    
104
    /**
105
     * The sequence ID is incremented with each packet and may wrap around.
106
     * It starts at 0 and is reset to 0 when a new command begins in the Command Phase.
107
     * @var int
108
     * @see https://dev.mysql.com/doc/internals/en/sequence-id.html
109
     */
110
    protected $sequenceID = -1;
111
    
112
    /**
113
     * Whether we use compression.
114
     * @var bool
115
     */
116
    protected $compressionEnabled = false;
117
    
118
    /**
119
     * The compression ID is incremented with each packet and may wrap around.
120
     * The compression ID is independent to the sequence ID.
121
     * @var int
122
     * @see https://dev.mysql.com/doc/internals/en/compressed-packet-header.html
123
     */
124
    protected $compressionID = -1;
125
    
126
    /**
127
     * Small packets should not be compressed. This defines a minimum size for compression.
128
     * @var int
129
     * @see https://dev.mysql.com/doc/internals/en/uncompressed-payload.html
130
     */
131
    protected $compressionSizeThreshold = 50;
132
    
133
    /**
134
     * @var \Plasma\BinaryBuffer
135
     */
136
    protected $compressionBuffer;
137
    
138
    /**
139
     * @var \Plasma\Drivers\MySQL\Messages\HandshakeMessage|null
140
     */
141
    protected $handshakeMessage;
142
    
143
    /**
144
     * @var \Plasma\Drivers\MySQL\Messages\OkResponseMessage|null
145
     */
146
    protected $lastOkMessage;
147
    
148
    /**
149
     * @var \Plasma\CommandInterface|null
150
     */
151
    protected $currentCommand;
152
    
153
    /**
154
     * @var callable|null
155
     */
156
    protected $parseCallback;
157
    
158
    /**
159
     * Constructor.
160
     * @param \Plasma\Drivers\MySQL\Driver       $driver
161
     * @param \React\Socket\ConnectionInterface  $connection
162
     */
163 66
    function __construct(\Plasma\Drivers\MySQL\Driver $driver, \React\Socket\ConnectionInterface $connection) {
164 66
        $this->driver = $driver;
165 66
        $this->connection = $connection;
166
        
167 66
        $this->buffer = new \Plasma\BinaryBuffer();
168 66
        $this->messageBuffer = new \Plasma\BinaryBuffer();
169 66
        $this->compressionBuffer = new \Plasma\BinaryBuffer();
170
        
171 66
        $this->addEvents();
172 66
    }
173
    
174
    /**
175
     * Invoke a command to execute.
176
     * @param \Plasma\CommandInterface|null  $command
177
     * @return void
178
     */
179 64
    function invokeCommand(?\Plasma\CommandInterface $command): void {
180 64
        if($command === null) {
181 60
            return;
182
        }
183
        
184 64
        $this->currentCommand = $command;
185 64
        $this->processCommand();
186 64
    }
187
    
188
    /**
189
     * Executes a command, without handling any aftermath.
190
     * The `onComplete` callback will be immediately invoked, regardless of the `waitForCompletion` value.
191
     * @param \Plasma\CommandInterface  $command
192
     * @return void
193
     */
194
    function executeCommand(\Plasma\CommandInterface $command): void {
195
        $this->processCommand($command);
196
    }
197
    
198
    /**
199
     * Marks the command itself as finished, if currently running.
200
     * @param \Plasma\Drivers\MySQL\Commands\CommandInterface  $command
201
     * @return void
202
     */
203 60
    function markCommandAsFinished(\Plasma\CommandInterface $command): void {
204 60
        if($command === $this->currentCommand) {
205 60
            $this->currentCommand = null;
206
        }
207
        
208 60
        $command->onComplete();
209 60
    }
210
    
211
    /**
212
     * Get the parser state.
213
     * @return int
214
     */
215 2
    function getState(): int {
216 2
        return $this->state;
217
    }
218
    
219
    /**
220
     * Get the handshake message, or null.
221
     * @return \Plasma\Drivers\MySQL\Messages\HandshakeMessage|null
222
     */
223 63
    function getHandshakeMessage(): ?\Plasma\Drivers\MySQL\Messages\HandshakeMessage {
224 63
        return $this->handshakeMessage;
225
    }
226
    
227
    /**
228
     * Get the last ok response message, or null.
229
     * @return \Plasma\Drivers\MySQL\Messages\OkResponseMessage|null
230
     */
231 4
    function getLastOkMessage(): ?\Plasma\Drivers\MySQL\Messages\OkResponseMessage {
232 4
        return $this->lastOkMessage;
233
    }
234
    
235
    /**
236
     * Enables compression.
237
     * @return void
238
     */
239 2
    function enableCompression(): void {
240 2
        $this->compressionEnabled = true;
241 2
    }
242
    
243
    /**
244
     * Sends a packet to the server.
245
     * @param string  $packet
246
     * @return void
247
     */
248 64
    function sendPacket(string $packet): void {
249 64
        $initPacklen = \strlen($packet);
250
        
251
        do {
252 64
            $partial = \substr($packet, 0, static::CLIENT_MAX_PACKET_SIZE);
253 64
            $partlen = \strlen($partial);
254
            
255 64
            $packet = \substr($packet, static::CLIENT_MAX_PACKET_SIZE);
256 64
            $packlen = \strlen($packet);
257
            
258 64
            $length = \Plasma\BinaryBuffer::writeInt3($partlen);
259 64
            $sequence = \Plasma\BinaryBuffer::writeInt1((++$this->sequenceID));
260
            
261 64
            $packet = $length.$sequence.$partial;
262
            
263 64
            if($this->compressionEnabled && $this->state === static::STATE_OK) {
264 2
                $packet = $this->compressPacket($packet);
265
            }
266
            
267 64
            $this->connection->write($packet);
268 64
        } while($packlen > static::CLIENT_MAX_PACKET_SIZE);
269
        
270
        // If the packet is exactly the max size, we have to send two packets
271 64
        if($initPacklen === static::CLIENT_MAX_PACKET_SIZE) {
272 1
            $length = \Plasma\BinaryBuffer::writeInt3(0);
273 1
            $sequence = \Plasma\BinaryBuffer::writeInt1((++$this->sequenceID));
274 1
            $packet = $length.$sequence;
275
            
276 1
            if($this->compressionEnabled && $this->state === static::STATE_OK) {
277
                $packet = $this->compressPacket($packet);
278
            }
279
            
280 1
            $this->connection->write($packet);
281
        }
282 64
    }
283
    
284
    /**
285
     * Sets the parse callback.
286
     * @param callable $callback
287
     * @return void
288
     */
289
    function setParseCallback(callable $callback): void {
290
        $this->parseCallback = $callback;
291
    }
292
    
293
    /**
294
     * Processes a command.
295
     * @param \Plasma\CommandInterface|null  $command
296
     * @return void
297
     */
298 64
    protected function processCommand(?\Plasma\CommandInterface $command = null) {
299 64
        if($command === null && $this->currentCommand instanceof \Plasma\CommandInterface) {
300 64
            $command = $this->currentCommand;
301
            
302 64
            if($this->currentCommand instanceof \Plasma\Drivers\MySQL\Commands\CommandInterface) {
303 64
                $state = $command->setParserState();
304 64
                if($state !== -1) {
305 63
                    $this->state = $state;
306
                }
307
            }
308
        }
309
        
310 64
        if($command === null) {
311
            return;
312
        }
313
        
314 64
        if(!($command instanceof \Plasma\Drivers\MySQL\Commands\CommandInterface) || $command->resetSequence()) {
315 61
            $this->sequenceID = -1;
316 61
            $this->compressionID = -1;
317
        }
318
        
319
        try {
320 64
            $msg = $command->getEncodedMessage();
321 2
        } catch (\Plasma\Exception $e) {
322 2
            $this->currentCommand = null;
323 2
            $command->onError($e);
324 2
            return;
325
        }
326
        
327 63
        $this->sendPacket($msg);
328
        
329 63
        if($command !== $this->currentCommand || !$command->waitForCompletion()) {
330 36
            $command->onComplete();
331
            
332 36
            if($command === $this->currentCommand) {
333 36
                $this->currentCommand = null;
334
            }
335
        }
336 63
    }
337
    
338
    /**
339
     * Processes the buffer.
340
     * @return void
341
     */
342 63
    protected function processBuffer() {
343 63
        if($this->buffer->getSize() < 4) {
344
            return;
345
        }
346
        
347 63
        $buffer = clone $this->buffer;
348
        
349 63
        $length = $buffer->readInt3();
350 63
        $this->sequenceID = $buffer->readInt1();
351
        
352 63
        if($length === static::CLIENT_MAX_PACKET_SIZE) {
353
            $this->buffer->read(($length + 4));
354
            $this->messageBuffer->append($buffer->read($length));
355
            return;
356 63
        } elseif($this->messageBuffer->getSize() > 0) {
357
            $this->messageBuffer->append($buffer->read($length));
358
            $buffer = $this->messageBuffer;
359
            $this->messageBuffer = new \Plasma\BinaryBuffer();
360
        }
361
        
362 63
        if($buffer->getSize() < $length) {
363
            return;
364
        }
365
        
366 63
        if($length > 0) {
367 63
            $this->buffer->read(($length + 4));
368 63
            $buffer->slice(0, $length);
369
        } else {
370
            $this->buffer->slice($buffer->getSize());
371
        }
372
        
373 63
        if($buffer->getSize() === 0) {
374
            return;
375
        }
376
        
377
        /** @var \Plasma\Drivers\MySQL\Messages\MessageInterface  $message */
378 63
        $message = null;
379
        
380 63
        if($this->state === static::STATE_INIT) {
381 63
            $message = new \Plasma\Drivers\MySQL\Messages\HandshakeMessage($this);
382
        } else {
383 63
            $firstChar = $buffer->read(1);
384
            
385 63
            $okRespID = \Plasma\Drivers\MySQL\Messages\OkResponseMessage::getID();
386
            $isOkMessage = (
387
                (
388 63
                    $firstChar === $okRespID &&
389 62
                    (!($this->currentCommand instanceof \Plasma\Drivers\MySQL\Commands\QueryCommand)
390 62
                        || \strtoupper(\substr($this->currentCommand->getQuery(), 0, 6)) !== 'SELECT') // Fix for MySQL 5.7
391
                ) ||
392
                (
393 49
                    $firstChar === \Plasma\Drivers\MySQL\Messages\EOFMessage::getID() &&
394 63
                    ($this->handshakeMessage->capability & \Plasma\Drivers\MySQL\CapabilityFlags::CLIENT_DEPRECATE_EOF) !== 0
395
                )
396
            );
397
            
398
            switch(true) {
399 63
                case ($firstChar === \Plasma\Drivers\MySQL\Messages\ErrResponseMessage::getID()):
400 2
                    $message = new \Plasma\Drivers\MySQL\Messages\ErrResponseMessage($this);
401 2
                break;
402 62
                case ($this->currentCommand instanceof \Plasma\Drivers\MySQL\Commands\StatementPrepareCommand && $firstChar === $okRespID):
403 38
                    $message = new \Plasma\Drivers\MySQL\Messages\PrepareStatementOkMessage($this);
404 38
                break;
405 62
                case $isOkMessage:
406 62
                    $message = new \Plasma\Drivers\MySQL\Messages\OkResponseMessage($this);
407 62
                    $this->lastOkMessage = $message;
408 62
                break;
409 48
                case ($this->state < static::STATE_OK && $firstChar === \Plasma\Drivers\MySQL\Messages\AuthMoreDataMessage::getID()):
410
                    $message = new \Plasma\Drivers\MySQL\Messages\AuthMoreDataMessage($this);
411
                break;
412 48
                case ($this->state < static::STATE_OK && $firstChar === \Plasma\Drivers\MySQL\Messages\AuthSwitchRequestMessage::getID()):
413
                    $message = new \Plasma\Drivers\MySQL\Messages\AuthSwitchRequestMessage($this);
414
                break;
415 48
                case ($this->state < static::STATE_OK && $firstChar === \Plasma\Drivers\MySQL\Messages\AuthMoreDataMessage::getID()):
416
                    $message = new \Plasma\Drivers\MySQL\Messages\AuthMoreDataMessage($this);
417
                break;
418 48
                case ($firstChar === \Plasma\Drivers\MySQL\Messages\EOFMessage::getID() && $length < 6):
419
                    $message = new \Plasma\Drivers\MySQL\Messages\EOFMessage($this);
420
                break;
421 48
                case ($firstChar === \Plasma\Drivers\MySQL\Messages\LocalInFileRequestMessage::getID()):
422
                    if($this->driver->getOptions()['localInFile.enable']) {
423
                        $message = new \Plasma\Drivers\MySQL\Messages\LocalInFileRequestMessage($this);
424
                    } else {
425
                        $this->emit('error', array((new \Plasma\Exception('MySQL server requested a local file, but the driver options is disabled'))));
426
                        
427
                        if($this->buffer->getSize() > 0) {
428
                            $this->driver->getLoop()->futureTick(function () {
429
                                $this->processBuffer();
430
                            });
431
                        }
432
                        
433
                        return;
434
                    }
435
                break;
436
                default:
437 48
                    $buffer->prepend($firstChar);
438
                    
439 48
                    if($this->parseCallback !== null) {
440
                        $parse = $this->parseCallback;
441
                        $this->parseCallback = null;
442
                        
443
                        $caller = new \Plasma\Drivers\MySQL\ProtocolOnNextCaller($this, $buffer);
444
                        $parse($caller);
445 48
                    } elseif($this->currentCommand !== null) {
446 48
                        $command = $this->currentCommand;
447
                        
448 48
                        $caller = new \Plasma\Drivers\MySQL\ProtocolOnNextCaller($this, $buffer);
449 48
                        $command->onNext($caller);
450
                        
451 48
                        if($command->hasFinished()) {
452 38
                            $this->currentCommand = null;
453 38
                            $command->onComplete();
454
                        }
455
                    }
456
                    
457 48
                    if($this->buffer->getSize() > 0) {
458
                        $this->driver->getLoop()->futureTick(function () {
459 48
                            $this->processBuffer();
460 48
                        });
461
                    }
462
                    
463 48
                    return;
464
                break;
465
            }
466
        }
467
        
468 63
        $state = $message->setParserState();
469 63
        if($state !== -1) {
470 63
            $this->state = $state;
471
        }
472
        
473 63
        if($message instanceof \Plasma\Drivers\MySQL\Messages\HandshakeMessage) {
474 63
            $this->handshakeMessage = $message;
475
        }
476
        
477 63
        $this->handleMessage($buffer, $message);
478 63
    }
479
    
480
    /**
481
     * Handles an incoming message.
482
     * @param \Plasma\BinaryBuffer                             $buffer
483
     * @param \Plasma\Drivers\MySQL\Messages\MessageInterface  $message
484
     * @return void
485
     */
486 63
    function handleMessage(\Plasma\BinaryBuffer $buffer, \Plasma\Drivers\MySQL\Messages\MessageInterface $message) {
487
        try {
488 63
            $buffer = $message->parseMessage($buffer);
489 63
            if(!$buffer) {
490
                return;
491
            }
492
            
493 63
            if($this->currentCommand !== null) {
494
                if(
495 63
                    ($message instanceof \Plasma\Drivers\MySQL\Messages\OkResponseMessage || $message instanceof \Plasma\Drivers\MySQL\Messages\EOFMessage)
496 63
                    && $this->currentCommand->hasFinished()
497
                ) {
498 62
                    $command = $this->currentCommand;
499 62
                    $this->currentCommand = null;
500
                    
501 62
                    $command->onComplete();
502 61
                } elseif($message instanceof \Plasma\Drivers\MySQL\Messages\ErrResponseMessage) {
503 2
                    $error = new \Plasma\Exception($message->errorMessage, $message->errorCode);
504
                    
505 2
                    $command = $this->currentCommand;
506 2
                    $this->currentCommand = null;
507
                    
508 2
                    $command->onError($error);
509
                } else {
510 60
                    $command = $this->currentCommand;
511 60
                    $command->onNext($message);
512
                    
513 60
                    if($command->hasFinished()) {
514 60
                        if($this->currentCommand === $command) {
515
                            $this->currentCommand = null;
516
                        }
517
                        
518 63
                        $command->onComplete();
519
                    }
520
                }
521 63
            } elseif($message instanceof \Plasma\Drivers\MySQL\Messages\ErrResponseMessage) {
522
                $error = new \Plasma\Exception($message->errorMessage, $message->errorCode);
523
                $this->emit('error', array($error));
524
            }
525
            
526 63
            $this->emit('message', array($message));
527 1
        } catch (\Plasma\Drivers\MySQL\Messages\ParseException $e) {
528
            $state = $e->getState();
529
            if($state !== null) {
530
                $this->state = $state;
531
            }
532
            
533
            $buffer = $e->getBuffer();
534
            if($buffer !== null) {
535
                $this->buffer->clear();
536
                $this->buffer->append($buffer);
537
            }
538
            
539
            if($this->currentCommand !== null) {
540
                $this->currentCommand->onError($e);
541
            }
542
            
543
            $this->emit('error', array($e));
544
            $this->connection->close();
545 1
        } catch (\Plasma\Exception $e) {
546 1
            if($this->currentCommand !== null) {
547 1
                $command = $this->currentCommand;
548 1
                $this->currentCommand = null;
549
                
550 1
                $command->onError($e);
551
            } else {
552
                $this->emit('error', array($e));
553
            }
554
        }
555
        
556 63
        if($this->buffer->getSize() > 0) {
557
            $this->driver->getLoop()->futureTick(function () {
558 38
                $this->processBuffer();
559 38
            });
560
        }
561 63
    }
562
    
563
    /**
564
     * Compresses a packet.
565
     * @param string  $packet
566
     * @return string
567
     */
568 2
    protected function compressPacket(string $packet): string {
569 2
        $length = \strlen($packet);
570 2
        $packetlen = \Plasma\BinaryBuffer::writeInt3($length);
571 2
        $id = \Plasma\BinaryBuffer::writeInt1((++$this->compressionID));
572
        
573 2
        if($length < $this->compressionSizeThreshold) {
574 2
            return $packetlen.$id.\Plasma\BinaryBuffer::writeInt3(0).$packet;
575
        }
576
        
577
        $compressed = \zlib_encode($packet, \ZLIB_ENCODING_DEFLATE);
578
        $compresslen = \Plasma\BinaryBuffer::writeInt3(\strlen($compressed));
579
        
580
        return $compresslen.$id.$compressed;
581
    }
582
    
583
    /**
584
     * Decompresses the buffer.
585
     * @return void
586
     */
587 2
    protected function decompressBuffer(): void {
588 2
        $buffer = new \Plasma\BinaryBuffer();
589
        
590
        // Copy packet header to new buffer
591 2
        for($i = 0; $i < 7; $i++) {
592 2
            $buffer->append($this->compressionBuffer[$i]);
593
        }
594
        
595 2
        $length = $buffer->readInt3();
596 2
        $this->compressionID = $buffer->readInt1();
597 2
        $uncompressedLength = $buffer->readInt3();
598
        
599 2
        if(($this->compressionBuffer->getSize() - 7) < $length) {
600
            return;
601
        }
602
        
603 2
        $this->compressionBuffer->read(7);
604 2
        $buffer = null;
605
        
606 2
        if($uncompressedLength === 0) {
607 2
            $this->buffer->append($this->compressionBuffer->read($length));
608 2
            return;
609
        }
610
        
611 1
        $rawPacket = $this->compressionBuffer->read($length);
612 1
        $packet = \zlib_decode($rawPacket, $uncompressedLength);
613
        
614 1
        if(\strlen($packet) !== $uncompressedLength) {
615
            $packet = "\xFF\x00\x00\x00     Invalid compressed packet";
616
            $this->connection->end($packet);
617
            
618
            return;
619
        }
620
        
621 1
        $this->buffer->append($packet);
622
        
623 1
        if($this->compressionBuffer->getSize() > 7) {
624
            $this->decompressBuffer();
625
        }
626 1
    }
627
    
628
    /**
629
     * Adds the events to the connection.
630
     * @return void
631
     */
632 66
    protected function addEvents() {
633
        $this->connection->on('data', function ($chunk) {
634 63
            if($this->compressionEnabled && $this->state === static::STATE_OK) {
635 2
                $this->compressionBuffer->append($chunk);
636
                
637 2
                if($this->compressionBuffer->getSize() > 7) {
638 2
                    $this->decompressBuffer();
639
                }
640
            } else {
641 63
                $this->buffer->append($chunk);
642
            }
643
            
644 63
            $this->processBuffer();
645 66
        });
646
        
647
        $this->connection->on('close', function () {
648 3
            $this->handleClose();
649 66
        });
650 66
    }
651
    
652
    /**
653
     * Connection close handler.
654
     * @return void
655
     */
656 3
    protected function handleClose() {
657 3
        if($this->state === static::STATE_AUTH || $this->state === static::STATE_AUTH_SENT) {
658
            $this->state = static::STATE_AUTH_ERROR;
659
        }
660
        
661 3
        $this->buffer->clear();
662 3
        $this->messageBuffer->clear();
663 3
        $this->compressionBuffer->clear();
664 3
    }
665
}
666