Skip to content

Commit 31b5641

Browse files
authored
Merge pull request #169 from clue-labs/compression-recurse
Improve DNS response parser to limit recursion for compressed labels
2 parents 6652607 + 6c3cbb0 commit 31b5641

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

src/Protocol/Parser.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,13 @@ function ($label) {
301301
);
302302
}
303303

304-
private function readLabels($data, $consumed)
304+
/**
305+
* @param string $data
306+
* @param int $consumed
307+
* @param int $compressionDepth maximum depth for compressed labels to avoid unreasonable recursion
308+
* @return array
309+
*/
310+
private function readLabels($data, $consumed, $compressionDepth = 127)
305311
{
306312
$labels = array();
307313

@@ -319,14 +325,14 @@ private function readLabels($data, $consumed)
319325
}
320326

321327
// first two bits set? this is a compressed label (14 bit pointer offset)
322-
if (($length & 0xc0) === 0xc0 && isset($data[$consumed + 1])) {
328+
if (($length & 0xc0) === 0xc0 && isset($data[$consumed + 1]) && $compressionDepth) {
323329
$offset = ($length & ~0xc0) << 8 | \ord($data[$consumed + 1]);
324330
if ($offset >= $consumed) {
325331
return array(null, null);
326332
}
327333

328334
$consumed += 2;
329-
list($newLabels) = $this->readLabels($data, $offset);
335+
list($newLabels) = $this->readLabels($data, $offset, $compressionDepth - 1);
330336

331337
if ($newLabels === null) {
332338
return array(null, null);

tests/Protocol/ParserTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,18 @@ public function testParseInvalidOffsetPointerToSameLabelInQuestionNameThrows()
811811
$this->parser->parseMessage($data);
812812
}
813813

814+
public function testParseInvalidOffsetPointerToPreviousLabelInQuestionNameThrows()
815+
{
816+
$data = "";
817+
$data .= "72 62 01 00 00 01 00 00 00 00 00 00"; // header
818+
$data .= "02 69 6f c0 0c"; // question: offset pointer to previous label
819+
820+
$data = $this->convertTcpDumpToBinary($data);
821+
822+
$this->setExpectedException('InvalidArgumentException');
823+
$this->parser->parseMessage($data);
824+
}
825+
814826
public function testParseInvalidOffsetPointerToStartOfMessageInQuestionNameThrows()
815827
{
816828
$data = "";

0 commit comments

Comments
 (0)