fuzzing REFACTOR fuzz harneses (#1126)

Fix minor issues with implicit function declarations, terminate fuzzer
string inputs with string termination characters and add an XML parser
harness
diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt
index 1e8cf7b..cc38904 100644
--- a/tests/fuzz/CMakeLists.txt
+++ b/tests/fuzz/CMakeLists.txt
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 2.8.12)
 
-set(fuzz_targets lys_parse_mem buf_add_char yang_parse_module)
+set(fuzz_targets lys_parse_mem lyd_parse_mem buf_add_char yang_parse_module)
 
 if(FUZZER STREQUAL "AFL")
 	foreach(target_name IN LISTS fuzz_targets)
diff --git a/tests/fuzz/lyd_parse_mem.c b/tests/fuzz/lyd_parse_mem.c
new file mode 100644
index 0000000..75cbc93
--- /dev/null
+++ b/tests/fuzz/lyd_parse_mem.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "libyang.h"
+
+int LLVMFuzzerTestOneInput(uint8_t const *buf, size_t len)
+{
+	struct ly_ctx *ctx = NULL;
+	static bool log = false;
+	const char *schema_a = "module defs {namespace urn:tests:defs;prefix d;yang-version 1.1;"
+		            "identity crypto-alg; identity interface-type; identity ethernet {base interface-type;} identity fast-ethernet {base ethernet;}}";
+    const char *schema_b = "module types {namespace urn:tests:types;prefix t;yang-version 1.1; import defs {prefix defs;}"
+            "feature f; identity gigabit-ethernet { base defs:ethernet;}"
+            "container cont {leaf leaftarget {type empty;}"
+                            "list listtarget {key id; max-elements 5;leaf id {type uint8;} leaf value {type string;}}"
+                            "leaf-list leaflisttarget {type uint8; max-elements 5;}}"
+            "list list {key id; leaf id {type string;} leaf value {type string;} leaf-list targets {type string;}}"
+            "list list2 {key \"id value\"; leaf id {type string;} leaf value {type string;}}"
+            "list list_inst {key id; leaf id {type instance-identifier {require-instance true;}} leaf value {type string;}}"
+            "list list_ident {key id; leaf id {type identityref {base defs:interface-type;}} leaf value {type string;}}"
+            "leaf-list leaflisttarget {type string;}"
+            "leaf binary {type binary {length 5 {error-message \"This base64 value must be of length 5.\";}}}"
+            "leaf binary-norestr {type binary;}"
+            "leaf int8 {type int8 {range 10..20;}}"
+            "leaf uint8 {type uint8 {range 150..200;}}"
+            "leaf int16 {type int16 {range -20..-10;}}"
+            "leaf uint16 {type uint16 {range 150..200;}}"
+            "leaf int32 {type int32;}"
+            "leaf uint32 {type uint32;}"
+            "leaf int64 {type int64;}"
+            "leaf uint64 {type uint64;}"
+            "leaf bits {type bits {bit zero; bit one {if-feature f;} bit two;}}"
+            "leaf enums {type enumeration {enum white; enum yellow {if-feature f;}}}"
+            "leaf dec64 {type decimal64 {fraction-digits 1; range 1.5..10;}}"
+            "leaf dec64-norestr {type decimal64 {fraction-digits 18;}}"
+            "leaf str {type string {length 8..10; pattern '[a-z ]*';}}"
+            "leaf str-norestr {type string;}"
+            "leaf str-utf8 {type string{length 2..5; pattern '€*';}}"
+            "leaf bool {type boolean;}"
+            "leaf empty {type empty;}"
+            "leaf ident {type identityref {base defs:interface-type;}}"
+ 	    "leaf inst {type instance-identifier {require-instance true;}}"
+            "leaf inst-noreq {type instance-identifier {require-instance false;}}"
+            "leaf lref {type leafref {path /leaflisttarget; require-instance true;}}"
+            "leaf lref2 {type leafref {path \"../list[id = current()/../str-norestr]/targets\"; require-instance true;}}"
+            "leaf un1 {type union {"
+            "type leafref {path /int8; require-instance true;}"
+            "type union { type identityref {base defs:interface-type;} type instance-identifier {require-instance true;} }"
+            "type string {length 1..20;}}}}";
+    	char *data = NULL;
+
+	LY_ERR err;
+
+	if (!log) {
+		ly_log_options(0);
+		log = true;
+	}
+
+	err = ly_ctx_new(NULL, 0, &ctx);
+	if (err != LY_SUCCESS) {
+		fprintf(stderr, "Failed to create context\n");
+		exit(EXIT_FAILURE);
+	}
+
+	lys_parse_mem(ctx, schema_a, LYS_IN_YANG);
+	lys_parse_mem(ctx, schema_b, LYS_IN_YANG);
+
+	data = malloc(len + 1);
+	if (data == NULL) {
+		return 0;
+	}
+	memcpy(data, buf, len);
+	data[len] = 0;
+
+	lyd_parse_mem(ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY);
+	ly_ctx_destroy(ctx, NULL);
+
+	free(data);
+
+	return 0;
+}
diff --git a/tests/fuzz/lys_parse_mem.c b/tests/fuzz/lys_parse_mem.c
index 6ab5e0b..516a6d9 100644
--- a/tests/fuzz/lys_parse_mem.c
+++ b/tests/fuzz/lys_parse_mem.c
@@ -8,6 +8,7 @@
 {
 	struct ly_ctx *ctx = NULL;
 	static bool log = false;
+	char *data = NULL;
 	LY_ERR err;
 
 	if (!log) {
@@ -21,7 +22,16 @@
 		exit(EXIT_FAILURE);
 	}
 
-	lys_parse_mem(ctx, buf, LYS_IN_YANG);
+	data = malloc(len + 1);
+	if (data == NULL) {
+		return 0;
+	}
+
+	memcpy(data, buf, len);
+	data[len] = 0;
+
+	lys_parse_mem(ctx, data, LYS_IN_YANG);
 	ly_ctx_destroy(ctx, NULL);
+	free(data);
 	return 0;
 }
