// SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright OpenBMC Authors #include #include #include #include #include #include // Test vectors: input bytes and expected hex strings static const UINT8 test_bytes_1[] = { 0x00 }; static const char *test_hex_1 = "00"; static const UINT8 test_bytes_2[] = { 0xff }; static const char *test_hex_2 = "ff"; static const UINT8 test_bytes_3[] = { 0xde, 0xad, 0xbe, 0xef }; static const char *test_hex_3 = "deadbeef"; static const UINT8 test_bytes_4[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; static const char *test_hex_4 = "0123456789abcdef"; static const UINT8 test_bytes_5[] = { 0x00, 0x00, 0x00, 0x00 }; static const char *test_hex_5 = "00000000"; // Test encoding: bytes -> hex string void test_hex_encode_good(void) { printf("Testing hex encoding...\n"); // Test 1: Single zero byte { json_object *obj = json_object_new_object(); add_bytes_hex(obj, "data", test_bytes_1, sizeof(test_bytes_1)); json_object *field = json_object_object_get(obj, "data"); assert(field != NULL); const char *hex = json_object_get_string(field); assert(strcmp(hex, test_hex_1) == 0); json_object_put(obj); } // Test 2: Single 0xFF byte { json_object *obj = json_object_new_object(); add_bytes_hex(obj, "data", test_bytes_2, sizeof(test_bytes_2)); json_object *field = json_object_object_get(obj, "data"); assert(field != NULL); const char *hex = json_object_get_string(field); assert(strcmp(hex, test_hex_2) == 0); json_object_put(obj); } // Test 3: "deadbeef" { json_object *obj = json_object_new_object(); add_bytes_hex(obj, "data", test_bytes_3, sizeof(test_bytes_3)); json_object *field = json_object_object_get(obj, "data"); assert(field != NULL); const char *hex = json_object_get_string(field); assert(strcmp(hex, test_hex_3) == 0); json_object_put(obj); } // Test 4: Full range 0-9, a-f { json_object *obj = json_object_new_object(); add_bytes_hex(obj, "data", test_bytes_4, sizeof(test_bytes_4)); json_object *field = json_object_object_get(obj, "data"); assert(field != NULL); const char *hex = json_object_get_string(field); assert(strcmp(hex, test_hex_4) == 0); json_object_put(obj); } // Test 5: All zeros { json_object *obj = json_object_new_object(); add_bytes_hex(obj, "data", test_bytes_5, sizeof(test_bytes_5)); json_object *field = json_object_object_get(obj, "data"); assert(field != NULL); const char *hex = json_object_get_string(field); assert(strcmp(hex, test_hex_5) == 0); json_object_put(obj); } printf("Hex encoding tests passed.\n"); } // Test decoding: hex string -> bytes void test_hex_decode_good(void) { printf("Testing hex decoding...\n"); // Test 1: Single zero byte { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string(test_hex_1)); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes != NULL); assert(out_len == sizeof(test_bytes_1)); assert(memcmp(bytes, test_bytes_1, out_len) == 0); free(bytes); json_object_put(obj); } // Test 2: Single 0xFF byte { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string(test_hex_2)); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes != NULL); assert(out_len == sizeof(test_bytes_2)); assert(memcmp(bytes, test_bytes_2, out_len) == 0); free(bytes); json_object_put(obj); } // Test 3: "deadbeef" { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string(test_hex_3)); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes != NULL); assert(out_len == sizeof(test_bytes_3)); assert(memcmp(bytes, test_bytes_3, out_len) == 0); free(bytes); json_object_put(obj); } // Test 4: Full range with uppercase hex { json_object *obj = json_object_new_object(); json_object_object_add( obj, "data", json_object_new_string("0123456789ABCDEF")); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes != NULL); assert(out_len == sizeof(test_bytes_4)); assert(memcmp(bytes, test_bytes_4, out_len) == 0); free(bytes); json_object_put(obj); } // Test 5: Mixed case hex { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string("DeAdBeEf")); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes != NULL); assert(out_len == sizeof(test_bytes_3)); assert(memcmp(bytes, test_bytes_3, out_len) == 0); free(bytes); json_object_put(obj); } printf("Hex decoding tests passed.\n"); } // Test error handling void test_hex_error_cases(void) { printf("Testing hex error handling...\n"); // Test encode with NULL object { add_bytes_hex(NULL, "data", test_bytes_1, sizeof(test_bytes_1)); // Should not crash } // Test encode with NULL bytes { json_object *obj = json_object_new_object(); add_bytes_hex(obj, "data", NULL, 4); json_object *field = json_object_object_get(obj, "data"); assert(field == NULL); // Should not add field json_object_put(obj); } // Test encode with zero length { json_object *obj = json_object_new_object(); add_bytes_hex(obj, "data", test_bytes_1, 0); json_object *field = json_object_object_get(obj, "data"); assert(field == NULL); // Should not add field json_object_put(obj); } // Test decode with NULL object { size_t out_len = 0; UINT8 *bytes = get_bytes_hex(NULL, "data", &out_len); assert(bytes == NULL); } // Test decode with NULL out_len { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string("deadbeef")); UINT8 *bytes = get_bytes_hex(obj, "data", NULL); assert(bytes == NULL); json_object_put(obj); } // Test decode with missing field { json_object *obj = json_object_new_object(); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "nonexistent", &out_len); assert(bytes == NULL); json_object_put(obj); } // Test decode with non-string field { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_int(12345)); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes == NULL); json_object_put(obj); } // Test decode with odd-length hex string { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string("abc")); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes == NULL); // Should fail - odd length json_object_put(obj); } // Test decode with invalid hex character { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string("deadbXef")); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); assert(bytes == NULL); // Should fail - 'X' is invalid json_object_put(obj); } // Test decode with empty string { json_object *obj = json_object_new_object(); json_object_object_add(obj, "data", json_object_new_string("")); size_t out_len = 0; UINT8 *bytes = get_bytes_hex(obj, "data", &out_len); // Empty string has even length (0), so it might succeed with 0 bytes // Or fail - depends on implementation. Current impl should return empty buf if (bytes != NULL) { assert(out_len == 0); free(bytes); } json_object_put(obj); } printf("Hex error handling tests passed.\n"); } // Test round-trip: bytes -> hex -> bytes void test_hex_roundtrip(void) { printf("Testing hex round-trip...\n"); // Test with various byte patterns UINT8 test_data[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; json_object *obj = json_object_new_object(); add_bytes_hex(obj, "roundtrip", test_data, sizeof(test_data)); size_t out_len = 0; UINT8 *decoded = get_bytes_hex(obj, "roundtrip", &out_len); assert(decoded != NULL); assert(out_len == sizeof(test_data)); assert(memcmp(decoded, test_data, out_len) == 0); free(decoded); json_object_put(obj); printf("Hex round-trip tests passed.\n"); }