1/*	$NetBSD: dns_rdata_fromtext.c,v 1.2 2024/02/21 22:51:58 christos Exp $	*/
2
3/*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16#include <stdbool.h>
17#include <stdlib.h>
18
19#include <isc/attributes.h>
20#include <isc/buffer.h>
21#include <isc/commandline.h>
22#include <isc/lex.h>
23#include <isc/mem.h>
24#include <isc/print.h>
25#include <isc/string.h>
26#include <isc/util.h>
27
28#include <dns/fixedname.h>
29#include <dns/name.h>
30#include <dns/rdata.h>
31#include <dns/rdataclass.h>
32#include <dns/rdatatype.h>
33#include <dns/result.h>
34
35#include "fuzz.h"
36
37bool debug = false;
38
39int
40LLVMFuzzerInitialize(int *argc, char ***argv) {
41	UNUSED(argc);
42	UNUSED(argv);
43	return (0);
44}
45
46/* following code was copied from named-rrchecker */
47isc_lexspecials_t specials = { ['('] = 1, [')'] = 1, ['"'] = 1 };
48
49int
50LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
51	isc_mem_t *mctx = NULL;
52	isc_mem_create(&mctx);
53
54	isc_lex_t *lex = NULL;
55	isc_token_t token;
56
57	isc_result_t result;
58	unsigned int options = 0;
59	dns_rdatatype_t rdtype;
60	dns_rdataclass_t rdclass;
61
62	char wiredata[64 * 1024];
63	isc_buffer_t wirebuf;
64	isc_buffer_init(&wirebuf, wiredata, sizeof(wiredata));
65
66	dns_rdata_t rdata = DNS_RDATA_INIT;
67	dns_name_t *name = NULL;
68
69	isc_buffer_t inbuf;
70	isc_buffer_constinit(&inbuf, data, size);
71	isc_buffer_add(&inbuf, size);
72	isc_buffer_setactive(&inbuf, size);
73
74	RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS);
75
76	/*
77	 * Set up to lex DNS master file.
78	 */
79	isc_lex_setspecials(lex, specials);
80	options = ISC_LEXOPT_EOL;
81	isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
82
83	RUNTIME_CHECK(isc_lex_openbuffer(lex, &inbuf) == ISC_R_SUCCESS);
84
85	result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token);
86	if (result != ISC_R_SUCCESS) {
87		goto cleanup;
88	}
89	if (token.type == isc_tokentype_eof) {
90		goto cleanup;
91	}
92	if (token.type == isc_tokentype_eol) {
93		goto cleanup;
94	}
95	/*
96	 * Get class.
97	 */
98	if (token.type == isc_tokentype_number) {
99		if (token.value.as_ulong > 0xffff) {
100			goto cleanup;
101		}
102		rdclass = (dns_rdataclass_t)token.value.as_ulong;
103	} else if (token.type == isc_tokentype_string) {
104		result = dns_rdataclass_fromtext(&rdclass,
105						 &token.value.as_textregion);
106		if (result != ISC_R_SUCCESS) {
107			goto cleanup;
108		}
109	} else {
110		goto cleanup;
111	}
112	result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token);
113	if (result != ISC_R_SUCCESS) {
114		goto cleanup;
115	}
116	if (token.type == isc_tokentype_eol) {
117		goto cleanup;
118	}
119	if (token.type == isc_tokentype_eof) {
120		goto cleanup;
121	}
122
123	/*
124	 * Get type.
125	 */
126	if (token.type == isc_tokentype_number) {
127		if (token.value.as_ulong > 0xffff) {
128			goto cleanup;
129		}
130		rdtype = (dns_rdatatype_t)token.value.as_ulong;
131	} else if (token.type == isc_tokentype_string) {
132		result = dns_rdatatype_fromtext(&rdtype,
133						&token.value.as_textregion);
134		if (result != ISC_R_SUCCESS) {
135			goto cleanup;
136		}
137	} else {
138		goto cleanup;
139	}
140
141	result = dns_rdata_fromtext(&rdata, rdclass, rdtype, lex, name, 0, mctx,
142				    &wirebuf, NULL);
143	if (debug) {
144		fprintf(stderr, "dns_rdata_fromtext: %s\n",
145			isc_result_totext(result));
146	}
147
148cleanup:
149	isc_lex_close(lex);
150	isc_lex_destroy(&lex);
151	isc_mem_destroy(&mctx);
152	return (0);
153}
154