Explorar o código

JSON: Add encoding/decoding fuzzing

Lukas M %!s(int64=5) %!d(string=hai) anos
pai
achega
887ebf842c

+ 5 - 0
tests/fuzz/CMakeLists.txt

@@ -92,6 +92,11 @@ add_fuzzer(fuzz_binary_message fuzz_binary_message.cc)
 add_fuzzer(fuzz_binary_decode fuzz_binary_decode.cc)
 add_fuzzer(fuzz_src_ua_util fuzz_src_ua_util.cc)
 
+if(UA_ENABLE_JSON_ENCODING)
+    add_fuzzer(fuzz_json_decode fuzz_json_decode.cc)
+    add_fuzzer(fuzz_json_decode_encode fuzz_json_decode_encode.cc)
+endif()
+
 file(GLOB CORPUS_FILES ${PROJECT_SOURCE_DIR}/tests/fuzz/fuzz_binary_message_corpus/generated/*)
 
 SET(CORPUS_CMDS "")

+ 65 - 0
tests/fuzz/fuzz_json/json_corpus

@@ -0,0 +1,65 @@
+{"Locale":"t1","Text":"t2"}
+{"Id":42}
+{"Type":1,"Body":false}
+{"Value":{"Type":1,"Body":true}}
+{"Type":1, "Body":false, "Type":1}
+{"Type":1,"Body":[null, null, null]}
+{"Type":12,"Body":["1","2","3","4","5","6","7","8"]}
+{"Type":12,"Body":["1","2","3","4","5","6","7","8"],"Dimension":[2,4]}
+{"Encoding":2,"TypeId":{"Id":42},"Body":"<Element></Element>"}
+{"Encoding":1,"TypeId":{"Id":42},"Body":"YXNkZmFzZGY="}
+{"TypeId":{"Id":1},"Body":true}
+{"Type":23,"Body":null}
+{"Value":{"Type":1,"Body":true}}
+{"Value":{"Type":1,"Body":true},"Status":2153250816,"SourceTimestamp":"1970-01-15T06:56:07Z","SourcePicoseconds":0,"ServerTimestamp":"1970-01-15T06:56:07Z","ServerPicoseconds":0}
+{"Type":25,"Body":null}
+{"SymbolicId":13,""LocalizedText":14,""Locale":12,"AdditionalInfo":"additionalInfo",""InnerStatusCode":2155216896,""InnerDiagnosticInfo":{"AdditionalInfo":"INNER ADDITION INFO"}}
+{"IdType":3,"Id":"YXNkZmFzZGY=","Namespace":"test","ServerUri":13}
+{"IdType":1,"Id":"test","Namespace":"test","ServerUri":13}
+{"IdType":1,"Id":"test","Namespace":42}
+{"IdType":1,"Id":"test","Namespace":"abcdef"}
+{"IdType":1,"Id":"test"}
+{"Id":42}
+{"IdType":3,"Id":"YXNkZmFzZGY="}
+{"IdType":2,"Id":"00000001-0002-0003-0405-060708090A0B"}
+{"IdType":1,"Id":"test123"}
+{"Id":42,"Namespace":123}
+{"Id":42}
+{"Timestamp":"1970-01-15T06:56:07Z","ViewVersion":1236,"ViewId":{"Id":"00000009-0002-027C-F3BF-BB7BEEFEEFBE","IdType":2}}
+{"Type":21,"Body":null}
+{"Locale":"t1"}
+{"Locale":"t1","Text":"t2"}
+{"Type":20,"Body":null}
+{"Name":"derName","Uri":1}
+1970-01-02T01:02:03.042Z
+1970-01-02T01:02:03.005Z
+{"Type":19,"Body":0}
+{"Type":19,"Body":2}
+{"Type":14,"Body":"00000=01-0002-0003-0405-060708090A0B"}
+{"Type":14,"Body":"00000001-0002-0003-0405-060708090A0B00000001"}
+{"Type":14,"Body":"00000001-00"}
+{"Type":14,"Body":"00000001-0002-0003-0405-060708090A0B"}
+{"Type":15,"Body":null}
+{"Type":15,"Body":"YXNkZmFzZGY="}
+{"Type":12,"Body":"\\u002c"}
+{"Type":12,"Body":"ab\\tcdef"}
+{"Type":12,"Body":"abcdef"}
+{"Type":11,"Body":nan}
+{"Type":11,"Body":1.0000000000000002}
+{"Type":11,"Body":1}
+{"Type":11,"Body":1.1234}
+{"Type":10,"Body":1}
+{"Type":10,"Body":3.1415927410}
+{"Type":8,"Body":9223372036854775807}
+{"Type":8,"Body":-9223372036854775808}
+{"Type":6,"Body":2147483647}
+{"Type":6,"Body":-2147483648}
+{"Type":4,"Body":32767}
+{"Type":4,"Body":-32768}
+{"Type":2,"Body":127}
+{"Type":2,"Body":-128}
+{"Type":9,"Body":18446744073709551615}
+{"Type":9,"Body":0}
+{"Type":7,"Body":4294967295}
+{"Type":7,"Body":0}
+{"Type":5,"Body":65535}

+ 30 - 0
tests/fuzz/fuzz_json_decode.cc

@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *    Copyright 2018 (c) Fraunhofer IOSB (Author: Lukas Meling)
+ */
+
+#include <ua_types.h>
+#include <ua_types_generated_handling.h>
+#include "ua_types_encoding_json.h"
+
+/*
+** Main entry point.  The fuzzer invokes this function with each
+** fuzzed input.
+*/
+extern "C" int
+LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+    UA_ByteString buf;
+    buf.data = (UA_Byte*)data;
+    buf.length = size;
+
+    UA_Variant out;
+    UA_Variant_init(&out);
+
+    UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
+    if(retval == UA_STATUSCODE_GOOD)
+        UA_Variant_deleteMembers(&out);
+
+    return 0;
+}

