]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Fix #166 Grow buffer when converting to presentation format
authorWillem Toorop <willem@nlnetlabs.nl>
Tue, 12 Jul 2022 14:53:56 +0000 (16:53 +0200)
committerWillem Toorop <willem@nlnetlabs.nl>
Tue, 12 Jul 2022 14:53:56 +0000 (16:53 +0200)
Changelog
host2str.c
ldns/buffer.h

index 2a9b79e6ce7abfd63aaba728e6e0efe4b8860a39..601a2ecf284a6327183912c26072b9fc47da797b 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -8,6 +8,9 @@
        * Enable compile of SVCB and HTTPS support by default.
        * bugfix #179: Free line memory even if zone file parsing fails
          Thanks Claudius Zingerli
+       * bugfix #166: Grow buffer when writing chars and fixed size
+         strings when converting to presentation format, preventing
+         potential assersion errors.
 
 1.8.1  2021-12-03
        * bugfix #146: ldns-1.7.1 had soname 3.0, so ldns-1.8.x soname
index 45b3f42de65ab9eb998ed54dc8de46cf85dab6b2..b0c76e934fdf7aab3f52e1fc5cd31265ef8a175d 100644 (file)
@@ -1286,7 +1286,7 @@ ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
 
                ldns_buffer_printf(output, "%02x", (int) *data);
        }
-       ldns_buffer_write_u8(output, (uint8_t) ' ');
+       ldns_buffer_write_char(output, (uint8_t) ' ');
 
        if (ldns_buffer_reserve(output,
                                ldns_b64_ntop_calculate_size(pk_size))) {
@@ -1402,7 +1402,7 @@ svcparam_mandatory2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
 
        svcparam_key2buffer_str(output, ldns_read_uint16(data));
        for (data += 2, sz -= 2; sz; data += 2, sz -= 2) {
-               ldns_buffer_write_u8(output, ',');
+               ldns_buffer_write_char(output, ',');
                svcparam_key2buffer_str(output, ldns_read_uint16(data));
        }
        return ldns_buffer_status(output);
@@ -1425,7 +1425,7 @@ svcparam_alpn2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
                quote = i < *dp;
        }
        if (quote)
-               ldns_buffer_write_u8(output, '"');
+               ldns_buffer_write_char(output, '"');
        while (data < eod) {
                uint8_t *eot = data + 1 + *data;
 
@@ -1433,22 +1433,22 @@ svcparam_alpn2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
                        return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
 
                if (eod - data < (int)sz)
-                       ldns_buffer_write_u8(output, ',');
+                       ldns_buffer_write_char(output, ',');
 
                for (data += 1; data < eot; data += 1) {
                        uint8_t ch = *data;
 
                        if (isprint(ch) || ch == '\t') {
                                if (ch == '"' ||  ch == ',' || ch == '\\')
-                                       ldns_buffer_write_u8(output, '\\');
-                               ldns_buffer_write_u8(output, ch);
+                                       ldns_buffer_write_char(output, '\\');
+                               ldns_buffer_write_char(output, ch);
                        } else
                                ldns_buffer_printf(output, "\\%03u"
                                                         , (unsigned)ch);
                }
        }
        if (quote)
-               ldns_buffer_write_u8(output, '"');
+               ldns_buffer_write_char(output, '"');
        return ldns_buffer_status(output);
 }
 
@@ -1469,14 +1469,14 @@ svcparam_ipv4hint2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
        if (sz % 4 || !inet_ntop(AF_INET, data, str, INET_ADDRSTRLEN))
                return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
 
-       ldns_buffer_write_string(output, str);
+       ldns_buffer_write_chars(output, str);
 
        for (data += 4, sz -= 4; sz ; data += 4, sz -= 4 ) {
-               ldns_buffer_write_u8(output, ',');
+               ldns_buffer_write_char(output, ',');
                if (!inet_ntop(AF_INET, data, str, INET_ADDRSTRLEN))
                        return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
 
-               ldns_buffer_write_string(output, str);
+               ldns_buffer_write_chars(output, str);
        }
        return ldns_buffer_status(output);
 }
@@ -1508,14 +1508,14 @@ svcparam_ipv6hint2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
        if (sz % 16 || !inet_ntop(AF_INET6, data, str, INET6_ADDRSTRLEN))
                return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
 
