diff --git a/src/rr-dict.c b/src/rr-dict.c index b269e19b..ceb66ad5 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -56,11 +56,6 @@ apl_n_wire2dict(getdns_dict *dict, const uint8_t *rdf) return getdns_dict_set_int(dict, "n", (*rdf >> 7)); } static getdns_return_t -apl_n_wire2list(getdns_list *list, const uint8_t *rdf) -{ - return _getdns_list_append_int(list, (*rdf >> 7)); -} -static getdns_return_t apl_n_2wire(uint32_t value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) { (void)rdata; /* unused parameter */ @@ -85,22 +80,10 @@ apl_n_dict2wire(const getdns_dict *dict, else return apl_n_2wire(value, rdata, rdf, rdf_len); } -static getdns_return_t -apl_n_list2wire(const getdns_list *list, size_t i, - uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) -{ - getdns_return_t r; - uint32_t value; - - if ((r = getdns_list_get_int(list, i, &value))) - return r; - else - return apl_n_2wire(value, rdata, rdf, rdf_len); -} static _getdns_rdf_special apl_n = { apl_n_rdf_end, - apl_n_wire2dict, apl_n_wire2list, - apl_n_dict2wire, apl_n_list2wire + apl_n_wire2dict, NULL, + apl_n_dict2wire, NULL }; static const uint8_t * @@ -118,11 +101,6 @@ apl_afdpart_wire2dict(getdns_dict *dict, const uint8_t *rdf) dict, "afdpart", (rdf[-1] & 0x7F), rdf); } static getdns_return_t -apl_afdpart_wire2list(getdns_list *list, const uint8_t *rdf) -{ - return _getdns_list_append_const_bindata(list, (rdf[-1] & 0x7F), rdf); -} -static getdns_return_t apl_afdpart_2wire( const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) { @@ -156,22 +134,10 @@ apl_afdpart_dict2wire( else return apl_afdpart_2wire(value, rdata, rdf, rdf_len); } -static getdns_return_t -apl_afdpart_list2wire(const getdns_list *list, - size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) -{ - getdns_return_t r; - getdns_bindata *value; - - if ((r = getdns_list_get_bindata(list, i, &value))) - return r; - else - return apl_afdpart_2wire(value, rdata, rdf, rdf_len); -} static _getdns_rdf_special apl_afdpart = { apl_afdpart_rdf_end, - apl_afdpart_wire2dict, apl_afdpart_wire2list, - apl_afdpart_dict2wire, apl_afdpart_list2wire + apl_afdpart_wire2dict, NULL, + apl_afdpart_dict2wire, NULL }; static const uint8_t * @@ -246,30 +212,12 @@ ipseckey_gateway_wire2dict(getdns_dict *dict, const uint8_t *rdf) return _getdns_dict_set_const_bindata(dict, "gateway", size, data); } static getdns_return_t -ipseckey_gateway_wire2list(getdns_list *list, const uint8_t *rdf) -{ - size_t size; - const uint8_t *data; - - if (ipseckey_gateway_equip_const_bindata(rdf, &size, &data)) - return GETDNS_RETURN_GENERIC_ERROR; - - else if (!size) - return GETDNS_RETURN_GOOD; - else - return _getdns_list_append_const_bindata(list, size, data); -} -static getdns_return_t ipseckey_gateway_2wire( const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) { - if (rdf - 2 < rdata) - return GETDNS_RETURN_GENERIC_ERROR; + assert(rdf - 2 >= rdata && rdf[-2] > 0); switch (rdf[-2]) { - case 0: if (value && value->size > 0) - return GETDNS_RETURN_INVALID_PARAMETER; - break; case 1: if (!value || value->size != 4) return GETDNS_RETURN_INVALID_PARAMETER; if (*rdf_len < 4) { @@ -310,27 +258,22 @@ ipseckey_gateway_dict2wire( getdns_return_t r; getdns_bindata *value; - if ((r = getdns_dict_get_bindata(dict, "gateway", &value))) - return r; - else - return ipseckey_gateway_2wire(value, rdata, rdf, rdf_len); -} -static getdns_return_t -ipseckey_gateway_list2wire(const getdns_list *list, - size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) -{ - getdns_return_t r; - getdns_bindata *value; + if (rdf - 2 < rdata) + return GETDNS_RETURN_GENERIC_ERROR; - if ((r = getdns_list_get_bindata(list, i, &value))) + else if (rdf[-2] == 0) { + *rdf_len = 0; + return GETDNS_RETURN_GOOD; + } + else if ((r = getdns_dict_get_bindata(dict, "gateway", &value))) return r; else return ipseckey_gateway_2wire(value, rdata, rdf, rdf_len); } static _getdns_rdf_special ipseckey_gateway = { ipseckey_gateway_rdf_end, - ipseckey_gateway_wire2dict, ipseckey_gateway_wire2list, - ipseckey_gateway_dict2wire, ipseckey_gateway_list2wire + ipseckey_gateway_wire2dict, NULL, + ipseckey_gateway_dict2wire, NULL }; static const uint8_t * @@ -348,11 +291,6 @@ hip_pk_algorithm_wire2dict(getdns_dict *dict, const uint8_t *rdf) return getdns_dict_set_int(dict, "pk_algorithm", rdf[1]); } static getdns_return_t -hip_pk_algorithm_wire2list(getdns_list *list, const uint8_t *rdf) -{ - return _getdns_list_append_int(list, rdf[1]); -} -static getdns_return_t hip_pk_algorithm_2wire(uint32_t value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) { if (rdata != rdf) @@ -379,22 +317,10 @@ hip_pk_algorithm_dict2wire( else return hip_pk_algorithm_2wire(value, rdata, rdf, rdf_len); } -static getdns_return_t -hip_pk_algorithm_list2wire(const getdns_list *list, - size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) -{ - getdns_return_t r; - uint32_t value; - - if ((r = getdns_list_get_int(list, i, &value))) - return r; - else - return hip_pk_algorithm_2wire(value, rdata, rdf, rdf_len); -} static _getdns_rdf_special hip_pk_algorithm = { hip_pk_algorithm_rdf_end, - hip_pk_algorithm_wire2dict, hip_pk_algorithm_wire2list, - hip_pk_algorithm_dict2wire, hip_pk_algorithm_list2wire + hip_pk_algorithm_wire2dict, NULL, + hip_pk_algorithm_dict2wire, NULL }; static const uint8_t * @@ -411,11 +337,6 @@ hip_hit_wire2dict(getdns_dict *dict, const uint8_t *rdf) return _getdns_dict_set_const_bindata(dict, "hit", rdf[-1], rdf + 3); } static getdns_return_t -hip_hit_wire2list(getdns_list *list, const uint8_t *rdf) -{ - return _getdns_list_append_const_bindata(list, rdf[-1], rdf + 3); -} -static getdns_return_t hip_hit_2wire( const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) { @@ -449,22 +370,10 @@ hip_hit_dict2wire( else return hip_hit_2wire(value, rdata, rdf, rdf_len); } -static getdns_return_t -hip_hit_list2wire(const getdns_list *list, - size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) -{ - getdns_return_t r; - getdns_bindata *value; - - if ((r = getdns_list_get_bindata(list, i, &value))) - return r; - else - return hip_hit_2wire(value, rdata, rdf, rdf_len); -} static _getdns_rdf_special hip_hit = { hip_hit_rdf_end, - hip_hit_wire2dict, hip_hit_wire2list, - hip_hit_dict2wire, hip_hit_list2wire + hip_hit_wire2dict, NULL, + hip_hit_dict2wire, NULL }; static const uint8_t * @@ -483,12 +392,6 @@ hip_public_key_wire2dict(getdns_dict *dict, const uint8_t *rdf) dict, "public_key", gldns_read_uint16(rdf), rdf + 2 + rdf[-2]); } static getdns_return_t -hip_public_key_wire2list(getdns_list *list, const uint8_t *rdf) -{ - return _getdns_list_append_const_bindata( - list, gldns_read_uint16(rdf), rdf + 2 + rdf[-2]); -} -static getdns_return_t hip_public_key_2wire( const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) { @@ -522,22 +425,10 @@ hip_public_key_dict2wire( else return hip_public_key_2wire(value, rdata, rdf, rdf_len); } -static getdns_return_t -hip_public_key_list2wire( - const getdns_list *list, size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len) -{ - getdns_return_t r; - getdns_bindata *value; - - if ((r = getdns_list_get_bindata(list, i, &value))) - return r; - else - return hip_public_key_2wire(value, rdata, rdf, rdf_len); -} static _getdns_rdf_special hip_public_key = { hip_public_key_rdf_end, - hip_public_key_wire2dict, hip_public_key_wire2list, - hip_public_key_dict2wire, hip_public_key_list2wire + hip_public_key_wire2dict, NULL, + hip_public_key_dict2wire, NULL }; @@ -1120,7 +1011,12 @@ write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start, return GETDNS_RETURN_GENERIC_ERROR; } else if (!(rd_def->type & GETDNS_RDF_REPEAT)) { - + /* + * Non repetitive special rdatafield, + * We must have a dict2wire function + */ + assert(rd_def->special->dict2wire); + rdf_len = gldns_buffer_remaining(buf); r = rd_def->special->dict2wire(rdata, rdata_start, gldns_buffer_current(buf), &rdf_len); @@ -1130,12 +1026,21 @@ write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start, if (r) return r; + /* We do not have repetitive special rdata fields (yet) + * + * LCOV_EXCL_START + */ } else if ((r = getdns_dict_get_list(rdata, rd_def->name, &list))) { return r == GETDNS_RETURN_NO_SUCH_DICT_NAME ? GETDNS_RETURN_GOOD : r; } else for ( i = 0; r == GETDNS_RETURN_GOOD; i++ ) { + /* + * A repetitive special rdata field must have the list2wire + * function. + */ + assert(rd_def->special->list2wire); rdf_len = gldns_buffer_remaining(buf); r = rd_def->special->list2wire(list, i, rdata_start, @@ -1144,6 +1049,7 @@ write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start, r == GETDNS_RETURN_NEED_MORE_SPACE) gldns_buffer_skip(buf, rdf_len); } + /* LCOV_EXCL_STOP */ return r != GETDNS_RETURN_NO_SUCH_LIST_ITEM ? r : GETDNS_RETURN_GOOD; } diff --git a/src/rr-iter.c b/src/rr-iter.c index ede6b2b5..7d57ace7 100644 --- a/src/rr-iter.c +++ b/src/rr-iter.c @@ -518,8 +518,16 @@ rdf_iter_find_nxt(_getdns_rdf_iter *i) /* Empty rdata fields are only allowed in case of non-repeating * remaining data. So only the GETDNS_RDF_BINDATA bit is set. + * + * There is one exception, the IPSECKEY has an empty special rdata + * field "gateway" when another rdata field, "gateway_type" is 0. + * In general, the special wire2dict or list functions should + * handle this case themselves, so allow for 0 sized RDF_SPECIAL + * typed rdata fields too. */ - (i->nxt > i->pos || (i->rdd_pos->type == GETDNS_RDF_BINDATA))) + ( i->nxt > i->pos + || i->rdd_pos->type == GETDNS_RDF_BINDATA + || i->rdd_pos->type == GETDNS_RDF_SPECIAL)) return i; done: i->pos = NULL; diff --git a/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.c b/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.c index 16933760..0e69eb4c 100644 --- a/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.c +++ b/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.c @@ -70,6 +70,7 @@ int main(int argc, char const * const argv[]) FILE *in; uint8_t wire_buf[8200]; size_t i; + size_t uavailable; int available; char str_buf[10000]; int str_len = sizeof(str_buf); @@ -300,15 +301,20 @@ int main(int argc, char const * const argv[]) * Then fill a string buffer with those rr_dicts. */ available = wire - wire_buf; + if (available < 0) { + fprintf(stderr, "Negative sized buffer!\n"); + exit(EXIT_FAILURE); + } + uavailable = available; wire = wire_buf; str = str_buf; str_len = sizeof(str_buf); - while (available > 0 && str_len > 0) { + while (uavailable > 0 && str_len > 0) { rr_dict = NULL; if ((r = getdns_wire2rr_dict_scan( - (const uint8_t **)&wire, &available, &rr_dict))) + (const uint8_t **)&wire, &uavailable, &rr_dict))) FAIL_r("getdns_wire2rr_dict_scan"); if ((r = getdns_rr_dict2str_scan(rr_dict, &str, &str_len))) diff --git a/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good b/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good index 47278b10..9079ef9a 100644 --- a/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good +++ b/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good @@ -1478,6 +1478,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. "algorithm": 10, "gateway_type": 0, "precedence": 2, + "public_key": , "rdata_raw": }, "ttl": 30, @@ -1536,6 +1537,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. "algorithm": 10, "gateway_type": 0, "precedence": 2, + "public_key": , "rdata_raw": }, "ttl": 30, diff --git a/src/test/tpkg/265-supported-rrs.tpkg/265-supported-rrs.good b/src/test/tpkg/265-supported-rrs.tpkg/265-supported-rrs.good index c48d3178..4fa8af97 100644 --- a/src/test/tpkg/265-supported-rrs.tpkg/265-supported-rrs.good +++ b/src/test/tpkg/265-supported-rrs.tpkg/265-supported-rrs.good @@ -395,6 +395,7 @@ "algorithm": 10, "gateway_type": 0, "precedence": 2, + "public_key": , "rdata_raw": }, "ttl": 30, @@ -453,6 +454,7 @@ "algorithm": 10, "gateway_type": 0, "precedence": 2, + "public_key": , "rdata_raw": }, "ttl": 30, @@ -1000,7 +1002,7 @@ } ] ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0 -;; flags: ; QUERY: 0, ANSWER: 75, AUTHORITY: 0, ADDITIONAL: 0 +;; flags: ; QUERY: 0, ANSWER: 77, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;; ANSWER SECTION: @@ -1033,9 +1035,11 @@ eui64.net-dns.org. 30 IN EUI64 00-00-5e-ef-10-00-00-2a gpos.net-dns.org. 30 IN GPOS "-32.6882" "116.8652" "10.0" hinfo.net-dns.org. 30 IN HINFO "CPU" "OS" hip.net-dns.org. 30 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D +ipseckey0.net-dns.org. 30 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ipseckey1.net-dns.org. 30 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ipseckey2.net-dns.org. 30 IN IPSECKEY 10 2 2 2001:db8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ipseckey3.net-dns.org. 30 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== +ipseckey.net-dns.org. 30 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ipseckey.net-dns.org. 30 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ipseckey.net-dns.org. 30 IN IPSECKEY 10 2 2 2001:db8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ipseckey.net-dns.org. 30 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== @@ -1083,5 +1087,5 @@ x25.net-dns.org. 30 IN X25 "1234567" ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: -;; MSG SIZE rcvd: 5189 +;; MSG SIZE rcvd: 5328 diff --git a/src/test/tpkg/clean.sh b/src/test/tpkg/clean.sh index b3ebef5e..e71f3114 100755 --- a/src/test/tpkg/clean.sh +++ b/src/test/tpkg/clean.sh @@ -3,5 +3,5 @@ export SRCDIR=`dirname $0` ( cd $SRCDIR ./tpkg clean - rm -fr build build-stub-only build-event-loops install scan-build-reports .tpkg.var.master + rm -fr build build-stub-only build-event-loops install scan-build-reports .tpkg.var.master *.info ) diff --git a/src/util-internal.c b/src/util-internal.c index ddac7b51..808944c3 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -340,10 +340,22 @@ _getdns_rr_iter2rr_dict_canonical( repeat_list, bin_size, bin_data)) goto rdata_error; break; + + /* Repetitive special types do not exist (yet) + * + * LCOV_EXCL_START + */ case wf_special: + /* Repetitive special types + * must have this function + */ + assert(rdf->rdd_pos->special->wire2list); + if (rdf->rdd_pos->special->wire2list( repeat_list, rdf->pos)) goto rdata_error; + /* LCOV_EXCL_STOP */ + default: break; }