From a09dd27c7d24225a81da5f2b5bf04576144bc9f1 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Tue, 30 May 2017 16:18:48 -0600 Subject: [PATCH] fixed a bug in message compression pointer handling --- dns.unpack-labels.js | 26 ++++++------ test/fixtures/canone30522.local.bin | Bin 0 -> 556 bytes test/fixtures/canone30522.local.js | 59 ++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 test/fixtures/canone30522.local.bin create mode 100644 test/fixtures/canone30522.local.js diff --git a/dns.unpack-labels.js b/dns.unpack-labels.js index ca791e2..0956fc0 100644 --- a/dns.unpack-labels.js +++ b/dns.unpack-labels.js @@ -29,18 +29,19 @@ exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { break; } - if (0xc0 === len) { - var cpptr = ui8[total + 1]; + // Handle message compression pointers. See 4.1.4 of RFC1035 for details. + if (len >= 0xc0) { + var cpptr = ((ui8[total] & 0x3f) << 8) | ui8[total + 1]; - // we're not coming back! - ptr = cpptr; + // We're not coming back, so if this is the first time we're following one of + // these pointers we up the byteLength to mark the pointer as part of the label if (!q.cpcount) { q.byteLength += 2; // cp and len } q.cpcount += 1; // recursion - return exports.DNS_UNPACK_LABELS(ui8, ptr, q); + return exports.DNS_UNPACK_LABELS(ui8, cpptr, q); } //str.length = 0; // fast empty array @@ -51,27 +52,28 @@ exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { ); } + // Advance the pointer to after the length indicator, then read the string in. + total += 1; for (i = 0; i < len; i += 1) { - total += 1; // TODO check url-allowable characters label.push(String.fromCharCode(ui8[total])); + total += 1; } if (label.length) { q.labels.push(label.join('')); } - total += 1; - + // It is important this be done every time, so that if we run into a message compression + // pointer later we still have a record of what was consumed before that. + if (0 === q.cpcount) { + q.byteLength = total - ptr; + } } while (0 !== len && undefined !== len); //str.pop(); // remove trailing '.' q.name = q.labels.join('.'); - if (0 === q.cpcount) { - q.byteLength = total - ptr; - } - return q; }; diff --git a/test/fixtures/canone30522.local.bin b/test/fixtures/canone30522.local.bin new file mode 100644 index 0000000000000000000000000000000000000000..0fccbcf0531f4ae8fbecbed7f6e4d13eb86609d2 GIT binary patch literal 556 zcmZuv+iDvz5S5G9wMk4{N&|sDB=n_u*z6^)aS8)z)~G4e#o*1ene58-Qdv^8v&DHz zJ|G{G&)7dp<#k&cs6b-oFlWwO#Mm8kr{%8qVs3Kj=SWzR6}W28DKnnb8A`@>o0vzo z_c}qP)xm@h<1jgx30sJ=-rZ?XaT0!rFBL%2GAH; zWJrZpfzC*fzilnRd{wB*N>~z^k3sNH`NvJi0T$NDD>`1%O7^SrYChqgwi+#4D-Qa5oW?4UPX}~ xMfu1dg>mRF2BYZYbi1L>EJFpU#~qv37cBU*9%r}Dm|I)?7wb9OWA2-r{Q@klre^>E literal 0 HcmV?d00001 diff --git a/test/fixtures/canone30522.local.js b/test/fixtures/canone30522.local.js new file mode 100644 index 0000000..169ca3f --- /dev/null +++ b/test/fixtures/canone30522.local.js @@ -0,0 +1,59 @@ +module.exports = { + "header": { + "id": 0, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 0, + "ra": 0, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "question": [], + "answer": [ + { + "name": "_pdl-datastream._tcp.local", + "type": 12, + "class": 1, + "ttl": 255, + "data": "Canon MF620C Series._pdl-datastream._tcp.local" + } + ], + "additional": [ + { + "name": "Canone30522.local", + "type": 1, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canon MF620C Series._pdl-datastream._tcp.local", + "type": 33, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canon MF620C Series._pdl-datastream._tcp.local", + "type": 16, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canone30522.local", + "type": 47, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canon MF620C Series._pdl-datastream._tcp.local", + "type": 47, + "class": 32769, + "ttl": 255, + } + ], + "authority": [], + "edns_options": [] +};