json.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2012 - 2013, Digium, Inc.
  5. *
  6. * David M. Lee, II <dlee@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief JSON abstraction layer.
  21. *
  22. * This is a very thin wrapper around the Jansson API. For more details on it,
  23. * see its docs at http://www.digip.org/jansson/doc/2.4/apiref.html.
  24. *
  25. * \author David M. Lee, II <dlee@digium.com>
  26. */
  27. /*** MODULEINFO
  28. <depend>jansson</depend>
  29. <support_level>core</support_level>
  30. ***/
  31. #include "asterisk.h"
  32. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  33. #include "asterisk/json.h"
  34. #include "asterisk/localtime.h"
  35. #include "asterisk/module.h"
  36. #include "asterisk/utils.h"
  37. #include "asterisk/astobj2.h"
  38. #include "asterisk/channel.h"
  39. #include "asterisk/callerid.h"
  40. #include <jansson.h>
  41. #include <time.h>
  42. #if defined(JANSSON_THREAD_SAFE_REFCOUNT)
  43. void *ast_json_malloc(size_t size)
  44. {
  45. return ast_malloc(size);
  46. }
  47. void ast_json_free(void *p)
  48. {
  49. ast_free(p);
  50. }
  51. /* No need to lock since jansson is thread safe. */
  52. #define SCOPED_JSON_LOCK(json)
  53. #else
  54. /*! \brief Magic number, for safety checks. */
  55. #define JSON_MAGIC 0x1541992
  56. /*! \brief Internal structure for allocated memory blocks */
  57. struct json_mem {
  58. /*! Magic number, for safety checks */
  59. uint32_t magic;
  60. /*! Mutext for locking this memory block */
  61. ast_mutex_t mutex;
  62. /*! Linked list pointer for the free list */
  63. AST_LIST_ENTRY(json_mem) list;
  64. /*! Data section of the allocation; void pointer for proper alignment */
  65. void *data[];
  66. };
  67. /*! \brief Free a \ref json_mem block. */
  68. static void json_mem_free(struct json_mem *mem)
  69. {
  70. mem->magic = 0;
  71. ast_mutex_destroy(&mem->mutex);
  72. ast_free(mem);
  73. }
  74. /*!
  75. * \brief Get the \ref json_mem block for a pointer allocated via
  76. * ast_json_malloc().
  77. *
  78. * This function properly handles Jansson singletons (null, true, false), and
  79. * \c NULL.
  80. *
  81. * \param p Pointer, usually to a \c json_t or \ref ast_json.
  82. * \return \ref json_mem object with extra allocation info.
  83. */
  84. static inline struct json_mem *to_json_mem(void *p)
  85. {
  86. struct json_mem *mem;
  87. /* Avoid ref'ing the singleton values */
  88. if (p == NULL || p == json_null() || p == json_true() ||
  89. p == json_false()) {
  90. return NULL;
  91. }
  92. mem = (struct json_mem *)((char *) (p) - sizeof(*mem));
  93. ast_assert(mem->magic == JSON_MAGIC);
  94. return mem;
  95. }
  96. /*!
  97. * \brief Lock an \ref ast_json instance.
  98. *
  99. * If \a json is an immutable singleton (null, true, false), this function
  100. * safely ignores it and returns \c NULL. Otherwise, \a json must have been
  101. * allocates using ast_json_malloc().
  102. *
  103. * \param json JSON instance to lock.
  104. * \return \ref Corresponding \ref json_mem block.
  105. * \return \c NULL if \a json was not allocated.
  106. */
  107. static struct json_mem *json_mem_lock(struct ast_json *json)
  108. {
  109. struct json_mem *mem = to_json_mem(json);
  110. if (!mem) {
  111. return NULL;
  112. }
  113. ast_mutex_lock(&mem->mutex);
  114. return mem;
  115. }
  116. /*!
  117. * \brief Unlock a \ref json_mem instance.
  118. *
  119. * \param mem \ref json_mem, usually returned from json_mem_lock().
  120. */
  121. static void json_mem_unlock(struct json_mem *mem)
  122. {
  123. if (!mem) {
  124. return;
  125. }
  126. ast_mutex_unlock(&mem->mutex);
  127. }
  128. /*!
  129. * \brief Scoped lock for a \ref ast_json instance.
  130. *
  131. * \param json JSON instance to lock.
  132. */
  133. #define SCOPED_JSON_LOCK(json) \
  134. RAII_VAR(struct json_mem *, __mem_ ## __LINE__, \
  135. json_mem_lock(json), json_mem_unlock)
  136. void *ast_json_malloc(size_t size)
  137. {
  138. struct json_mem *mem = ast_malloc(size + sizeof(*mem));
  139. if (!mem) {
  140. return NULL;
  141. }
  142. mem->magic = JSON_MAGIC;
  143. ast_mutex_init(&mem->mutex);
  144. return mem->data;
  145. }
  146. AST_THREADSTORAGE(json_free_list_ts);
  147. /*!
  148. * \brief Struct for a linked list of \ref json_mem.
  149. */
  150. AST_LIST_HEAD_NOLOCK(json_mem_list, json_mem);
  151. /*!
  152. * \brief Thread local list of \ref json_mem blocks to free at the end of an
  153. * unref.
  154. */
  155. static struct json_mem_list *json_free_list(void)
  156. {
  157. return ast_threadstorage_get(&json_free_list_ts,
  158. sizeof(struct json_mem_list));
  159. }
  160. void ast_json_free(void *p)
  161. {
  162. struct json_mem *mem;
  163. struct json_mem_list *free_list;
  164. mem = to_json_mem(p);
  165. if (!mem) {
  166. return;
  167. }
  168. /* Since the unref is holding a lock in mem, we can't free it
  169. * immediately. Store it off on a thread local list to be freed by
  170. * ast_json_unref().
  171. */
  172. free_list = json_free_list();
  173. if (!free_list) {
  174. ast_log(LOG_ERROR, "Error allocating free list\n");
  175. ast_assert(0);
  176. /* It's not ideal to free the memory immediately, but that's the
  177. * best we can do if the threadlocal allocation fails */
  178. json_mem_free(mem);
  179. return;
  180. }
  181. AST_LIST_INSERT_HEAD(free_list, mem, list);
  182. }
  183. #endif
  184. void ast_json_set_alloc_funcs(void *(*malloc_fn)(size_t), void (*free_fn)(void*))
  185. {
  186. json_set_alloc_funcs(malloc_fn, free_fn);
  187. }
  188. void ast_json_reset_alloc_funcs(void)
  189. {
  190. json_set_alloc_funcs(ast_json_malloc, ast_json_free);
  191. }
  192. struct ast_json *ast_json_ref(struct ast_json *json)
  193. {
  194. /* If Jansson refcounting is non-atomic; lock it. */
  195. SCOPED_JSON_LOCK(json);
  196. json_incref((json_t *)json);
  197. return json;
  198. }
  199. void ast_json_unref(struct ast_json *json)
  200. {
  201. #if defined(JANSSON_THREAD_SAFE_REFCOUNT)
  202. json_decref((json_t *) json);
  203. #else
  204. struct json_mem_list *free_list;
  205. struct json_mem *mem;
  206. if (!json) {
  207. return;
  208. }
  209. /* Jansson refcounting is non-atomic; lock it. */
  210. {
  211. SCOPED_JSON_LOCK(json);
  212. json_decref((json_t *) json);
  213. }
  214. /* Now free any objects that were ast_json_free()'s while the lock was
  215. * held */
  216. free_list = json_free_list();
  217. if (!free_list) {
  218. return;
  219. }
  220. while ((mem = AST_LIST_REMOVE_HEAD(free_list, list))) {
  221. json_mem_free(mem);
  222. }
  223. #endif
  224. }
  225. enum ast_json_type ast_json_typeof(const struct ast_json *json)
  226. {
  227. int r = json_typeof((json_t*)json);
  228. switch(r) {
  229. case JSON_OBJECT: return AST_JSON_OBJECT;
  230. case JSON_ARRAY: return AST_JSON_ARRAY;
  231. case JSON_STRING: return AST_JSON_STRING;
  232. case JSON_INTEGER: return AST_JSON_INTEGER;
  233. case JSON_REAL: return AST_JSON_REAL;
  234. case JSON_TRUE: return AST_JSON_TRUE;
  235. case JSON_FALSE: return AST_JSON_FALSE;
  236. case JSON_NULL: return AST_JSON_NULL;
  237. }
  238. ast_assert(0); /* Unexpect return from json_typeof */
  239. return r;
  240. }
  241. const char *ast_json_typename(enum ast_json_type type)
  242. {
  243. switch (type) {
  244. case AST_JSON_OBJECT: return "object";
  245. case AST_JSON_ARRAY: return "array";
  246. case AST_JSON_STRING: return "string";
  247. case AST_JSON_INTEGER: return "integer";
  248. case AST_JSON_REAL: return "real";
  249. case AST_JSON_TRUE: return "boolean";
  250. case AST_JSON_FALSE: return "boolean";
  251. case AST_JSON_NULL: return "null";
  252. }
  253. ast_assert(0);
  254. return "?";
  255. }
  256. /* Ported from libjansson utf.c:utf8_check_first() */
  257. static size_t json_utf8_check_first(char byte)
  258. {
  259. unsigned char ch = (unsigned char) byte;
  260. if (ch < 0x80) {
  261. return 1;
  262. }
  263. if (0x80 <= ch && ch <= 0xBF) {
  264. /* second, third or fourth byte of a multi-byte
  265. sequence, i.e. a "continuation byte" */
  266. return 0;
  267. } else if (ch == 0xC0 || ch == 0xC1) {
  268. /* overlong encoding of an ASCII byte */
  269. return 0;
  270. } else if (0xC2 <= ch && ch <= 0xDF) {
  271. /* 2-byte sequence */
  272. return 2;
  273. } else if (0xE0 <= ch && ch <= 0xEF) {
  274. /* 3-byte sequence */
  275. return 3;
  276. } else if (0xF0 <= ch && ch <= 0xF4) {
  277. /* 4-byte sequence */
  278. return 4;
  279. } else { /* ch >= 0xF5 */
  280. /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid
  281. UTF-8 */
  282. return 0;
  283. }
  284. }
  285. /* Ported from libjansson utf.c:utf8_check_full() */
  286. static size_t json_utf8_check_full(const char *str, size_t len)
  287. {
  288. size_t pos;
  289. int32_t value;
  290. unsigned char ch = (unsigned char) str[0];
  291. if (len == 2) {
  292. value = ch & 0x1F;
  293. } else if (len == 3) {
  294. value = ch & 0xF;
  295. } else if (len == 4) {
  296. value = ch & 0x7;
  297. } else {
  298. return 0;
  299. }
  300. for (pos = 1; pos < len; ++pos) {
  301. ch = (unsigned char) str[pos];
  302. if (ch < 0x80 || ch > 0xBF) {
  303. /* not a continuation byte */
  304. return 0;
  305. }
  306. value = (value << 6) + (ch & 0x3F);
  307. }
  308. if (value > 0x10FFFF) {
  309. /* not in Unicode range */
  310. return 0;
  311. } else if (0xD800 <= value && value <= 0xDFFF) {
  312. /* invalid code point (UTF-16 surrogate halves) */
  313. return 0;
  314. } else if ((len == 2 && value < 0x80)
  315. || (len == 3 && value < 0x800)
  316. || (len == 4 && value < 0x10000)) {
  317. /* overlong encoding */
  318. return 0;
  319. }
  320. return 1;
  321. }
  322. int ast_json_utf8_check_len(const char *str, size_t len)
  323. {
  324. size_t pos;
  325. size_t count;
  326. int res = 1;
  327. if (!str) {
  328. return 0;
  329. }
  330. /*
  331. * Since the json library does not make the check function
  332. * public we recreate/copy the function in our interface
  333. * module.
  334. *
  335. * Loop ported from libjansson utf.c:utf8_check_string()
  336. */
  337. for (pos = 0; pos < len; pos += count) {
  338. count = json_utf8_check_first(str[pos]);
  339. if (count == 0) {
  340. res = 0;
  341. break;
  342. } else if (count > 1) {
  343. if (count > len - pos) {
  344. /* UTF-8 needs more than we have left in the string. */
  345. res = 0;
  346. break;
  347. }
  348. if (!json_utf8_check_full(&str[pos], count)) {
  349. res = 0;
  350. break;
  351. }
  352. }
  353. }
  354. if (!res) {
  355. ast_debug(1, "String '%.*s' is not UTF-8 for json conversion\n", (int) len, str);
  356. }
  357. return res;
  358. }
  359. int ast_json_utf8_check(const char *str)
  360. {
  361. return str ? ast_json_utf8_check_len(str, strlen(str)) : 0;
  362. }
  363. struct ast_json *ast_json_true(void)
  364. {
  365. return (struct ast_json *)json_true();
  366. }
  367. struct ast_json *ast_json_false(void)
  368. {
  369. return (struct ast_json *)json_false();
  370. }
  371. struct ast_json *ast_json_boolean(int value)
  372. {
  373. #if JANSSON_VERSION_HEX >= 0x020400
  374. return (struct ast_json *)json_boolean(value);
  375. #else
  376. return value ? ast_json_true() : ast_json_false();
  377. #endif
  378. }
  379. struct ast_json *ast_json_null(void)
  380. {
  381. return (struct ast_json *)json_null();
  382. }
  383. int ast_json_is_true(const struct ast_json *json)
  384. {
  385. return json_is_true((const json_t *)json);
  386. }
  387. int ast_json_is_false(const struct ast_json *json)
  388. {
  389. return json_is_false((const json_t *)json);
  390. }
  391. int ast_json_is_null(const struct ast_json *json)
  392. {
  393. return json_is_null((const json_t *)json);
  394. }
  395. struct ast_json *ast_json_string_create(const char *value)
  396. {
  397. return (struct ast_json *)json_string(value);
  398. }
  399. const char *ast_json_string_get(const struct ast_json *string)
  400. {
  401. return json_string_value((json_t *)string);
  402. }
  403. int ast_json_string_set(struct ast_json *string, const char *value)
  404. {
  405. return json_string_set((json_t *)string, value);
  406. }
  407. struct ast_json *ast_json_stringf(const char *format, ...)
  408. {
  409. struct ast_json *ret;
  410. va_list args;
  411. va_start(args, format);
  412. ret = ast_json_vstringf(format, args);
  413. va_end(args);
  414. return ret;
  415. }
  416. struct ast_json *ast_json_vstringf(const char *format, va_list args)
  417. {
  418. json_t *ret = NULL;
  419. if (format) {
  420. /* json_pack was not introduced until jansson-2.0 so Asterisk could never
  421. * be compiled against older versions. The version check can never match
  422. * anything older than 2.12. */
  423. #if defined(HAVE_JANSSON_BUNDLED) || JANSSON_MAJOR_VERSION > 2 || JANSSON_MINOR_VERSION > 11
  424. ret = json_vsprintf(format, args);
  425. #else
  426. char *str = NULL;
  427. int err = ast_vasprintf(&str, format, args);
  428. if (err >= 0) {
  429. ret = json_string(str);
  430. ast_free(str);
  431. }
  432. #endif
  433. }
  434. return (struct ast_json *)ret;
  435. }
  436. struct ast_json *ast_json_integer_create(intmax_t value)
  437. {
  438. return (struct ast_json *)json_integer(value);
  439. }
  440. intmax_t ast_json_integer_get(const struct ast_json *integer)
  441. {
  442. return json_integer_value((json_t *)integer);
  443. }
  444. int ast_json_integer_set(struct ast_json *integer, intmax_t value)
  445. {
  446. return json_integer_set((json_t *)integer, value);
  447. }
  448. struct ast_json *ast_json_real_create(double value)
  449. {
  450. return (struct ast_json *)json_real(value);
  451. }
  452. double ast_json_real_get(const struct ast_json *real)
  453. {
  454. return json_real_value((json_t *)real);
  455. }
  456. int ast_json_real_set(struct ast_json *real, double value)
  457. {
  458. return json_real_set((json_t *)real, value);
  459. }
  460. int ast_json_equal(const struct ast_json *lhs, const struct ast_json *rhs)
  461. {
  462. return json_equal((json_t *)lhs, (json_t *)rhs);
  463. }
  464. struct ast_json *ast_json_array_create(void)
  465. {
  466. return (struct ast_json *)json_array();
  467. }
  468. size_t ast_json_array_size(const struct ast_json *array)
  469. {
  470. return json_array_size((json_t *)array);
  471. }
  472. struct ast_json *ast_json_array_get(const struct ast_json *array, size_t index)
  473. {
  474. return (struct ast_json *)json_array_get((json_t *)array, index);
  475. }
  476. int ast_json_array_set(struct ast_json *array, size_t index, struct ast_json *value)
  477. {
  478. return json_array_set_new((json_t *)array, index, (json_t *)value);
  479. }
  480. int ast_json_array_append(struct ast_json *array, struct ast_json *value)
  481. {
  482. return json_array_append_new((json_t *)array, (json_t *)value);
  483. }
  484. int ast_json_array_insert(struct ast_json *array, size_t index, struct ast_json *value)
  485. {
  486. return json_array_insert_new((json_t *)array, index, (json_t *)value);
  487. }
  488. int ast_json_array_remove(struct ast_json *array, size_t index)
  489. {
  490. return json_array_remove((json_t *)array, index);
  491. }
  492. int ast_json_array_clear(struct ast_json *array)
  493. {
  494. return json_array_clear((json_t *)array);
  495. }
  496. int ast_json_array_extend(struct ast_json *array, struct ast_json *tail)
  497. {
  498. return json_array_extend((json_t *)array, (json_t *)tail);
  499. }
  500. struct ast_json *ast_json_object_create(void)
  501. {
  502. return (struct ast_json *)json_object();
  503. }
  504. size_t ast_json_object_size(struct ast_json *object)
  505. {
  506. return json_object_size((json_t *)object);
  507. }
  508. struct ast_json *ast_json_object_get(struct ast_json *object, const char *key)
  509. {
  510. if (!key) {
  511. return NULL;
  512. }
  513. return (struct ast_json *)json_object_get((json_t *)object, key);
  514. }
  515. int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
  516. {
  517. return json_object_set_new((json_t *)object, key, (json_t *)value);
  518. }
  519. int ast_json_object_del(struct ast_json *object, const char *key)
  520. {
  521. return json_object_del((json_t *)object, key);
  522. }
  523. int ast_json_object_clear(struct ast_json *object)
  524. {
  525. return json_object_clear((json_t *)object);
  526. }
  527. int ast_json_object_update(struct ast_json *object, struct ast_json *other)
  528. {
  529. return json_object_update((json_t *)object, (json_t *)other);
  530. }
  531. int ast_json_object_update_existing(struct ast_json *object, struct ast_json *other)
  532. {
  533. #if JANSSON_VERSION_HEX >= 0x020300
  534. return json_object_update_existing((json_t *)object, (json_t *)other);
  535. #else
  536. struct ast_json_iter *iter = ast_json_object_iter(other);
  537. int ret = 0;
  538. if (object == NULL || other == NULL) {
  539. return -1;
  540. }
  541. while (iter != NULL && ret == 0) {
  542. const char *key = ast_json_object_iter_key(iter);
  543. if (ast_json_object_get(object, key) != NULL) {
  544. struct ast_json *value = ast_json_object_iter_value(iter);
  545. if (!value || ast_json_object_set(object, key, ast_json_ref(value))) {
  546. ret = -1;
  547. }
  548. }
  549. iter = ast_json_object_iter_next(other, iter);
  550. }
  551. return ret;
  552. #endif
  553. }
  554. int ast_json_object_update_missing(struct ast_json *object, struct ast_json *other)
  555. {
  556. #if JANSSON_VERSION_HEX >= 0x020300
  557. return json_object_update_missing((json_t *)object, (json_t *)other);
  558. #else
  559. struct ast_json_iter *iter = ast_json_object_iter(other);
  560. int ret = 0;
  561. if (object == NULL || other == NULL) {
  562. return -1;
  563. }
  564. while (iter != NULL && ret == 0) {
  565. const char *key = ast_json_object_iter_key(iter);
  566. if (ast_json_object_get(object, key) == NULL) {
  567. struct ast_json *value = ast_json_object_iter_value(iter);
  568. if (!value || ast_json_object_set(object, key, ast_json_ref(value))) {
  569. ret = -1;
  570. }
  571. }
  572. iter = ast_json_object_iter_next(other, iter);
  573. }
  574. return ret;
  575. #endif
  576. }
  577. struct ast_json_iter *ast_json_object_iter(struct ast_json *object)
  578. {
  579. return json_object_iter((json_t *)object);
  580. }
  581. struct ast_json_iter *ast_json_object_iter_at(struct ast_json *object, const char *key)
  582. {
  583. return json_object_iter_at((json_t *)object, key);
  584. }
  585. struct ast_json_iter *ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
  586. {
  587. return json_object_iter_next((json_t *)object, iter);
  588. }
  589. const char *ast_json_object_iter_key(struct ast_json_iter *iter)
  590. {
  591. return json_object_iter_key(iter);
  592. }
  593. struct ast_json *ast_json_object_iter_value(struct ast_json_iter *iter)
  594. {
  595. return (struct ast_json *)json_object_iter_value(iter);
  596. }
  597. int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter, struct ast_json *value)
  598. {
  599. return json_object_iter_set_new((json_t *)object, iter, (json_t *)value);
  600. }
  601. /*!
  602. * \brief Default flags for JSON encoding.
  603. */
  604. static size_t dump_flags(enum ast_json_encoding_format format)
  605. {
  606. return format == AST_JSON_PRETTY ?
  607. JSON_INDENT(2) | JSON_PRESERVE_ORDER : JSON_COMPACT;
  608. }
  609. char *ast_json_dump_string_format(struct ast_json *root, enum ast_json_encoding_format format)
  610. {
  611. /* Jansson's json_dump*, even though it's a read operation, isn't
  612. * thread safe for concurrent reads. Locking is necessary.
  613. * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety.
  614. *
  615. * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined,
  616. * in that case SCOPED_JSON_LOCK is a no-op.
  617. */
  618. SCOPED_JSON_LOCK(root);
  619. return json_dumps((json_t *)root, dump_flags(format));
  620. }
  621. static int write_to_ast_str(const char *buffer, size_t size, void *data)
  622. {
  623. struct ast_str **dst = data;
  624. size_t str_size = ast_str_size(*dst);
  625. size_t remaining = str_size - ast_str_strlen(*dst);
  626. int ret;
  627. /* While ast_str_append will grow the ast_str, it won't report
  628. * allocation errors. Fortunately, it's not that hard.
  629. */
  630. /* Remaining needs to be big enough for buffer, plus null char */
  631. while (remaining < size + 1) {
  632. /* doubling the size of the buffer gives us 'amortized
  633. * constant' time.
  634. * See http://stackoverflow.com/a/249695/115478 for info.
  635. */
  636. str_size *= 2;
  637. remaining = str_size - ast_str_strlen(*dst);
  638. }
  639. ret = ast_str_make_space(dst, str_size);
  640. if (ret == -1) {
  641. /* Could not alloc; fail */
  642. return -1;
  643. }
  644. ast_str_append_substr(dst, -1, buffer, size);
  645. return 0;
  646. }
  647. int ast_json_dump_str_format(struct ast_json *root, struct ast_str **dst, enum ast_json_encoding_format format)
  648. {
  649. /* Jansson's json_dump*, even though it's a read operation, isn't
  650. * thread safe for concurrent reads. Locking is necessary.
  651. * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety.
  652. *
  653. * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined,
  654. * in that case SCOPED_JSON_LOCK is a no-op.
  655. */
  656. SCOPED_JSON_LOCK(root);
  657. return json_dump_callback((json_t *)root, write_to_ast_str, dst, dump_flags(format));
  658. }
  659. int ast_json_dump_file_format(struct ast_json *root, FILE *output, enum ast_json_encoding_format format)
  660. {
  661. /* Jansson's json_dump*, even though it's a read operation, isn't
  662. * thread safe for concurrent reads. Locking is necessary.
  663. * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety.
  664. *
  665. * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined,
  666. * in that case SCOPED_JSON_LOCK is a no-op.
  667. */
  668. SCOPED_JSON_LOCK(root);
  669. if (!root || !output) {
  670. return -1;
  671. }
  672. return json_dumpf((json_t *)root, output, dump_flags(format));
  673. }
  674. int ast_json_dump_new_file_format(struct ast_json *root, const char *path, enum ast_json_encoding_format format)
  675. {
  676. /* Jansson's json_dump*, even though it's a read operation, isn't
  677. * thread safe for concurrent reads. Locking is necessary.
  678. * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety.
  679. *
  680. * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined,
  681. * in that case SCOPED_JSON_LOCK is a no-op.
  682. */
  683. SCOPED_JSON_LOCK(root);
  684. if (!root || !path) {
  685. return -1;
  686. }
  687. return json_dump_file((json_t *)root, path, dump_flags(format));
  688. }
  689. /*!
  690. * \brief Copy Jansson error struct to ours.
  691. */
  692. static void copy_error(struct ast_json_error *error, const json_error_t *jansson_error)
  693. {
  694. if (error && jansson_error) {
  695. error->line = jansson_error->line;
  696. error->column = jansson_error->column;
  697. error->position = jansson_error->position;
  698. ast_copy_string(error->text, jansson_error->text, sizeof(error->text));
  699. ast_copy_string(error->source, jansson_error->source, sizeof(error->source));
  700. }
  701. }
  702. static void parse_error(struct ast_json_error *error, const char *text, const char *source)
  703. {
  704. if (error != NULL) {
  705. error->line = 0;
  706. error->column = 0;
  707. error->position = 0;
  708. strncpy(error->text, text, sizeof(error->text));
  709. strncpy(error->source, source, sizeof(error->text));
  710. }
  711. }
  712. struct ast_json *ast_json_load_string(const char *input, struct ast_json_error *error)
  713. {
  714. json_error_t jansson_error = {};
  715. struct ast_json *r = NULL;
  716. if (input != NULL) {
  717. r = (struct ast_json *)json_loads(input, 0, &jansson_error);
  718. copy_error(error, &jansson_error);
  719. } else {
  720. parse_error(error, "NULL input string", "<null>");
  721. }
  722. return r;
  723. }
  724. struct ast_json *ast_json_load_str(const struct ast_str *input, struct ast_json_error *error)
  725. {
  726. return ast_json_load_string(ast_str_buffer(input), error);
  727. }
  728. struct ast_json *ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
  729. {
  730. json_error_t jansson_error = {};
  731. struct ast_json *r = (struct ast_json *)json_loadb(buffer, buflen, 0, &jansson_error);
  732. copy_error(error, &jansson_error);
  733. return r;
  734. }
  735. struct ast_json *ast_json_load_file(FILE *input, struct ast_json_error *error)
  736. {
  737. json_error_t jansson_error = {};
  738. struct ast_json *r = NULL;
  739. if (input != NULL) {
  740. r = (struct ast_json *)json_loadf(input, 0, &jansson_error);
  741. copy_error(error, &jansson_error);
  742. } else {
  743. parse_error(error, "NULL input file", "<null>");
  744. }
  745. return r;
  746. }
  747. struct ast_json *ast_json_load_new_file(const char *path, struct ast_json_error *error)
  748. {
  749. json_error_t jansson_error = {};
  750. struct ast_json *r = (struct ast_json *)json_load_file(path, 0, &jansson_error);
  751. copy_error(error, &jansson_error);
  752. return r;
  753. }
  754. struct ast_json *ast_json_pack(char const *format, ...)
  755. {
  756. struct ast_json *ret;
  757. va_list args;
  758. va_start(args, format);
  759. ret = ast_json_vpack(format, args);
  760. va_end(args);
  761. return ret;
  762. }
  763. struct ast_json *ast_json_vpack(char const *format, va_list ap)
  764. {
  765. json_error_t error;
  766. struct ast_json *r = NULL;
  767. if (format) {
  768. r = (struct ast_json *)json_vpack_ex(&error, 0, format, ap);
  769. if (!r && !ast_strlen_zero(error.text)) {
  770. ast_log(LOG_ERROR,
  771. "Error building JSON from '%s': %s.\n",
  772. format, error.text);
  773. ast_log_backtrace();
  774. }
  775. }
  776. return r;
  777. }
  778. struct ast_json *ast_json_copy(const struct ast_json *value)
  779. {
  780. return (struct ast_json *)json_copy((json_t *)value);
  781. }
  782. struct ast_json *ast_json_deep_copy(const struct ast_json *value)
  783. {
  784. return (struct ast_json *)json_deep_copy((json_t *)value);
  785. }
  786. struct ast_json *ast_json_name_number(const char *name, const char *number)
  787. {
  788. return ast_json_pack("{s: s, s: s}",
  789. "name", AST_JSON_UTF8_VALIDATE(name),
  790. "number", AST_JSON_UTF8_VALIDATE(number));
  791. }
  792. struct ast_json *ast_json_dialplan_cep(const char *context, const char *exten, int priority)
  793. {
  794. return ast_json_pack("{s: o, s: o, s: o}",
  795. "context", context ? ast_json_string_create(context) : ast_json_null(),
  796. "exten", exten ? ast_json_string_create(exten) : ast_json_null(),
  797. "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null());
  798. }
  799. struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone)
  800. {
  801. char buf[AST_ISO8601_LEN];
  802. struct ast_tm tm = {};
  803. ast_localtime(&tv, &tm, zone);
  804. ast_strftime(buf, sizeof(buf),AST_ISO8601_FORMAT, &tm);
  805. return ast_json_string_create(buf);
  806. }
  807. struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type)
  808. {
  809. struct ast_str *string = ast_str_alloca(64);
  810. if (!string) {
  811. return NULL;
  812. }
  813. ast_str_set(&string, 0, (ast_sockaddr_is_ipv4(addr) ||
  814. ast_sockaddr_is_ipv4_mapped(addr)) ? "IPV4/" : "IPV6/");
  815. if (transport_type) {
  816. char *transport_string = NULL;
  817. /* NOTE: None will be applied if multiple transport types are specified in transport_type */
  818. switch(transport_type) {
  819. case AST_TRANSPORT_UDP:
  820. transport_string = "UDP";
  821. break;
  822. case AST_TRANSPORT_TCP:
  823. transport_string = "TCP";
  824. break;
  825. case AST_TRANSPORT_TLS:
  826. transport_string = "TLS";
  827. break;
  828. case AST_TRANSPORT_WS:
  829. transport_string = "WS";
  830. break;
  831. case AST_TRANSPORT_WSS:
  832. transport_string = "WSS";
  833. break;
  834. }
  835. if (transport_string) {
  836. ast_str_append(&string, 0, "%s/", transport_string);
  837. }
  838. }
  839. ast_str_append(&string, 0, "%s", ast_sockaddr_stringify_addr(addr));
  840. ast_str_append(&string, 0, "/%s", ast_sockaddr_stringify_port(addr));
  841. return ast_json_string_create(ast_str_buffer(string));
  842. }
  843. void ast_json_init(void)
  844. {
  845. /* Setup to use Asterisk custom allocators */
  846. ast_json_reset_alloc_funcs();
  847. }
  848. static void json_payload_destructor(void *obj)
  849. {
  850. struct ast_json_payload *payload = obj;
  851. ast_json_unref(payload->json);
  852. }
  853. struct ast_json_payload *ast_json_payload_create(struct ast_json *json)
  854. {
  855. struct ast_json_payload *payload;
  856. if (!(payload = ao2_alloc(sizeof(*payload), json_payload_destructor))) {
  857. return NULL;
  858. }
  859. ast_json_ref(json);
  860. payload->json = json;
  861. return payload;
  862. }
  863. static struct ast_json *json_party_number(struct ast_party_number *number)
  864. {
  865. if (!number->valid) {
  866. return NULL;
  867. }
  868. return ast_json_pack("{s: s, s: i, s: i, s: s}",
  869. "number", AST_JSON_UTF8_VALIDATE(number->str),
  870. "plan", number->plan,
  871. "presentation", number->presentation,
  872. "presentation_txt", ast_describe_caller_presentation(number->presentation));
  873. }
  874. static struct ast_json *json_party_name(struct ast_party_name *name)
  875. {
  876. if (!name->valid) {
  877. return NULL;
  878. }
  879. return ast_json_pack("{s: s, s: s, s: i, s: s}",
  880. "name", AST_JSON_UTF8_VALIDATE(name->str),
  881. "character_set", ast_party_name_charset_describe(name->char_set),
  882. "presentation", name->presentation,
  883. "presentation_txt", ast_describe_caller_presentation(name->presentation));
  884. }
  885. static struct ast_json *json_party_subaddress(struct ast_party_subaddress *subaddress)
  886. {
  887. if (!subaddress->valid) {
  888. return NULL;
  889. }
  890. return ast_json_pack("{s: s, s: i, s: b}",
  891. "subaddress", AST_JSON_UTF8_VALIDATE(subaddress->str),
  892. "type", subaddress->type,
  893. "odd", subaddress->odd_even_indicator);
  894. }
  895. struct ast_json *ast_json_party_id(struct ast_party_id *party)
  896. {
  897. RAII_VAR(struct ast_json *, json_party_id, NULL, ast_json_unref);
  898. int pres;
  899. /* Combined party presentation */
  900. pres = ast_party_id_presentation(party);
  901. json_party_id = ast_json_pack("{s: i, s: s}",
  902. "presentation", pres,
  903. "presentation_txt", ast_describe_caller_presentation(pres));
  904. if (!json_party_id) {
  905. return NULL;
  906. }
  907. /* Party number */
  908. if (party->number.valid
  909. && ast_json_object_set(json_party_id, "number", json_party_number(&party->number))) {
  910. return NULL;
  911. }
  912. /* Party name */
  913. if (party->name.valid
  914. && ast_json_object_set(json_party_id, "name", json_party_name(&party->name))) {
  915. return NULL;
  916. }
  917. /* Party subaddress */
  918. if (party->subaddress.valid
  919. && ast_json_object_set(json_party_id, "subaddress", json_party_subaddress(&party->subaddress))) {
  920. return NULL;
  921. }
  922. return ast_json_ref(json_party_id);
  923. }
  924. enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
  925. {
  926. struct ast_json_iter *it_json_var;
  927. struct ast_variable *tail = NULL;
  928. *variables = NULL;
  929. for (it_json_var = ast_json_object_iter(json_variables); it_json_var;
  930. it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) {
  931. struct ast_variable *new_var;
  932. const char *key = ast_json_object_iter_key(it_json_var);
  933. const char *value;
  934. struct ast_json *json_value;
  935. if (ast_strlen_zero(key)) {
  936. continue;
  937. }
  938. json_value = ast_json_object_iter_value(it_json_var);
  939. if (ast_json_typeof(json_value) != AST_JSON_STRING) {
  940. /* Error: Only strings allowed */
  941. ast_variables_destroy(*variables);
  942. *variables = NULL;
  943. return AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE;
  944. }
  945. value = ast_json_string_get(json_value);
  946. /* Should never be NULL. Otherwise, how could it be a string type? */
  947. ast_assert(value != NULL);
  948. if (!value) {
  949. /* To be safe. */
  950. continue;
  951. }
  952. new_var = ast_variable_new(key, value, "");
  953. if (!new_var) {
  954. /* Error: OOM */
  955. ast_variables_destroy(*variables);
  956. *variables = NULL;
  957. return AST_JSON_TO_AST_VARS_CODE_OOM;
  958. }
  959. tail = ast_variable_list_append_hint(variables, tail, new_var);
  960. }
  961. return AST_JSON_TO_AST_VARS_CODE_SUCCESS;
  962. }