diff -urN ../exim-4.97.orig/src/dns.c ./src/dns.c --- ../exim-4.97.orig/src/dns.c 2023-11-04 14:55:49.000000000 +0200 +++ ./src/dns.c 2023-11-17 21:17:46.681557000 +0200 @@ -431,7 +431,9 @@ if (namelen < 0) goto null_return; /* Move the pointer past the name and fill in the rest of the data structure -from the following bytes. */ +from the following bytes. We seem to be assuming here that the RR blob passed +to us by the resolver library is the same as that defined for an RR by RFC 1035 +section 3.2.1 */ TRACE trace = "R-name"; if (dnss_inc_aptr(dnsa, dnss, namelen)) goto null_return; diff -urN ../exim-4.97.orig/src/lookups/dnsdb.c ./src/lookups/dnsdb.c --- ../exim-4.97.orig/src/lookups/dnsdb.c 2023-11-04 14:55:49.000000000 +0200 +++ ./src/lookups/dnsdb.c 2023-11-17 21:17:58.419591000 +0200 @@ -387,38 +387,31 @@ } /* Other kinds of record just have one piece of data each, but there may be - several of them, of course. */ + several of them, of course. TXT & SPF can have data in multiple chunks. */ if (yield->ptr) yield = string_catn(yield, outsep, 1); if (type == T_TXT || type == T_SPF) - { - if (!outsep2) /* output only the first item of data */ + for (unsigned data_offset = 0; data_offset + 1 < rr->size; ) { - uschar n = (rr->data)[0]; - /* size byte + data bytes must not excced the RRs length */ - if (n + 1 <= rr->size) - yield = string_catn(yield, US (rr->data+1), n); - } - else - for (unsigned data_offset = 0; data_offset < rr->size; ) - { - uschar chunk_len = (rr->data)[data_offset]; - int remain = rr->size - data_offset; + uschar chunk_len = (rr->data)[data_offset]; + int remain; - /* Apparently there are resolvers that do not check RRs before passing - them on, and glibc fails to do so. So every application must... - Check for chunk len exceeding RR */ + if (outsep2 && *outsep2 && data_offset != 0) + yield = string_catn(yield, outsep2, 1); - if (chunk_len > remain) - chunk_len = remain; + /* Apparently there are resolvers that do not check RRs before passing + them on, and glibc fails to do so. So every application must... + Check for chunk len exceeding RR */ - if (*outsep2 && data_offset != 0) - yield = string_catn(yield, outsep2, 1); - yield = string_catn(yield, US ((rr->data) + ++data_offset), --chunk_len); - data_offset += chunk_len; - } - } + remain = rr->size - ++data_offset; + if (chunk_len > remain) + chunk_len = remain; + yield = string_catn(yield, US ((rr->data) + data_offset), chunk_len); + data_offset += chunk_len; + + if (!outsep2) break; /* output only the first chunk of the RR */ + } else if (type == T_TLSA) if (rr->size < 3) continue;