summaryrefslogtreecommitdiffstats
path: root/src/jplist.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2026-05-22 18:46:02 +0200
committerGravatar Nikias Bassen2026-05-22 18:46:02 +0200
commit9711459dbed7d60bb00c7d2c052623e8489c88e1 (patch)
tree550cceb133bbff047ad5b8d7e0334596b252f7f2 /src/jplist.c
parent389fab9a07baf3913c4214425e86cca588d559a1 (diff)
downloadlibplist-9711459dbed7d60bb00c7d2c052623e8489c88e1.tar.gz
libplist-9711459dbed7d60bb00c7d2c052623e8489c88e1.tar.bz2
refactor: centralize formatting helpers and harden out-plutil
Diffstat (limited to 'src/jplist.c')
-rw-r--r--src/jplist.c68
1 files changed, 3 insertions, 65 deletions
diff --git a/src/jplist.c b/src/jplist.c
index 410d4b3..cc1cd1b 100644
--- a/src/jplist.c
+++ b/src/jplist.c
@@ -41,8 +41,7 @@
41#include "hashtable.h" 41#include "hashtable.h"
42#include "base64.h" 42#include "base64.h"
43#include "time64.h" 43#include "time64.h"
44 44#include "common.h"
45#define MAC_EPOCH 978307200
46 45
47#ifdef DEBUG 46#ifdef DEBUG
48static int plist_json_debug = 0; 47static int plist_json_debug = 0;
@@ -95,30 +94,6 @@ static char* strndup(const char* str, size_t len)
95#endif 94#endif
96#endif 95#endif
97 96
98static size_t dtostr(char *buf, size_t bufsize, double realval)
99{
100 size_t len = 0;
101 if (isnan(realval)) {
102 len = snprintf(buf, bufsize, "nan");
103 } else if (isinf(realval)) {
104 len = snprintf(buf, bufsize, "%cinfinity", (realval > 0.0) ? '+' : '-');
105 } else if (realval == 0.0f) {
106 len = snprintf(buf, bufsize, "0.0");
107 } else {
108 size_t i = 0;
109 len = snprintf(buf, bufsize, "%.*g", 17, realval);
110 for (i = 0; buf && i < len; i++) {
111 if (buf[i] == ',') {
112 buf[i] = '.';
113 break;
114 } else if (buf[i] == '.') {
115 break;
116 }
117 }
118 }
119 return len;
120}
121
122static plist_err_t node_to_json(node_t node, bytearray_t **outbuf, uint32_t depth, int prettify, int coerce) 97static plist_err_t node_to_json(node_t node, bytearray_t **outbuf, uint32_t depth, int prettify, int coerce)
123{ 98{
124 plist_data_t node_data = NULL; 99 plist_data_t node_data = NULL;
@@ -325,44 +300,6 @@ static plist_err_t node_to_json(node_t node, bytearray_t **outbuf, uint32_t dept
325 return PLIST_ERR_SUCCESS; 300 return PLIST_ERR_SUCCESS;
326} 301}
327 302
328#define PO10i_LIMIT (INT64_MAX/10)
329
330/* based on https://stackoverflow.com/a/4143288 */
331static int num_digits_i(int64_t i)
332{
333 int n;
334 int64_t po10;
335 n=1;
336 if (i < 0) {
337 i = (i == INT64_MIN) ? INT64_MAX : -i;
338 n++;
339 }
340 po10=10;
341 while (i>=po10) {
342 n++;
343 if (po10 > PO10i_LIMIT) break;
344 po10*=10;
345 }
346 return n;
347}
348
349#define PO10u_LIMIT (UINT64_MAX/10)
350
351/* based on https://stackoverflow.com/a/4143288 */
352static int num_digits_u(uint64_t i)
353{
354 int n;
355 uint64_t po10;
356 n=1;
357 po10=10;
358 while (i>=po10) {
359 n++;
360 if (po10 > PO10u_LIMIT) break;
361 po10*=10;
362 }
363 return n;
364}
365
366static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify, int coerce, hashtable_t *visited) 303static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify, int coerce, hashtable_t *visited)
367{ 304{
368 plist_data_t data; 305 plist_data_t data;
@@ -556,6 +493,7 @@ typedef struct {
556 493
557static int64_t parse_decimal(const char* str, const char* str_end, char** endp) 494static int64_t parse_decimal(const char* str, const char* str_end, char** endp)
558{ 495{
496 const uint64_t po10i_limit = INT64_MAX / 10;
559 uint64_t MAX = INT64_MAX; 497 uint64_t MAX = INT64_MAX;
560 uint64_t x = 0; 498 uint64_t x = 0;
561 int is_neg = 0; 499 int is_neg = 0;
@@ -571,7 +509,7 @@ static int64_t parse_decimal(const char* str, const char* str_end, char** endp)
571 MAX++; 509 MAX++;
572 } 510 }
573 while (*endp < str_end && isdigit(**endp)) { 511 while (*endp < str_end && isdigit(**endp)) {
574 if (x > PO10i_LIMIT) { 512 if (x > po10i_limit) {
575 x = MAX; 513 x = MAX;
576 break; 514 break;
577 } 515 }