You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

json-master.patches 14 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. commit ea817e4eb61c4ff834ecf198c4a3bdfa4745841b
  2. Author: Lauri Jakku <lja@iki.fi>
  3. Date: Thu Dec 19 07:19:23 2019 +0200
  4. Optimization to default
  5. diff --git a/json_object.c b/json_object.c
  6. index d44754b..4b5a70b 100644
  7. --- a/json_object.c
  8. +++ b/json_object.c
  9. @@ -10,7 +10,7 @@
  10. *
  11. */
  12. -#pragma GCC optimize ("O0")
  13. +//#pragma GCC optimize ("O0")
  14. #include "config.h"
  15. commit 79a37997c74c2437b9f202aeb693f878752790be
  16. Author: Lauri Jakku <lja@iki.fi>
  17. Date: Thu Dec 19 00:02:28 2019 +0200
  18. stringdup bug fix
  19. diff --git a/json_object.c b/json_object.c
  20. index 86fd692..d44754b 100644
  21. --- a/json_object.c
  22. +++ b/json_object.c
  23. @@ -485,7 +485,7 @@ static char *stringdup(const char *s)
  24. return NULL;
  25. new[len] = 0;
  26. - return (char *) memcpy (new, s, len-1);
  27. + return (char *) memcpy (new, s, len);
  28. }
  29. commit b9f22447479419745b9b865ff4303eb6f361a970
  30. Author: Lauri Jakku <lja@iki.fi>
  31. Date: Wed Dec 18 05:52:52 2019 +0200
  32. Few segfaults away
  33. diff --git a/json_object.c b/json_object.c
  34. index 18b3bd5..86fd692 100644
  35. --- a/json_object.c
  36. +++ b/json_object.c
  37. @@ -219,14 +219,16 @@ static void json_object_generic_delete(struct json_object* jso)
  38. lh_table_delete(json_object_table, jso);
  39. #endif /* REFCOUNT_DEBUG */
  40. printbuf_free(jso->_pb);
  41. + jso->_pb = NULL;
  42. free(jso);
  43. + jso= NULL;
  44. }
  45. static struct json_object* json_object_new(enum json_type o_type)
  46. {
  47. struct json_object *jso;
  48. - jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
  49. + jso = (struct json_object*)calloc(1, sizeof(struct json_object));
  50. if (!jso)
  51. return NULL;
  52. jso->o_type = o_type;
  53. @@ -474,6 +476,19 @@ struct lh_table* json_object_get_object(const struct json_object *jso)
  54. }
  55. }
  56. +static char *stringdup(const char *s)
  57. +{
  58. + size_t len = strnlen (s, 1024) + 1;
  59. + char *new = malloc (len);
  60. +
  61. + if (new == NULL)
  62. + return NULL;
  63. +
  64. + new[len] = 0;
  65. + return (char *) memcpy (new, s, len-1);
  66. +}
  67. +
  68. +
  69. int json_object_object_add_ex(struct json_object* jso,
  70. const char *const key,
  71. struct json_object *const val,
  72. @@ -488,9 +503,9 @@ int json_object_object_add_ex(struct json_object* jso,
  73. // We lookup the entry and replace the value, rather than just deleting
  74. // and re-adding it, so the existing key remains valid.
  75. hash = lh_get_hash(jso->o.c_object, (const void *)key);
  76. - existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ? NULL :
  77. - lh_table_lookup_entry_w_hash(jso->o.c_object,
  78. - (const void *)key, hash);
  79. + existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ?
  80. + NULL :
  81. + lh_table_lookup_entry_w_hash(jso->o.c_object, (const void *)key, hash);
  82. // The caller must avoid creating loops in the object tree, but do a
  83. // quick check anyway to make sure we're not creating a trivial loop.
  84. @@ -499,17 +514,26 @@ int json_object_object_add_ex(struct json_object* jso,
  85. if (!existing_entry)
  86. {
  87. - const void *const k = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ?
  88. - (const void *)key : strdup(key);
  89. + char *key_dup = stringdup(key);
  90. +
  91. + /* key duplicate must be done first */
  92. + const void *const k = ((opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ? (const void *)key : (const void *)key_dup);
  93. +
  94. + /* key duplicate must be freed here if constant */
  95. + if (opts & JSON_C_OBJECT_KEY_IS_CONSTANT)
  96. + free(key_dup);
  97. +
  98. if (k == NULL)
  99. return -1;
  100. +
  101. return lh_table_insert_w_hash(jso->o.c_object, k, val, hash, opts);
  102. + } else {
  103. + existing_value = (json_object *) lh_entry_v(existing_entry);
  104. + if (existing_value)
  105. + json_object_put(existing_value);
  106. + existing_entry->v = val;
  107. + return 0;
  108. }
  109. - existing_value = (json_object *) lh_entry_v(existing_entry);
  110. - if (existing_value)
  111. - json_object_put(existing_value);
  112. - existing_entry->v = val;
  113. - return 0;
  114. }
  115. int json_object_object_add(struct json_object* jso, const char *key,
  116. diff --git a/linkhash.c b/linkhash.c
  117. index f324a10..3e65302 100644
  118. --- a/linkhash.c
  119. +++ b/linkhash.c
  120. @@ -563,7 +563,9 @@ void lh_table_free(struct lh_table *t)
  121. t->free_fn(c);
  122. }
  123. free(t->table);
  124. + t->table = NULL;
  125. free(t);
  126. + t = NULL;
  127. }
  128. diff --git a/printbuf.c b/printbuf.c
  129. index 3f87f77..3fb8e4b 100644
  130. --- a/printbuf.c
  131. +++ b/printbuf.c
  132. @@ -71,7 +71,8 @@ static int printbuf_extend(struct printbuf *p, int min_size)
  133. int new_size;
  134. if(
  135. - (p != NULL) &&
  136. + (p != NULL) &&
  137. + (p->buf != NULL) &&
  138. (p->size >= min_size)
  139. )
  140. return 0;
  141. @@ -87,18 +88,17 @@ static int printbuf_extend(struct printbuf *p, int min_size)
  142. p->bpos, min_size, p->size, new_size);
  143. #endif /* PRINTBUF_DEBUG */
  144. - if(
  145. - (p != NULL) &&
  146. - (p->buf != NULL)
  147. - )
  148. + if (p != NULL)
  149. {
  150. t = (char*)calloc(1, new_size);
  151. - if (t != NULL) {
  152. + if ( (t != NULL) &&
  153. + (p->buf != NULL))
  154. + {
  155. memcpy(t, p->buf, p->size);
  156. }
  157. }
  158. - if(t == NULL)
  159. + if (t == NULL)
  160. return -1;
  161. p->size = new_size;
  162. @@ -109,9 +109,17 @@ static int printbuf_extend(struct printbuf *p, int min_size)
  163. int printbuf_memappend(struct printbuf *p, const char *buf, int size)
  164. {
  165. +
  166. + if ( (p->size > 0) && (p->buf == NULL)) {
  167. + int size_wanted = p->size;
  168. + p->size = 0;
  169. + if (printbuf_extend(p, size_wanted) < 0)
  170. + return -1;
  171. + }
  172. +
  173. if (p->size <= p->bpos + size + 1) {
  174. - if (printbuf_extend(p, p->bpos + size + 1) < 0)
  175. - return -1;
  176. + if (printbuf_extend(p, p->bpos + size + 1) < 0)
  177. + return -2;
  178. }
  179. memcpy(p->buf + p->bpos, buf, size);
  180. p->bpos += size;
  181. @@ -172,7 +180,10 @@ void printbuf_reset(struct printbuf *p)
  182. {
  183. if (p != NULL)
  184. {
  185. - if ( (p->size > 0) && (p->buf != NULL) ) {
  186. + if ( (p->size > 0) &&
  187. + (p->buf != NULL)
  188. + )
  189. + {
  190. p->buf[0] = '\0';
  191. }
  192. @@ -183,8 +194,12 @@ void printbuf_reset(struct printbuf *p)
  193. void printbuf_free(struct printbuf *p)
  194. {
  195. if(p) {
  196. - free(p->buf);
  197. +
  198. + if (p->buf != NULL)
  199. + free(p->buf);
  200. +
  201. p->buf = NULL;
  202. +
  203. free(p);
  204. p = NULL;
  205. }
  206. commit 827255a466d2d366bc3c68f90486dd5069341638
  207. Author: Lauri Jakku <lja@iki.fi>
  208. Date: Wed Dec 18 00:26:34 2019 +0200
  209. Tweaks & modifications
  210. diff --git a/json_object.c b/json_object.c
  211. index 74d5266..18b3bd5 100644
  212. --- a/json_object.c
  213. +++ b/json_object.c
  214. @@ -10,6 +10,8 @@
  215. *
  216. */
  217. +#pragma GCC optimize ("O0")
  218. +
  219. #include "config.h"
  220. #include "strerror_override.h"
  221. @@ -143,16 +145,13 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl
  222. default:
  223. if(c < ' ')
  224. {
  225. - char sbuf[7];
  226. if(pos - start_offset > 0)
  227. printbuf_memappend(pb,
  228. str + start_offset,
  229. pos - start_offset);
  230. - snprintf(sbuf, sizeof(sbuf),
  231. - "\\u00%c%c",
  232. - json_hex_chars[c >> 4],
  233. - json_hex_chars[c & 0xf]);
  234. - printbuf_memappend_fast(pb, sbuf, (int) sizeof(sbuf) - 1);
  235. + sprintbuf(pb, "\\u00%c%c",
  236. + json_hex_chars[c >> 4],
  237. + json_hex_chars[c & 0xf]);
  238. start_offset = ++pos;
  239. } else
  240. pos++;
  241. @@ -325,24 +324,30 @@ const char* json_object_to_json_string_length(struct json_object *jso, int flags
  242. const char *r = NULL;
  243. size_t s = 0;
  244. - if (!jso)
  245. - {
  246. - s = 4;
  247. - r = "null";
  248. - }
  249. - else if ((jso->_pb) || (jso->_pb = printbuf_new()))
  250. + /* Failure case set first */
  251. + s = 4;
  252. + r = "null";
  253. +
  254. + if (jso)
  255. {
  256. - printbuf_reset(jso->_pb);
  257. + if ( jso->_pb == NULL )
  258. + jso->_pb = printbuf_new();
  259. - if(jso->_to_json_string(jso, jso->_pb, 0, flags) >= 0)
  260. + if ( jso->_pb != NULL )
  261. {
  262. - s = (size_t)jso->_pb->bpos;
  263. - r = jso->_pb->buf;
  264. + printbuf_reset(jso->_pb);
  265. +
  266. + if(jso->_to_json_string(jso, jso->_pb, 0, flags) >= 0)
  267. + {
  268. + s = (size_t)jso->_pb->bpos;
  269. + r = jso->_pb->buf;
  270. + }
  271. }
  272. }
  273. if (length)
  274. *length = s;
  275. +
  276. return r;
  277. }
  278. @@ -400,10 +405,12 @@ static int json_object_object_to_json_string(struct json_object* jso,
  279. indent(pb, level+1, flags);
  280. printbuf_strappend(pb, "\"");
  281. json_escape_str(pb, iter.key, strlen(iter.key), flags);
  282. +
  283. if (flags & JSON_C_TO_STRING_SPACED)
  284. printbuf_strappend(pb, "\": ");
  285. else
  286. printbuf_strappend(pb, "\":");
  287. +
  288. if(iter.val == NULL)
  289. printbuf_strappend(pb, "null");
  290. else
  291. @@ -1428,7 +1435,7 @@ static int json_object_deep_copy_recursive(struct json_object *src, struct json_
  292. if (shallow_copy_rc < 1)
  293. {
  294. errno = EINVAL;
  295. - return -1;
  296. + return -120;
  297. }
  298. assert(*dst != NULL);
  299. @@ -1442,13 +1449,13 @@ static int json_object_deep_copy_recursive(struct json_object *src, struct json_
  300. else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso, shallow_copy) < 0)
  301. {
  302. json_object_put(jso);
  303. - return -1;
  304. + return -130;
  305. }
  306. if (json_object_object_add(*dst, iter.key, jso) < 0)
  307. {
  308. json_object_put(jso);
  309. - return -1;
  310. + return -140;
  311. }
  312. }
  313. break;
  314. @@ -1464,13 +1471,13 @@ static int json_object_deep_copy_recursive(struct json_object *src, struct json_
  315. else if (json_object_deep_copy_recursive(jso1, src, NULL, ii, &jso, shallow_copy) < 0)
  316. {
  317. json_object_put(jso);
  318. - return -1;
  319. + return -150;
  320. }
  321. if (json_object_array_add(*dst, jso) < 0)
  322. {
  323. json_object_put(jso);
  324. - return -1;
  325. + return -160;
  326. }
  327. }
  328. break;
  329. @@ -1491,9 +1498,17 @@ int json_object_deep_copy(struct json_object *src, struct json_object **dst, jso
  330. int rc;
  331. /* Check if arguments are sane ; *dst must not point to a non-NULL object */
  332. - if (!src || !dst || *dst) {
  333. + if (!src) {
  334. errno = EINVAL;
  335. - return -1;
  336. + return -101;
  337. + }
  338. + if (!dst) {
  339. + errno = EINVAL;
  340. + return -102;
  341. + }
  342. + if (*dst) {
  343. + errno = EINVAL;
  344. + return -103;
  345. }
  346. if (shallow_copy == NULL)
  347. @@ -1501,6 +1516,7 @@ int json_object_deep_copy(struct json_object *src, struct json_object **dst, jso
  348. rc = json_object_deep_copy_recursive(src, NULL, NULL, -1, dst, shallow_copy);
  349. if (rc < 0) {
  350. +
  351. json_object_put(*dst);
  352. *dst = NULL;
  353. }
  354. diff --git a/printbuf.c b/printbuf.c
  355. index 6c77b5d..3f87f77 100644
  356. --- a/printbuf.c
  357. +++ b/printbuf.c
  358. @@ -13,6 +13,10 @@
  359. * (http://www.opensource.org/licenses/mit-license.php)
  360. */
  361. +#define PRINTBUF_DEBUG 1
  362. +
  363. +#pragma GCC optimize ("O0")
  364. +
  365. #include "config.h"
  366. #include <stdio.h>
  367. @@ -30,6 +34,8 @@
  368. #include "snprintf_compat.h"
  369. #include "vasprintf_compat.h"
  370. +#define PRINTBUF_DEFAULT_SIZE (256)
  371. +
  372. static int printbuf_extend(struct printbuf *p, int min_size);
  373. struct printbuf* printbuf_new(void)
  374. @@ -38,9 +44,10 @@ struct printbuf* printbuf_new(void)
  375. p = (struct printbuf*)calloc(1, sizeof(struct printbuf));
  376. if(!p) return NULL;
  377. - p->size = 32;
  378. + p->size = PRINTBUF_DEFAULT_SIZE;
  379. p->bpos = 0;
  380. - if(!(p->buf = (char*)malloc(p->size))) {
  381. + p->buf = (char*)calloc(1, p->size);
  382. + if(p->buf == NULL) {
  383. free(p);
  384. return NULL;
  385. }
  386. @@ -59,24 +66,44 @@ struct printbuf* printbuf_new(void)
  387. */
  388. static int printbuf_extend(struct printbuf *p, int min_size)
  389. {
  390. - char *t;
  391. +#define PRINTBUF_EXTEND_BY_BYTES_MIN (8)
  392. + char *t = NULL;
  393. int new_size;
  394. - if (p->size >= min_size)
  395. + if(
  396. + (p != NULL) &&
  397. + (p->size >= min_size)
  398. + )
  399. return 0;
  400. new_size = p->size * 2;
  401. - if (new_size < min_size + 8)
  402. - new_size = min_size + 8;
  403. +
  404. + if (new_size < (min_size + PRINTBUF_EXTEND_BY_BYTES_MIN))
  405. + new_size = min_size + PRINTBUF_EXTEND_BY_BYTES_MIN;
  406. +
  407. #ifdef PRINTBUF_DEBUG
  408. MC_DEBUG("printbuf_memappend: realloc "
  409. "bpos=%d min_size=%d old_size=%d new_size=%d\n",
  410. p->bpos, min_size, p->size, new_size);
  411. #endif /* PRINTBUF_DEBUG */
  412. - if(!(t = (char*)realloc(p->buf, new_size)))
  413. +
  414. + if(
  415. + (p != NULL) &&
  416. + (p->buf != NULL)
  417. + )
  418. + {
  419. + t = (char*)calloc(1, new_size);
  420. + if (t != NULL) {
  421. + memcpy(t, p->buf, p->size);
  422. + }
  423. + }
  424. +
  425. + if(t == NULL)
  426. return -1;
  427. +
  428. p->size = new_size;
  429. p->buf = t;
  430. +
  431. return 0;
  432. }
  433. @@ -116,20 +143,21 @@ int sprintbuf(struct printbuf *p, const char *msg, ...)
  434. {
  435. va_list ap;
  436. char *t;
  437. - int size;
  438. - char buf[128];
  439. + long int size;
  440. +#define PRINTBUF_DEFAULT_SIZE_BUF ((PRINTBUF_DEFAULT_SIZE<<2) > +1)
  441. + char buf[PRINTBUF_DEFAULT_SIZE_BUF];
  442. /* user stack buffer first */
  443. va_start(ap, msg);
  444. - size = vsnprintf(buf, 128, msg, ap);
  445. + size = (long int)vsnprintf(buf, sizeof(buf), msg, ap);
  446. va_end(ap);
  447. /* if string is greater than stack buffer, then use dynamic string
  448. with vasprintf. Note: some implementation of vsnprintf return -1
  449. if output is truncated whereas some return the number of bytes that
  450. would have been written - this code handles both cases. */
  451. - if(size == -1 || size > 127) {
  452. + if(size == -1 || size > (long int)sizeof(buf)) {
  453. va_start(ap, msg);
  454. - if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
  455. + if((size = (long int)vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
  456. va_end(ap);
  457. printbuf_memappend(p, t, size);
  458. free(t);
  459. @@ -142,14 +170,22 @@ int sprintbuf(struct printbuf *p, const char *msg, ...)
  460. void printbuf_reset(struct printbuf *p)
  461. {
  462. - p->buf[0] = '\0';
  463. - p->bpos = 0;
  464. + if (p != NULL)
  465. + {
  466. + if ( (p->size > 0) && (p->buf != NULL) ) {
  467. + p->buf[0] = '\0';
  468. + }
  469. +
  470. + p->bpos = 0;
  471. + }
  472. }
  473. void printbuf_free(struct printbuf *p)
  474. {
  475. if(p) {
  476. free(p->buf);
  477. + p->buf = NULL;
  478. free(p);
  479. + p = NULL;
  480. }
  481. }
  482. diff --git a/tests/test_printbuf.c b/tests/test_printbuf.c
  483. index 06dd13d..19064b5 100644
  484. --- a/tests/test_printbuf.c
  485. +++ b/tests/test_printbuf.c
  486. @@ -159,6 +159,42 @@ static void test_sprintbuf(int before_resize)
  487. printf("%s: end test\n", __func__);
  488. }
  489. +static void test_sprintbuf(int before_resize);
  490. +static void test_sprintbuf(int before_resize)
  491. +{
  492. + struct printbuf *pb;
  493. +
  494. + printf("%s: starting test\n", __func__);
  495. + pb = printbuf_new();
  496. + printf("Buffer length: %d\n", printbuf_length(pb));
  497. +
  498. + char *data = malloc(before_resize + 1 + 1);
  499. + memset(data, 'X', before_resize + 1 + 1);
  500. + data[before_resize + 1] = '\0';
  501. + sprintbuf(pb, "%s", data);
  502. + free(data);
  503. + printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf));
  504. +
  505. + printbuf_reset(pb);
  506. + sprintbuf(pb, "plain");
  507. + printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
  508. +
  509. + sprintbuf(pb, "%d", 1);
  510. + printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
  511. +
  512. + sprintbuf(pb, "%d", INT_MAX);
  513. + printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
  514. +
  515. + sprintbuf(pb, "%d", INT_MIN);
  516. + printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
  517. +
  518. + sprintbuf(pb, "%s", "%s");
  519. + printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
  520. +
  521. + printbuf_free(pb);
  522. + printf("%s: end test\n", __func__);
  523. +}
  524. +
  525. int main(int argc, char **argv)
  526. {
  527. int before_resize = 0;