When sending a POST request with deployment feedback to hawkBit,
the payload for "details" was built by raw string concatenation of
TRACE/ERROR messages. If these messages contained JSON special characters,
the generated JSON became invalid, causing hawkBit to return a 400 Bad
Request with the following response body:
{
"errorCode": "hawkbit.server.error.rest.body.notReadable",
"exceptionClass": "org.eclipse.hawkbit.rest.exception.MessageNotReadableException",
"message": "The given request body is not well formed"
}
Particularly when this error occurs during feedback requests intended to
notify final statuses like "finished" or "error", hawkBit fails to register
the completion of the action. Consequently, hawkBit keeps the action active,
causing SWUpdate to repeatedly attempt the update at every polling interval.
To ensure robust serialization of arbitrary script outputs (stdout/stderr)
from run_system_cmd(), modify server_create_details() to construct the JSON
array using json-c. This guarantees proper JSON escaping for all special
characters in the deploymentBase feedback details.
Signed-off-by: Shota Shimoyama <
shota.s...@atmark-techno.com>
---
suricatta/server_hawkbit.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/suricatta/server_hawkbit.c b/suricatta/server_hawkbit.c
index a9d09ac5..781c023a 100644
--- a/suricatta/server_hawkbit.c
+++ b/suricatta/server_hawkbit.c
@@ -367,27 +367,35 @@ cleanup:
static char *server_create_details(int numdetails, const char *details[])
{
- int i, ret;
- char *prev = NULL;
- char *next = NULL;
+ int i;
+ struct json_object *jarray = NULL;
+ struct json_object *jstr = NULL;
+ char *result = NULL;
/*
* Note: NEVER call TRACE / ERROR inside this function
* because it generates a recursion
*/
+
+ jarray = json_object_new_array_ext(numdetails);
+ if (!jarray)
+ return NULL;
+
for (i = 0; i < numdetails; i++) {
- if (i == 0) {
- ret = asprintf(&next, "\"%s\"", details[i]);
- } else {
- ret = asprintf(&next, "%s,\"%s\"", prev, details[i]);
- free(prev);
- }
- if (ret == ENOMEM_ASPRINTF)
+ jstr = json_object_new_string(details[i]);
+ if (!jstr) {
+ json_object_put(jarray);
return NULL;
- prev = next;
+ }
+ json_object_array_add(jarray, jstr);
}
- return next;
+ const char *json_str = json_object_to_json_string(jarray);
+
+ result = json_str ? strdup(json_str) : NULL;
+
+ json_object_put(jarray);
+ return result;
}
server_op_res_t
@@ -421,7 +429,7 @@ server_send_deployment_reply(channel_t *channel,
"finished": "%s"
},
"execution": "%s",
- "details" : [ %s ]
+ "details" : %s
}
}
);
@@ -436,7 +444,7 @@ server_send_deployment_reply(channel_t *channel,
if (ENOMEM_ASPRINTF ==
asprintf(&json_reply_string, json_hawkbit_deployment_feedback,
action_id, fdate, job_cnt_cur, job_cnt_max, finished,
- execution_status, detail ? detail : " ")) {
+ execution_status, detail ? detail : "[]")) {
ERROR("hawkBit server reply cannot be sent because of OOM.");
result = SERVER_EINIT;
goto cleanup;
--
2.34.1