Commit 67d75732 authored by Mark Andrews's avatar Mark Andrews
Browse files

Merge branch '899-add-totext-fromtext-to-wirechecks' into 'master'

Run wire check through "totext" and "fromtext" methods including multi-line.

See merge request !1572
parents 961d256d 307a1b56
Pipeline #13318 passed with stages
in 59 seconds
5208. [test] Run valid rdata wire encodings through totext+fromtext
and tofmttext+fromtext methods to check these methods.
[GL #899]
5207. [test] Check delv and dig TTL values. [GL #965]
 
5206. [bug] Delv could print out bad TTLs. [GL #965]
......
......@@ -569,6 +569,10 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
if (result != ISC_R_SUCCESS)
goto cleanup_inc;
lctx->keep_lex = false;
/*
* If specials change update dns_test_rdatafromstring()
* in lib/dns/tests/dnstest.c.
*/
memset(specials, 0, sizeof(specials));
specials[0] = 1;
specials['('] = 1;
......
......@@ -87,14 +87,14 @@ struct dns_master_style {
*/
typedef struct dns_totext_ctx {
dns_master_style_t style;
bool class_printed;
bool class_printed;
char * linebreak;
char linebreak_buf[DNS_TOTEXT_LINEBREAK_MAXLEN];
dns_name_t * origin;
dns_name_t * neworigin;
dns_fixedname_t origin_fixname;
uint32_t current_ttl;
bool current_ttl_valid;
bool current_ttl_valid;
dns_ttl_t serve_stale_ttl;
} dns_totext_ctx_t;
......
......@@ -481,6 +481,7 @@ dns_test_rdatafromstring(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
dns_rdatacallbacks_t callbacks;
isc_buffer_t source, target;
isc_lex_t *lex = NULL;
isc_lexspecials_t specials = { 0 };
isc_result_t result;
size_t length;
......@@ -504,6 +505,22 @@ dns_test_rdatafromstring(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
return (result);
}
/*
* Set characters which will be treated as valid multi-line RDATA
* delimiters while reading the source string. These should match
* specials from lib/dns/master.c.
*/
specials[0] = 1;
specials['('] = 1;
specials[')'] = 1;
specials['"'] = 1;
isc_lex_setspecials(lex, specials);
/*
* Expect DNS masterfile comments.
*/
isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
/*
* Point lexer at source.
*/
......
......@@ -34,6 +34,8 @@
#include "dnstest.h"
static bool debug = false;
/*
* An array of these structures is passed to compare_ok().
*/
......@@ -101,7 +103,14 @@ typedef struct wire_ok {
ok \
}
#define WIRE_VALID(...) WIRE_TEST(true, __VA_ARGS__)
#define WIRE_INVALID(...) WIRE_TEST(false, __VA_ARGS__)
/*
* WIRE_INVALID() test cases must always have at least one octet specified to
* distinguish them from WIRE_SENTINEL(). Use the 'empty_ok' parameter passed
* to check_wire_ok() for indicating whether empty RDATA is allowed for a given
* RR type or not.
*/
#define WIRE_INVALID(FIRST, ...) \
WIRE_TEST(false, FIRST, __VA_ARGS__)
#define WIRE_SENTINEL() WIRE_TEST(false)
/*
......@@ -212,8 +221,14 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
* Check whether result is as expected.
*/
if (text_ok->text_out != NULL) {
if (debug && result != ISC_R_SUCCESS) {
fprintf(stdout, "#'%s'\n", text_ok->text_in);
}
assert_int_equal(result, ISC_R_SUCCESS);
} else {
if (debug && result == ISC_R_SUCCESS) {
fprintf(stdout, "#'%s'\n", text_ok->text_in);
}
assert_int_not_equal(result, ISC_R_SUCCESS);
}
......@@ -232,6 +247,16 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
isc_buffer_init(&target, buf_totext, sizeof(buf_totext));
result = dns_rdata_totext(&rdata, NULL, &target);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Ensure buf_totext is properly NUL terminated as dns_rdata_totext()
* may attempt different output formats writing into the apparently
* unused part of the buffer.
*/
isc_buffer_putuint8(&target, 0);
if (debug && strcmp(buf_totext, text_ok->text_out) != 0) {
fprintf(stdout, "# '%s' != '%s'\n",
buf_totext, text_ok->text_out);
}
assert_string_equal(buf_totext, text_ok->text_out);
/*
......@@ -250,6 +275,102 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
check_struct_conversions(&rdata, structsize);
}
/*
* Test whether converting rdata to text form and then parsing the result of
* that conversion again results in the same uncompressed wire form. This
* checks whether totext_*() output is parsable by fromtext_*() for given RR
* class and type.
*
* This function is called for every input RDATA which is successfully parsed
* by check_wire_ok_single() and whose type is not a meta-type.
*/
static void
check_text_conversions(dns_rdata_t *rdata) {
char buf_totext[1024] = { 0 };
unsigned char buf_fromtext[1024];
isc_result_t result;
isc_buffer_t target;
dns_rdata_t rdata2 = DNS_RDATA_INIT;
/*
* Convert uncompressed wire form RDATA into text form. This
* conversion must succeed since input RDATA was successfully
* parsed by check_wire_ok_single().
*/
isc_buffer_init(&target, buf_totext, sizeof(buf_totext));
result = dns_rdata_totext(rdata, NULL, &target);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Ensure buf_totext is properly NUL terminated as dns_rdata_totext()
* may attempt different output formats writing into the apparently
* unused part of the buffer.
*/
isc_buffer_putuint8(&target, 0);
if (debug) {
fprintf(stdout, "#'%s'\n", buf_totext);
}
/*
* Try parsing text form RDATA output by dns_rdata_totext() again.
*/
result = dns_test_rdatafromstring(&rdata2, rdata->rdclass, rdata->type,
buf_fromtext, sizeof(buf_fromtext),
buf_totext, false);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(rdata2.length, rdata->length);
assert_memory_equal(buf_fromtext, rdata->data, rdata->length);
}
/*
* Test whether converting rdata to multi-line text form and then parsing the
* result of that conversion again results in the same uncompressed wire form.
* This checks whether multi-line totext_*() output is parsable by fromtext_*()
* for given RR class and type.
*
* This function is called for every input RDATA which is successfully parsed
* by check_wire_ok_single() and whose type is not a meta-type.
*/
static void
check_multiline_text_conversions(dns_rdata_t *rdata) {
char buf_totext[1024] = { 0 };
unsigned char buf_fromtext[1024];
isc_result_t result;
isc_buffer_t target;
dns_rdata_t rdata2 = DNS_RDATA_INIT;
unsigned int flags;
/*
* Convert uncompressed wire form RDATA into multi-line text form.
* This conversion must succeed since input RDATA was successfully
* parsed by check_wire_ok_single().
*/
isc_buffer_init(&target, buf_totext, sizeof(buf_totext));
flags = dns_master_styleflags(&dns_master_style_default);
result = dns_rdata_tofmttext(rdata, dns_rootname, flags, 80 - 32, 4,
"\n", &target);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Ensure buf_totext is properly NUL terminated as
* dns_rdata_tofmttext() may attempt different output formats
* writing into the apparently unused part of the buffer.
*/
isc_buffer_putuint8(&target, 0);
if (debug) {
fprintf(stdout, "#'%s'\n", buf_totext);
}
/*
* Try parsing multi-line text form RDATA output by
* dns_rdata_tofmttext() again.
*/
result = dns_test_rdatafromstring(&rdata2, rdata->rdclass, rdata->type,
buf_fromtext, sizeof(buf_fromtext),
buf_totext, false);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(rdata2.length, rdata->length);
assert_memory_equal(buf_fromtext, rdata->data, rdata->length);
}
/*
* Test whether supplied wire form RDATA is properly handled as being either
* valid or invalid for an RR of given rdclass and type.
......@@ -278,9 +399,19 @@ check_wire_ok_single(const wire_ok_t *wire_ok, dns_rdataclass_t rdclass,
/*
* If data was parsed correctly, perform two-way conversion checks
* between uncompressed wire form and type-specific struct.
*
* If the RR type is not a meta-type, additionally perform two-way
* conversion checks between:
*
* - uncompressed wire form and text form,
* - uncompressed wire form and multi-line text form.
*/
if (result == ISC_R_SUCCESS) {
check_struct_conversions(&rdata, structsize);
if (!dns_rdatatype_ismeta(rdata.type)) {
check_text_conversions(&rdata);
check_multiline_text_conversions(&rdata);
}
}
}
......@@ -1528,11 +1659,8 @@ eid(void **state) {
TEXT_SENTINEL()
};
wire_ok_t wire_ok[] = {
/*
* Too short.
*/
WIRE_INVALID(),
WIRE_VALID(0x00),
WIRE_VALID(0xAA, 0xBB, 0xCC),
/*
* Sentinel.
*/
......@@ -1721,11 +1849,8 @@ nimloc(void **state) {
TEXT_SENTINEL()
};
wire_ok_t wire_ok[] = {
/*
* Too short.
*/
WIRE_INVALID(),
WIRE_VALID(0x00),
WIRE_VALID(0xAA, 0xBB, 0xCC),
/*
* Sentinel.
*/
......@@ -1817,7 +1942,7 @@ nsec(void **state) {
WIRE_INVALID(0x00, 0x00),
WIRE_INVALID(0x00, 0x00, 0x00),
WIRE_VALID(0x00, 0x00, 0x01, 0x02),
WIRE_INVALID()
WIRE_SENTINEL()
};
UNUSED(state);
......@@ -1838,8 +1963,8 @@ nsec3(void **state) {
TEXT_INVALID("."),
TEXT_INVALID(". RRSIG"),
TEXT_INVALID("1 0 10 76931F"),
TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONG;UED541AS"),
TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONG;UED541AS A RRSIG"),
TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONG&UED541AS"),
TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONGAUED541AS A RRSIG BADTYPE"),
TEXT_VALID("1 0 10 76931F AJHVGTICN6K0VDA53GCHFMT219SRRQLM A RRSIG"),
TEXT_VALID("1 0 10 76931F AJHVGTICN6K0VDA53GCHFMT219SRRQLM"),
TEXT_VALID("1 0 10 - AJHVGTICN6K0VDA53GCHFMT219SRRQLM"),
......@@ -2233,7 +2358,7 @@ iszonecutauth(void **state) {
}
int
main(void) {
main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(amtrelay, _setup, _teardown),
cmocka_unit_test_setup_teardown(apl, _setup, _teardown),
......@@ -2261,6 +2386,12 @@ main(void) {
cmocka_unit_test_setup_teardown(iszonecutauth, NULL, NULL),
};
UNUSED(argv);
if (argc > 1) {
debug = true;
}
return (cmocka_run_group_tests(tests, NULL, NULL));
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment