From c7b479706d4b8bfc5165ca062f24e6db5b90017e Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Mon, 3 Feb 2025 15:51:20 +0200 Subject: [PATCH 1/7] Add: gvm_json_obj_int --- openvasd/openvasd.c | 7 +------ util/json.c | 20 ++++++++++++++++++++ util/json.h | 3 +++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/openvasd/openvasd.c b/openvasd/openvasd.c index f19aba4d..68521881 100644 --- a/openvasd/openvasd.c +++ b/openvasd/openvasd.c @@ -1094,7 +1094,6 @@ parse_results (const gchar *body, GSList **results) cJSON *result_obj = NULL; const gchar *err = NULL; openvasd_result_t result = NULL; - int port = 0; gchar *detail_name = NULL; gchar *detail_value = NULL; gchar *detail_source_type = NULL; @@ -1120,10 +1119,6 @@ parse_results (const gchar *body, GSList **results) // error goto res_cleanup; - if ((item = cJSON_GetObjectItem (result_obj, "port")) != NULL - && cJSON_IsNumber (item)) - port = item->valueint; - if ((item = cJSON_GetObjectItem (result_obj, "detail")) != NULL && cJSON_IsObject (item)) { @@ -1162,7 +1157,7 @@ parse_results (const gchar *body, GSList **results) gvm_json_obj_str (result_obj, "ip_address"), gvm_json_obj_str (result_obj, "hostname"), gvm_json_obj_str (result_obj, "oid"), - port, + gvm_json_obj_int (result_obj, "port"), gvm_json_obj_str (result_obj, "protocol"), gvm_json_obj_str (result_obj, "message"), detail_name, detail_value, diff --git a/util/json.c b/util/json.c index 4a154955..be940c5a 100644 --- a/util/json.c +++ b/util/json.c @@ -83,6 +83,26 @@ gvm_json_obj_double (cJSON *obj, const gchar *key) return 0; } +/** + * @brief Get an int field from a JSON object. + * + * @param[in] obj Object + * @param[in] key Field name. + * + * @return An int. + */ +int +gvm_json_obj_int (cJSON *obj, const gchar *key) +{ + cJSON *item; + + item = cJSON_GetObjectItem (obj, key); + if (item && cJSON_IsNumber (item)) + return item->valueint; + + return 0; +} + /** * @brief Get a string field from a JSON object. * diff --git a/util/json.h b/util/json.h index 9e5c61ad..0bfec1fd 100644 --- a/util/json.h +++ b/util/json.h @@ -17,6 +17,9 @@ gvm_json_string_escape (const char *, gboolean); double gvm_json_obj_double (cJSON *, const gchar *); +int +gvm_json_obj_int (cJSON *, const gchar *); + gchar * gvm_json_obj_str (cJSON *, const gchar *); From 4752c1f6e0947fcc9ff25e2a725711346479bbe3 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Mon, 3 Feb 2025 15:51:32 +0200 Subject: [PATCH 2/7] Add: tests of gvm_json_obj_int --- util/json_tests.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/util/json_tests.c b/util/json_tests.c index f590dacb..4871e0c2 100644 --- a/util/json_tests.c +++ b/util/json_tests.c @@ -88,6 +88,44 @@ Ensure (json, gvm_json_obj_str_null_when_missing) cJSON_Delete (json); } +/* gvm_json_obj_int */ + +Ensure (json, gvm_json_obj_int_gets_value) +{ + cJSON *json; + int i; + + json = cJSON_Parse ("{ \"eg\": 33 }"); + assert_that (json, is_not_null); + i = gvm_json_obj_int (json, "eg"); + assert_that (i, is_equal_to (33)); + cJSON_Delete (json); +} + +Ensure (json, gvm_json_obj_int_0_when_missing) +{ + cJSON *json; + int i; + + json = cJSON_Parse ("{ \"eg\": 33 }"); + assert_that (json, is_not_null); + i = gvm_json_obj_int (json, "err"); + assert_that (i, is_equal_to (0)); + cJSON_Delete (json); +} + +Ensure (json, gvm_json_obj_int_0_when_str) +{ + cJSON *json; + int i; + + json = cJSON_Parse ("{ \"eg\": \"abc\" }"); + assert_that (json, is_not_null); + i = gvm_json_obj_int (json, "eg"); + assert_that (i, is_equal_to (0)); + cJSON_Delete (json); +} + int main (int argc, char **argv) { @@ -103,6 +141,10 @@ main (int argc, char **argv) add_test_with_context (suite, json, gvm_json_obj_str_gets_value); add_test_with_context (suite, json, gvm_json_obj_str_null_when_missing); + add_test_with_context (suite, json, gvm_json_obj_int_gets_value); + add_test_with_context (suite, json, gvm_json_obj_int_0_when_missing); + add_test_with_context (suite, json, gvm_json_obj_int_0_when_str); + if (argc > 1) return run_single_test (suite, argv[1], create_text_reporter ()); return run_test_suite (suite, create_text_reporter ()); From 4f82c401d3a7b5d89014049b6b91e114ba294e6d Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 4 Feb 2025 16:58:54 +0200 Subject: [PATCH 3/7] Add: gvm_json_obj_check_int There are only two cases that use this variant but there will be a similar function for strings which will have more cases. --- openvasd/openvasd.c | 8 ++++---- openvasd/vtparser.c | 4 +--- util/json.c | 23 +++++++++++++++++++++++ util/json.h | 3 +++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/openvasd/openvasd.c b/openvasd/openvasd.c index 68521881..7870fa75 100644 --- a/openvasd/openvasd.c +++ b/openvasd/openvasd.c @@ -1257,12 +1257,12 @@ openvasd_get_scan_status (openvasd_connector_t conn) static int get_member_value_or_fail (cJSON *reader, const gchar *member) { - cJSON *item = NULL; - if ((item = cJSON_GetObjectItem (reader, member)) == NULL - && cJSON_IsNumber (item)) + int ret; + + if (gvm_json_obj_check_int (reader, member, &ret)) return -1; - return item->valueint; + return ret; } static int diff --git a/openvasd/vtparser.c b/openvasd/vtparser.c index 53e5f29f..824250ee 100644 --- a/openvasd/vtparser.c +++ b/openvasd/vtparser.c @@ -246,13 +246,11 @@ add_preferences_to_nvt (nvti_t *nvt, cJSON *vt_obj) } class = prefs_item->valuestring; - if ((prefs_item = cJSON_GetObjectItem (prefs_obj, "id")) == NULL - || !cJSON_IsNumber (prefs_item)) + if (gvm_json_obj_check_int (prefs_obj, "id", &id)) { g_warning ("%s: PREF missing id attribute", __func__); continue; } - id = prefs_item->valueint; if ((prefs_item = cJSON_GetObjectItem (prefs_obj, "name")) == NULL || !cJSON_IsString (prefs_item)) diff --git a/util/json.c b/util/json.c index be940c5a..cf04ee63 100644 --- a/util/json.c +++ b/util/json.c @@ -83,6 +83,29 @@ gvm_json_obj_double (cJSON *obj, const gchar *key) return 0; } +/** + * @brief Get an int field from a JSON object. + * + * @param[in] obj Object + * @param[in] key Field name. + * @param[out] val Return location for int if int exists. + * + * @return 0 if such an int field exists, else 1. + */ +int +gvm_json_obj_check_int (cJSON *obj, const gchar *key, int *val) +{ + cJSON *item; + + item = cJSON_GetObjectItem (obj, key); + if (item && cJSON_IsNumber (item)) { + if (val) + *val = item->valueint; + return 0; + } + return 1; +} + /** * @brief Get an int field from a JSON object. * diff --git a/util/json.h b/util/json.h index 0bfec1fd..cc017f55 100644 --- a/util/json.h +++ b/util/json.h @@ -17,6 +17,9 @@ gvm_json_string_escape (const char *, gboolean); double gvm_json_obj_double (cJSON *, const gchar *); +int +gvm_json_obj_check_int (cJSON *, const gchar *, int *); + int gvm_json_obj_int (cJSON *, const gchar *); From e838d90329f2cde4e1177f8edc3d9d6c2a2e8bdc Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Wed, 5 Feb 2025 19:31:13 +0200 Subject: [PATCH 4/7] Format --- util/json.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/util/json.c b/util/json.c index cf04ee63..80160a54 100644 --- a/util/json.c +++ b/util/json.c @@ -98,11 +98,12 @@ gvm_json_obj_check_int (cJSON *obj, const gchar *key, int *val) cJSON *item; item = cJSON_GetObjectItem (obj, key); - if (item && cJSON_IsNumber (item)) { - if (val) - *val = item->valueint; - return 0; - } + if (item && cJSON_IsNumber (item)) + { + if (val) + *val = item->valueint; + return 0; + } return 1; } From ff93d5dedef86ede7b69dbf01f2cb49b150bbd13 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Wed, 5 Feb 2025 21:11:26 +0200 Subject: [PATCH 5/7] Add: tests of gvm_json_obj_check_int --- util/json_tests.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/util/json_tests.c b/util/json_tests.c index 4871e0c2..f6328755 100644 --- a/util/json_tests.c +++ b/util/json_tests.c @@ -126,6 +126,50 @@ Ensure (json, gvm_json_obj_int_0_when_str) cJSON_Delete (json); } +/* gvm_json_obj_check_int */ + +Ensure (json, gvm_json_obj_check_int_0_when_has) +{ + cJSON *json; + + json = cJSON_Parse ("{ \"eg\": 33 }"); + assert_that (json, is_not_null); + assert_that (gvm_json_obj_check_int (json, "eg", NULL), is_equal_to (0)); + cJSON_Delete (json); +} + +Ensure (json, gvm_json_obj_check_int_1_when_missing) +{ + cJSON *json; + + json = cJSON_Parse ("{ \"eg\": 33 }"); + assert_that (json, is_not_null); + assert_that (gvm_json_obj_check_int (json, "err", NULL), is_equal_to (1)); + cJSON_Delete (json); +} + +Ensure (json, gvm_json_obj_check_int_1_when_str) +{ + cJSON *json; + + json = cJSON_Parse ("{ \"eg\": \"33\" }"); + assert_that (json, is_not_null); + assert_that (gvm_json_obj_check_int (json, "eg", NULL), is_equal_to (1)); + cJSON_Delete (json); +} + +Ensure (json, gvm_json_obj_check_int_0_and_val_when_has) +{ + cJSON *json; + int ret; + + json = cJSON_Parse ("{ \"eg\": 33 }"); + assert_that (json, is_not_null); + assert_that (gvm_json_obj_check_int (json, "eg", &ret), is_equal_to (0)); + assert_that (ret, is_equal_to (33)); + cJSON_Delete (json); +} + int main (int argc, char **argv) { @@ -145,6 +189,11 @@ main (int argc, char **argv) add_test_with_context (suite, json, gvm_json_obj_int_0_when_missing); add_test_with_context (suite, json, gvm_json_obj_int_0_when_str); + add_test_with_context (suite, json, gvm_json_obj_check_int_0_when_has); + add_test_with_context (suite, json, gvm_json_obj_check_int_1_when_missing); + add_test_with_context (suite, json, gvm_json_obj_check_int_1_when_str); + add_test_with_context (suite, json, gvm_json_obj_check_int_0_and_val_when_has); + if (argc > 1) return run_single_test (suite, argv[1], create_text_reporter ()); return run_test_suite (suite, create_text_reporter ()); From aebf62d63adb072fd91f0495fdec533403b85f51 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Wed, 5 Feb 2025 21:13:55 +0200 Subject: [PATCH 6/7] Doc: be clearer about the val arg --- util/json.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/json.c b/util/json.c index 80160a54..3082491c 100644 --- a/util/json.c +++ b/util/json.c @@ -88,7 +88,8 @@ gvm_json_obj_double (cJSON *obj, const gchar *key) * * @param[in] obj Object * @param[in] key Field name. - * @param[out] val Return location for int if int exists. + * @param[out] val Either NULL or a return location for the int (only set if + * int field exists). * * @return 0 if such an int field exists, else 1. */ From fa5ae356c05fcb8a9f74d599496994a99be5fe29 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Wed, 5 Feb 2025 21:15:44 +0200 Subject: [PATCH 7/7] Format --- util/json_tests.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/json_tests.c b/util/json_tests.c index f6328755..15c4e786 100644 --- a/util/json_tests.c +++ b/util/json_tests.c @@ -192,7 +192,8 @@ main (int argc, char **argv) add_test_with_context (suite, json, gvm_json_obj_check_int_0_when_has); add_test_with_context (suite, json, gvm_json_obj_check_int_1_when_missing); add_test_with_context (suite, json, gvm_json_obj_check_int_1_when_str); - add_test_with_context (suite, json, gvm_json_obj_check_int_0_and_val_when_has); + add_test_with_context (suite, json, + gvm_json_obj_check_int_0_and_val_when_has); if (argc > 1) return run_single_test (suite, argv[1], create_text_reporter ());