diff --git a/tests/fuzz/main.c b/tests/fuzz/main.c
index 0d6c20f..2776dea 100644
--- a/tests/fuzz/main.c
+++ b/tests/fuzz/main.c
@@ -24,4 +24,18 @@
 	return 0;
 }
 
+#else
+int main(void) {
+	int ret;
+	uint8_t buf[64 * 1024];
+
+	ret = fread(buf, 1, sizeof(buf), stdin);
+	if (ret < 0) {
+		return 0;
+	}
+
+	LLVMFuzzerTestOneInput(buf, ret);
+
+	return 0;
+}
 #endif /* __AFL_COMPILER */
diff --git a/tests/fuzz/yang_parse_module.c b/tests/fuzz/yang_parse_module.c
index 4b464a7..595da62 100644
--- a/tests/fuzz/yang_parse_module.c
+++ b/tests/fuzz/yang_parse_module.c
@@ -5,10 +5,12 @@
 #include "../../src/common.h"
 #include "../../src/tree_schema_internal.h"
 
+LY_ERR yang_parse_module(struct lys_yang_parser_ctx **context, const char *data, struct lys_module *mod);
+
 int LLVMFuzzerTestOneInput(uint8_t const *buf, size_t len)
 {
 	struct lys_module *mod = NULL;
-	struct lys_parser_ctx *context = NULL;
+	struct lys_yang_parser_ctx *context = NULL;
 	uint8_t *data = NULL;
 	struct ly_ctx *ctx = NULL;
 	static bool log = false; 
@@ -30,8 +32,8 @@
 		fprintf(stderr, "Out of memory\n");
 		return 0;
 	}
-	data[len] = 0;
 	memcpy(data, buf, len);
+	data[len] = 0;
 
 	mod = calloc(1, sizeof *mod);
 	if (mod == NULL) {