-       ldns_buffer_write_string(output, str);
+       ldns_buffer_write_chars(output, str);
 
        for (data += 16, sz -= 16; sz ; data += 16, sz -= 16) {
-               ldns_buffer_write_u8(output, ',');
+               ldns_buffer_write_char(output, ',');
                if (!inet_ntop(AF_INET6, data, str, INET6_ADDRSTRLEN))
                        return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
 
-               ldns_buffer_write_string(output, str);
+               ldns_buffer_write_chars(output, str);
        }
        return ldns_buffer_status(output);
 }
@@ -1530,20 +1530,20 @@ svcparam_value2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
                ; /* pass */
 
        if ((quote = dp < eod))
-               ldns_buffer_write_u8(output, '"');
+               ldns_buffer_write_char(output, '"');
 
        for (dp = data; dp < eod; dp++) {
                uint8_t ch = *dp;
 
                if (isprint(ch) || ch == '\t') {
                        if (ch == '"' ||  ch == '\\')
-                               ldns_buffer_write_u8(output, '\\');
-                       ldns_buffer_write_u8(output, ch);
+                               ldns_buffer_write_char(output, '\\');
+                       ldns_buffer_write_char(output, ch);
                } else
                        ldns_buffer_printf(output, "\\%03u", (unsigned)ch);
        }
        if (quote)
-               ldns_buffer_write_u8(output, '"');
+               ldns_buffer_write_char(output, '"');
        return ldns_buffer_status(output);
 }
 
@@ -1569,7 +1569,7 @@ ldns_rdf2buffer_str_svcparams(ldns_buffer *output, const ldns_rdf *rdf)
                        return LDNS_STATUS_RDATA_OVERFLOW;
 
                if (dp > data)
-                       ldns_buffer_write_u8(output, ' ');
+                       ldns_buffer_write_char(output, ' ');
 
                if ((st = svcparam_key2buffer_str(output, key)))
                        return st;
@@ -1577,7 +1577,7 @@ ldns_rdf2buffer_str_svcparams(ldns_buffer *output, const ldns_rdf *rdf)
                if (val_sz == 0)
                        continue;
                dp += 4;
-               ldns_buffer_write_u8(output, '=');
+               ldns_buffer_write_char(output, '=');
                switch (key) {
                case LDNS_SVCPARAM_KEY_MANDATORY:
                        st = svcparam_mandatory2buffer_str(output, val_sz, dp);
@@ -2653,7 +2653,7 @@ ldns_buffer2str(ldns_buffer *buffer)
                if (!ldns_buffer_reserve(buffer, 1)) {
                        return NULL;
                }
-               ldns_buffer_write_u8(buffer, (uint8_t) '\0');
+               ldns_buffer_write_char(buffer, (uint8_t) '\0');
                if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
                        return NULL;
                }
@@ -2676,7 +2676,7 @@ ldns_buffer_export2str(ldns_buffer *buffer)
        if (! ldns_buffer_reserve(buffer, 1)) {
                return NULL;
        }
-       ldns_buffer_write_u8(buffer, 0);
+       ldns_buffer_write_char(buffer, 0);
 
        /* reallocate memory to the size of the string and export */
        ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
index f49a550bbd15a521a64a9658ce7bb80f9aada4c9..79ae0f5cc15e2d5f5630d5de8e4e46697ccf8015 100644 (file)
@@ -399,6 +399,22 @@ ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
        ldns_buffer_write(buffer, str, strlen(str));
 }
 
+/**
+ * copies the given (null-delimited) string to the current position at the buffer
+ * increasing the capacity if necessary
+ * \param[in] buffer the buffer
+ * \param[in] str the string to write
+ */
+INLINE void
+ldns_buffer_write_chars(ldns_buffer *buffer, const char *str)
+{
+       if (!ldns_buffer_reserve(buffer, strlen(str)))
+               buffer->_status = LDNS_STATUS_MEM_ERR;
+       else
+               ldns_buffer_write_string(buffer, str);
+}
+
+
 /**
  * writes the given byte of data at the given position in the buffer
  * \param[in] buffer the buffer
@@ -424,6 +440,21 @@ ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
        buffer->_position += sizeof(data);
 }
 
+/**
+ * writes the given byte of data at the current position in the buffer
+ * increasing the capacity if necessary
+ * \param[in] buffer the buffer
+ * \param[in] data the 8 bits to write
+ */
+INLINE void
+ldns_buffer_write_char(ldns_buffer *buffer, uint8_t data)
+{
+       if (!ldns_buffer_reserve(buffer, sizeof(data)))
+               buffer->_status = LDNS_STATUS_MEM_ERR;
+       else
+               ldns_buffer_write_u8(buffer, data);
+}
+
 /**
  * writes the given 2 byte integer at the given position in the buffer
  * \param[in] buffer the buffer