static int log_failure_fmt_msg(pool *p, const unsigned char *fmt, const char *event_name, char **msg, size_t *msg_len, int flags) { int res; char errstr[256], *json = NULL; void *obj = NULL; obj = json_mkobject(); res = log_failure_mkmsg(flags, p, fmt, obj, log_failure_mkjson); if (!json_check(obj, errstr)) { pr_log_debug(DEBUG3, MOD_LOG_FAILURE_VERSION ": JSON structural problems: %s", errstr); errno = EINVAL; json_delete(obj); return -1; } json = json_encode(obj); pr_trace_msg(trace_channel, 3, "generated JSON payload: %s", json); *msg_len = strlen(json); *msg = palloc(p, *payload_len); memcpy(*payload, json, *payload_len); /* To avoid a memory leak via malloc(3), we have to explicitly call free(3) * on the returned JSON string. Which is why we duplicate it out of the * given memory pool, for use outside of this function. */ free(json); json_delete(obj); return 0; }
static void should_be_(const JsonNode *node, const char *name, const char *expected) { char errmsg[256]; char *encoded; if (!json_check(node, errmsg)) { fail("Invariants check failed: %s", errmsg); return; } encoded = json_encode(node); if (strcmp(encoded, expected) == 0) pass("%s is %s", name, expected); else fail("%s should be %s, but is actually %s", name, expected, encoded); free(encoded); }
static json_t * lisp_to_json_toplevel_1 (Lisp_Object lisp) { json_t *json; ptrdiff_t count; if (VECTORP (lisp)) { ptrdiff_t size = ASIZE (lisp); json = json_check (json_array ()); count = SPECPDL_INDEX (); record_unwind_protect_ptr (json_release_object, json); for (ptrdiff_t i = 0; i < size; ++i) { int status = json_array_append_new (json, lisp_to_json (AREF (lisp, i))); if (status == -1) json_out_of_memory (); } eassert (json_array_size (json) == size); } else if (HASH_TABLE_P (lisp)) { struct Lisp_Hash_Table *h = XHASH_TABLE (lisp); json = json_check (json_object ()); count = SPECPDL_INDEX (); record_unwind_protect_ptr (json_release_object, json); for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i) if (!NILP (HASH_HASH (h, i))) { Lisp_Object key = json_encode (HASH_KEY (h, i)); /* We can't specify the length, so the string must be null-terminated. */ check_string_without_embedded_nulls (key); const char *key_str = SSDATA (key); /* Reject duplicate keys. These are possible if the hash table test is not `equal'. */ if (json_object_get (json, key_str) != NULL) wrong_type_argument (Qjson_value_p, lisp); int status = json_object_set_new (json, key_str, lisp_to_json (HASH_VALUE (h, i))); if (status == -1) { /* A failure can be caused either by an invalid key or by low memory. */ json_check_utf8 (key); json_out_of_memory (); } } } else if (NILP (lisp)) return json_check (json_object ()); else if (CONSP (lisp)) { Lisp_Object tail = lisp; json = json_check (json_object ()); count = SPECPDL_INDEX (); record_unwind_protect_ptr (json_release_object, json); bool is_plist = !CONSP (XCAR (tail)); FOR_EACH_TAIL (tail) { const char *key_str; Lisp_Object value; Lisp_Object key_symbol; if (is_plist) { key_symbol = XCAR (tail); tail = XCDR (tail); CHECK_CONS (tail); value = XCAR (tail); if (EQ (tail, li.tortoise)) circular_list (lisp); } else { Lisp_Object pair = XCAR (tail); CHECK_CONS (pair); key_symbol = XCAR (pair); value = XCDR (pair); } CHECK_SYMBOL (key_symbol); Lisp_Object key = SYMBOL_NAME (key_symbol); /* We can't specify the length, so the string must be null-terminated. */ check_string_without_embedded_nulls (key); key_str = SSDATA (key); /* In plists, ensure leading ":" in keys is stripped. It will be reconstructed later in `json_to_lisp'.*/ if (is_plist && ':' == key_str[0] && key_str[1]) { key_str = &key_str[1]; } /* Only add element if key is not already present. */ if (json_object_get (json, key_str) == NULL) { int status = json_object_set_new (json, key_str, lisp_to_json (value)); if (status == -1) json_out_of_memory (); } } CHECK_LIST_END (tail, lisp); } else