fuzz TEST add regression testing for lyd_parse_mem JSON
This separates lyd_parse_mem into two harnesses and fuzz regress tests,
one for XML and one for JSON. The crashing corpus is separated into
the appropriate directories as well, with previous issues encountered in
the JSON parser added.
diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt
index f4df572..3e53cc7 100644
--- a/tests/fuzz/CMakeLists.txt
+++ b/tests/fuzz/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.8.12)
if (ENABLE_FUZZ_TARGETS)
- set(fuzz_targets lys_parse_mem lyd_parse_mem buf_add_char yang_parse_module)
+ set(fuzz_targets lys_parse_mem lyd_parse_mem_xml lyd_parse_mem_json buf_add_char yang_parse_module)
if(FUZZER STREQUAL "AFL")
foreach(target_name IN LISTS fuzz_targets)
@@ -20,7 +20,7 @@
if (ENABLE_BUILD_TESTS)
add_executable(fuzz_regression_test fuzz_regression_test.c)
- set(fuzz_regression_tests lys_parse_mem lyd_parse_mem)
+ set(fuzz_regression_tests lys_parse_mem lyd_parse_mem_xml lyd_parse_mem_json)
foreach(target_name IN LISTS fuzz_regression_tests)
file(COPY ${CMAKE_SOURCE_DIR}/tests/fuzz/corpus/${target_name} DESTINATION ${CMAKE_BINARY_DIR}/tests/fuzz/)
add_executable(regress_fuzz_${target_name} ${target_name}.c main.c $<TARGET_OBJECTS:yangobj>)
diff --git a/tests/fuzz/corpus/lyd_parse_mem_json/pull1203 b/tests/fuzz/corpus/lyd_parse_mem_json/pull1203
new file mode 100644
index 0000000..b732c50
--- /dev/null
+++ b/tests/fuzz/corpus/lyd_parse_mem_json/pull1203
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/fuzz/corpus/lyd_parse_mem/issue1074 b/tests/fuzz/corpus/lyd_parse_mem_xml/issue1074
similarity index 100%
rename from tests/fuzz/corpus/lyd_parse_mem/issue1074
rename to tests/fuzz/corpus/lyd_parse_mem_xml/issue1074
diff --git a/tests/fuzz/corpus/lyd_parse_mem/issue1131 b/tests/fuzz/corpus/lyd_parse_mem_xml/issue1131
similarity index 100%
rename from tests/fuzz/corpus/lyd_parse_mem/issue1131
rename to tests/fuzz/corpus/lyd_parse_mem_xml/issue1131
Binary files differ
diff --git a/tests/fuzz/corpus/lyd_parse_mem/issue1132 b/tests/fuzz/corpus/lyd_parse_mem_xml/issue1132
similarity index 100%
rename from tests/fuzz/corpus/lyd_parse_mem/issue1132
rename to tests/fuzz/corpus/lyd_parse_mem_xml/issue1132
diff --git a/tests/fuzz/corpus/lyd_parse_mem/issue1132_2 b/tests/fuzz/corpus/lyd_parse_mem_xml/issue1132_2
similarity index 100%
rename from tests/fuzz/corpus/lyd_parse_mem/issue1132_2
rename to tests/fuzz/corpus/lyd_parse_mem_xml/issue1132_2
diff --git a/tests/fuzz/corpus/lyd_parse_mem/issue1132_3 b/tests/fuzz/corpus/lyd_parse_mem_xml/issue1132_3
similarity index 100%
rename from tests/fuzz/corpus/lyd_parse_mem/issue1132_3
rename to tests/fuzz/corpus/lyd_parse_mem_xml/issue1132_3
diff --git a/tests/fuzz/corpus/lyd_parse_mem/pull1129_1 b/tests/fuzz/corpus/lyd_parse_mem_xml/pull1129_1
similarity index 100%
rename from tests/fuzz/corpus/lyd_parse_mem/pull1129_1
rename to tests/fuzz/corpus/lyd_parse_mem_xml/pull1129_1
Binary files differ
diff --git a/tests/fuzz/corpus/lyd_parse_mem/pull1129_2 b/tests/fuzz/corpus/lyd_parse_mem_xml/pull1129_2
similarity index 100%
rename from tests/fuzz/corpus/lyd_parse_mem/pull1129_2
rename to tests/fuzz/corpus/lyd_parse_mem_xml/pull1129_2
diff --git a/tests/fuzz/lyd_parse_mem_json.c b/tests/fuzz/lyd_parse_mem_json.c
new file mode 100644
index 0000000..cd4be88
--- /dev/null
+++ b/tests/fuzz/lyd_parse_mem_json.c
@@ -0,0 +1,83 @@
+#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;
+ struct lyd_node *tree = 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, NULL);
+ lys_parse_mem(ctx, schema_b, LYS_IN_YANG, NULL);
+
+ data = malloc(len + 1);
+ if (data == NULL) {
+ return 0;
+ }
+ memcpy(data, buf, len);
+ data[len] = 0;
+
+ lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree);
+ ly_ctx_destroy(ctx, NULL);
+
+ free(data);
+
+ return 0;
+}
diff --git a/tests/fuzz/lyd_parse_mem.c b/tests/fuzz/lyd_parse_mem_xml.c
similarity index 100%
rename from tests/fuzz/lyd_parse_mem.c
rename to tests/fuzz/lyd_parse_mem_xml.c