Fix false ***buffer overflow*** detection
[src/app-framework-binder.git] / src / afb-api-dbus.c
index a2c9b08..17e1eb0 100644 (file)
@@ -27,6 +27,9 @@
 
 #include <systemd/sd-bus.h>
 #include <json-c/json.h>
+#if !defined(JSON_C_TO_STRING_NOSLASHESCAPE)
+#define JSON_C_TO_STRING_NOSLASHESCAPE 0
+#endif
 
 #include <afb/afb-event-x2.h>
 
@@ -43,6 +46,7 @@
 #include "afb-xreq.h"
 #include "verbose.h"
 
+
 static const char DEFAULT_PATH_PREFIX[] = "/org/agl/afb/api/";
 
 struct dbus_memo;
@@ -282,6 +286,8 @@ static int api_dbus_client_on_reply(sd_bus_message *message, void *userdata, sd_
        int rc;
        struct dbus_memo *memo;
        const char *json, *error, *info;
+       struct json_object *object;
+       enum json_tokener_error jerr;
 
        /* retrieve the recorded data */
        memo = userdata;
@@ -293,7 +299,14 @@ static int api_dbus_client_on_reply(sd_bus_message *message, void *userdata, sd_
                afb_xreq_reply(memo->xreq, NULL, "error", "dbus error");
        } else {
                /* report the answer */
-               afb_xreq_reply(memo->xreq, *json ? json_tokener_parse(json) : NULL, *error ? error : NULL, *info ? info : NULL);
+               if (!*json)
+                       object = NULL;
+               else {
+                       object = json_tokener_parse_verbose(json, &jerr);
+                       if (jerr != json_tokener_success)
+                               object = json_object_new_string(json);
+               }
+               afb_xreq_reply(memo->xreq, object, *error ? error : NULL, *info ? info : NULL);
        }
        api_dbus_client_memo_destroy(memo);
        return 1;
@@ -354,11 +367,14 @@ static int api_dbus_client_on_broadcast_event(sd_bus_message *m, void *userdata,
 {
        struct json_object *object;
        const char *event, *data;
+       enum json_tokener_error jerr;
        int rc = sd_bus_message_read(m, "ss", &event, &data);
        if (rc < 0)
                ERROR("unreadable broadcasted event");
        else {
-               object = json_tokener_parse(data);
+               object = json_tokener_parse_verbose(data, &jerr);
+               if (jerr != json_tokener_success)
+                       object = json_object_new_string(data);
                afb_evt_broadcast(event, object);
        }
        return 1;
@@ -437,6 +453,7 @@ static void api_dbus_client_event_push(struct api_dbus *api, int id, const char
 {
        struct json_object *object;
        struct dbus_event *ev;
+       enum json_tokener_error jerr;
 
        /* retrieves the event */
        ev = api_dbus_client_event_search(api, id, name);
@@ -446,7 +463,9 @@ static void api_dbus_client_event_push(struct api_dbus *api, int id, const char
        }
 
        /* destroys the event */
-       object = json_tokener_parse(data);
+       object = json_tokener_parse_verbose(data, &jerr);
+       if (jerr != json_tokener_success)
+               object = json_object_new_string(data);
        afb_evt_event_x2_push(ev->event, object);
 }
 
@@ -646,7 +665,7 @@ struct origin
        struct afb_cred *cred;
 
        /* the origin */
-       char name[1];
+       char name[];
 };
 
 /* get the credentials for the message */
@@ -690,7 +709,7 @@ static struct origin *afb_api_dbus_server_origin_get(struct api_dbus *api, const
        }
 
        /* not found, create it */
-       origin = malloc(strlen(sender) + sizeof *origin);
+       origin = malloc(strlen(sender) + 1 + sizeof *origin);
        if (origin == NULL)
                errno = ENOMEM;
        else {
@@ -810,7 +829,7 @@ void dbus_req_raw_reply(struct afb_xreq *xreq, struct json_object *obj, const ch
        int rc;
 
        rc = sd_bus_reply_method_return(dreq->message, "sss",
-               obj ? json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN) : "",
+               obj ? json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOSLASHESCAPE) : "",
                error ? : "",
                info ? : "");
        if (rc < 0)
@@ -892,7 +911,7 @@ static void afb_api_dbus_server_event_remove(void *closure, const char *event, i
 
 static void afb_api_dbus_server_event_push(void *closure, const char *event, int eventid, struct json_object *object)
 {
-       const char *data = json_object_to_json_string_ext(object, JSON_C_TO_STRING_PLAIN);
+       const char *data = json_object_to_json_string_ext(object, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOSLASHESCAPE);
        afb_api_dbus_server_event_send(closure, '!', event, eventid, data, 0);
        json_object_put(object);
 }
@@ -904,7 +923,7 @@ static void afb_api_dbus_server_event_broadcast(void *closure, const char *event
 
        api = closure;
        rc = sd_bus_emit_signal(api->sdbus, api->path, api->name, "broadcast",
-                       "ss", event, json_object_to_json_string_ext(object, JSON_C_TO_STRING_PLAIN));
+                       "ss", event, json_object_to_json_string_ext(object, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOSLASHESCAPE));
        if (rc < 0)
                ERROR("error while broadcasting event %s", event);
        json_object_put(object);
@@ -922,6 +941,7 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd
        uint32_t flags;
        struct afb_session *session;
        struct listener *listener;
+       enum json_tokener_error jerr;
 
        /* check the interface */
        if (strcmp(sd_bus_message_get_interface(message), api->name) != 0)
@@ -957,8 +977,8 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd
        dreq->xreq.context.flags = flags;
        dreq->xreq.cred = afb_cred_mixed_on_behalf_import(listener->origin->cred, uuid, creds && creds[0] ? creds : NULL);
        dreq->message = sd_bus_message_ref(message);
-       dreq->json = json_tokener_parse(dreq->request);
-       if (dreq->json == NULL && strcmp(dreq->request, "null")) {
+       dreq->json = json_tokener_parse_verbose(dreq->request, &jerr);
+       if (jerr != json_tokener_success) {
                /* lazy error detection of json request. Is it to improve? */
                dreq->json = json_object_new_string(dreq->request);
        }