From 4d1c3adfae90c829e041995d91fc28fb1b3d610e Mon Sep 17 00:00:00 2001 From: Marek Vavrusa <marek.vavrusa@nic.cz> Date: Fri, 26 Jul 2013 15:30:41 +0200 Subject: [PATCH] Fixed skipping of multiple compr. ptrs at once. Also correct size calculation of dname parse of compressed data. --- src/libknot/dname.c | 19 ++++++++++--------- src/libknot/util/wire.h | 10 +++++++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/libknot/dname.c b/src/libknot/dname.c index 8fc8e8ab8..682d6367f 100644 --- a/src/libknot/dname.c +++ b/src/libknot/dname.c @@ -50,11 +50,16 @@ knot_dname_t *knot_dname_parse(const uint8_t *pkt, size_t *pos, size_t maxpos) if (parsed < 0) return NULL; + /* Calculate decompressed length. */ + int decompressed_len = knot_dname_wire_size(name, pkt); + if (decompressed_len < parsed) + return NULL; + /* Allocate space for the name. */ - knot_dname_t *res = malloc(parsed); + knot_dname_t *res = malloc(decompressed_len); if (res) { /* Unpack name (expand compression pointers). */ - if (knot_dname_unpack(res, name, parsed, pkt) > 0) { + if (knot_dname_unpack(res, name, decompressed_len, pkt) > 0) { *pos += parsed; } else { free(res); @@ -125,9 +130,7 @@ int knot_dname_unpack(uint8_t* dst, const knot_dname_t *src, return KNOT_EINVAL; /* Seek first real label occurence. */ - while (knot_wire_is_pointer(src)) { - src = knot_wire_next_label(src, pkt); - } + src = knot_wire_seek_label(src, pkt); /* Unpack rest of the labels. */ int len = 0; @@ -570,14 +573,12 @@ int knot_dname_prefixlen(const uint8_t *name, unsigned nlabels, const uint8_t *p return 1; /* Seek first real label occurence. */ - while (knot_wire_is_pointer(name)) { - name = knot_wire_next_label((uint8_t *)name, (uint8_t *)pkt); - } + name = knot_wire_seek_label(name, pkt); int len = 1; /* Terminal label */ while (*name != '\0') { len += *name + 1; - name = knot_wire_next_label((uint8_t *)name, (uint8_t *)pkt); + name = knot_wire_next_label(name, pkt); if (--nlabels == 0) /* Count N first labels only. */ break; } diff --git a/src/libknot/util/wire.h b/src/libknot/util/wire.h index 80588a689..a556636d1 100644 --- a/src/libknot/util/wire.h +++ b/src/libknot/util/wire.h @@ -955,10 +955,9 @@ static inline uint16_t knot_wire_get_pointer(const uint8_t *pos) return (knot_wire_read_u16(pos) - KNOT_WIRE_PTR_BASE); // Return offset. } -static inline const uint8_t *knot_wire_next_label(const uint8_t *lp, const uint8_t *wire) +static inline const uint8_t *knot_wire_seek_label(const uint8_t *lp, const uint8_t *wire) { - lp = lp + (lp[0] + sizeof(uint8_t)); - if (knot_wire_is_pointer(lp)) { + while (knot_wire_is_pointer(lp)) { if (!wire) return NULL; lp = wire + knot_wire_get_pointer(lp); @@ -966,6 +965,11 @@ static inline const uint8_t *knot_wire_next_label(const uint8_t *lp, const uint8 return lp; } +static inline const uint8_t *knot_wire_next_label(const uint8_t *lp, const uint8_t *wire) +{ + return knot_wire_seek_label(lp + (lp[0] + sizeof(uint8_t)), wire); +} + #endif /* _KNOT_WIRE_H_ */ /*! @} */ -- GitLab