+ 73 - 0
tests/fuzz/fuzz_json_decode_encode.cc

@@ -0,0 +1,73 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *    Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
+ */
+
+#include <ua_types.h>
+#include <ua_types_generated_handling.h>
+#include "ua_types_encoding_json.h"
+
+/* Decode a message, then encode, decode, encode.
+ * The two encodings must be bit-equal. */
+extern "C" int
+LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+    UA_ByteString buf;
+    buf.data = (UA_Byte*)data;
+    buf.length = size;
+
+    UA_Variant value;
+    UA_Variant_init(&value);
+
+    UA_StatusCode retval = UA_decodeJson(&buf, &value, &UA_TYPES[UA_TYPES_VARIANT]);
+    if(retval != UA_STATUSCODE_GOOD)
+        return 0;
+
+    size_t jsonSize = UA_calcSizeJson(&value, &UA_TYPES[UA_TYPES_VARIANT],
+                                      NULL, 0, NULL, 0, true);
+
+    UA_ByteString buf2 = UA_BYTESTRING_NULL;
+    retval = UA_ByteString_allocBuffer(&buf2, jsonSize);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_Variant_deleteMembers(&value);
+        return 0;
+    }
+
+    uint8_t *bufPos = buf2.data;
+    const uint8_t *bufEnd = &buf2.data[buf2.length];
+    retval = UA_encodeJson(&value, &UA_TYPES[UA_TYPES_VARIANT],
+                           &bufPos, &bufEnd, NULL, 0, NULL, 0, true);
+    assert(retval == UA_STATUSCODE_GOOD);
+    assert(bufPos == bufEnd);
+
+    UA_Variant value2;
+    UA_Variant_init(&value2);
+
+    retval = UA_decodeJson(&buf2, &value2, &UA_TYPES[UA_TYPES_VARIANT]);
+    assert(retval == UA_STATUSCODE_GOOD);
+
+    UA_ByteString buf3 = UA_BYTESTRING_NULL;
+    retval = UA_ByteString_allocBuffer(&buf3, jsonSize);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_Variant_deleteMembers(&value);
+        UA_Variant_deleteMembers(&value2);
+        UA_ByteString_deleteMembers(&buf2);
+        return 0;
+    }
+
+    bufPos = buf3.data;
+    bufEnd = &buf3.data[buf3.length];
+    retval = UA_encodeJson(&value2, &UA_TYPES[UA_TYPES_VARIANT],
+                           &bufPos, &bufEnd, NULL, 0, NULL, 0, true);
+    assert(retval == UA_STATUSCODE_GOOD);
+    assert(bufPos == bufEnd);
+    assert(memcmp(buf2.data, buf3.data, buf.length) == 0);
+
+    UA_Variant_deleteMembers(&value);
+    UA_Variant_deleteMembers(&value2);
+    UA_ByteString_deleteMembers(&buf2);
+    UA_ByteString_deleteMembers(&buf3);
+
+    return 0;
+}