NLnetLabs / ldns

LDNS is a DNS library that facilitates DNS tool programming
https://nlnetlabs.nl/ldns
BSD 3-Clause "New" or "Revised" License
292 stars 98 forks source link

TAB + quote breaks NAPTR parsing #157

Closed FGasper closed 2 years ago

FGasper commented 2 years ago
#include <stdio.h>

#include <ldns/ldns.h>

int main() {

    ldns_rr *rr = NULL;

    const char* strs[] = {
        /* with tab, no regexp quotes */
        "com. 14400 IN NAPTR 100   10 S SIP+D2U !^.*$!sip:customer-service@example.com!\tcom.",

        /* no tab, with regexp quotes */
        "com. 14400 IN NAPTR 100   10 S SIP+D2U \"!^.*$!sip:customer-service@example.com!\" com.",

        /* with tab and regexp quotes */
        "com. 14400 IN NAPTR 100   10 S SIP+D2U \"!^.*$!sip:customer-service@example.com!\"\tcom.",

        NULL,
    };

    fprintf(stderr, "strs[0] = %p; strs[1] = %p; strs[2] = %p\n");

    char** str = strs;

    for (str; *str; str++) {
        printf("%s\n", *str);

        ldns_status s = ldns_rr_new_frm_str(&rr, *str, NULL, NULL, NULL);

        printf("\tparse status: %d\n", s);
    }

    return 0;
}

… when compiled, prints:

com. 14400 IN NAPTR 100   10 S SIP+D2U !^.*$!sip:customer-service@example.com!  com.
    parse status: 0
com. 14400 IN NAPTR 100   10 S SIP+D2U "!^.*$!sip:customer-service@example.com!" com.
    parse status: 0
com. 14400 IN NAPTR 100   10 S SIP+D2U "!^.*$!sip:customer-service@example.com!"com.
    parse status: 104

The TAB shouldn’t break the NAPTR parse.

FGasper commented 2 years ago

Looks similar to #147 … probably just needs a similar fix.

FGasper commented 2 years ago

Seen in latest master as well as 1.8.1. We believe it worked before 1.8.0, but I haven’t confirmed.

FGasper commented 2 years ago

This fixes it:

diff --git a/rr.c b/rr.c
index 433e61d4..5fc9c733 100644
--- a/rr.c
+++ b/rr.c
@@ -398,7 +398,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,

                /* skip spaces */
                while (ldns_buffer_position(rd_buf) < ldns_buffer_limit(rd_buf)
-                               && *(ldns_buffer_current(rd_buf)) == ' '
+                               && NULL != strchr( LDNS_PARSE_NO_NL, *(ldns_buffer_current(rd_buf)))
                                && !quoted) {

                        ldns_buffer_skip(rd_buf, 1);

Should probably roll up that NULL != … stuff into a nice macro.