summaryrefslogtreecommitdiffstats
path: root/src/out-plutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/out-plutil.c')
-rw-r--r--src/out-plutil.c148
1 files changed, 63 insertions, 85 deletions
diff --git a/src/out-plutil.c b/src/out-plutil.c
index bf9e72e..9f7968e 100644
--- a/src/out-plutil.c
+++ b/src/out-plutil.c
@@ -39,46 +39,24 @@
#include "strbuf.h"
#include "time64.h"
#include "hashtable.h"
-
-#define MAC_EPOCH 978307200
-
-static size_t dtostr(char *buf, size_t bufsize, double realval)
-{
- size_t len = 0;
- if (isnan(realval)) {
- len = snprintf(buf, bufsize, "nan");
- } else if (isinf(realval)) {
- len = snprintf(buf, bufsize, "%cinfinity", (realval > 0.0) ? '+' : '-');
- } else if (realval == 0.0f) {
- len = snprintf(buf, bufsize, "0.0");
- } else {
- size_t i = 0;
- len = snprintf(buf, bufsize, "%.*g", 17, realval);
- for (i = 0; buf && i < len; i++) {
- if (buf[i] == ',') {
- buf[i] = '.';
- break;
- } else if (buf[i] == '.') {
- break;
- }
- }
- }
- return len;
-}
+#include "common.h"
static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t depth)
{
plist_data_t node_data = NULL;
char *val = NULL;
+ int slen = 0;
size_t val_len = 0;
- uint32_t i = 0;
-
- if (!node)
+ if (!node || !outbuf || !*outbuf) {
return PLIST_ERR_INVALID_ARG;
+ }
node_data = plist_get_data(node);
+ if (!node_data) {
+ return PLIST_ERR_INVALID_ARG;
+ }
switch (node_data->type)
{
@@ -98,17 +76,24 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
case PLIST_INT:
val = (char*)malloc(64);
+ if (!val) return PLIST_ERR_NO_MEM;
if (node_data->length == 16) {
- val_len = snprintf(val, 64, "%" PRIu64, node_data->intval);
+ slen = snprintf(val, 64, "%" PRIu64, node_data->intval);
} else {
- val_len = snprintf(val, 64, "%" PRIi64, node_data->intval);
+ slen = snprintf(val, 64, "%" PRIi64, node_data->intval);
+ }
+ if (slen < 0) {
+ free(val);
+ return PLIST_ERR_UNKNOWN;
}
+ val_len = (size_t)slen;
str_buf_append(*outbuf, val, val_len);
free(val);
break;
case PLIST_REAL:
val = (char*)malloc(64);
+ if (!val) return PLIST_ERR_NO_MEM;
val_len = dtostr(val, 64, node_data->realval);
str_buf_append(*outbuf, val, val_len);
free(val);
@@ -116,6 +101,9 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
case PLIST_STRING:
case PLIST_KEY: {
+ if (!node_data->strval && node_data->length > 0) {
+ return PLIST_ERR_INVALID_ARG;
+ }
const char *charmap[32] = {
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
"\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f",
@@ -124,8 +112,8 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
};
size_t j = 0;
size_t len = 0;
- off_t start = 0;
- off_t cur = 0;
+ size_t start = 0;
+ size_t cur = 0;
str_buf_append(*outbuf, "\"", 1);
@@ -152,14 +140,18 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
str_buf_append(*outbuf, "[", 1);
node_t ch;
uint32_t cnt = 0;
+ uint32_t i;
for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
str_buf_append(*outbuf, "\n", 1);
for (i = 0; i <= depth; i++) {
str_buf_append(*outbuf, " ", 2);
}
char indexbuf[16];
- int l = sprintf(indexbuf, "%u => ", cnt);
- str_buf_append(*outbuf, indexbuf, l);
+ slen = snprintf(indexbuf, sizeof(indexbuf), "%u => ", cnt);
+ if (slen < 0) {
+ return PLIST_ERR_UNKNOWN;
+ }
+ str_buf_append(*outbuf, indexbuf, (size_t)slen);
plist_err_t res = node_to_string(ch, outbuf, depth+1);
if (res < 0) {
return res;
@@ -178,6 +170,7 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
str_buf_append(*outbuf, "{", 1);
node_t ch;
uint32_t cnt = 0;
+ uint32_t i;
for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
if (cnt % 2 == 0) {
str_buf_append(*outbuf, "\n", 1);
@@ -204,27 +197,36 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
} break;
case PLIST_DATA:
{
+ if (!node_data->buff && node_data->length > 0) {
+ return PLIST_ERR_INVALID_ARG;
+ }
val = (char*)calloc(1, 48);
+ if (!val) return PLIST_ERR_NO_MEM;
size_t len = node_data->length;
- size_t slen = snprintf(val, 48, "{length = %" PRIu64 ", bytes = 0x", (uint64_t)len);
- str_buf_append(*outbuf, val, slen);
+ slen = snprintf(val, 48, "{length = %" PRIu64 ", bytes = 0x", (uint64_t)len);
+ if (slen < 0) {
+ free(val);
+ return PLIST_ERR_UNKNOWN;
+ }
+ str_buf_append(*outbuf, val, (size_t)slen);
+ size_t j;
if (len <= 24) {
- for (i = 0; i < len; i++) {
- sprintf(val, "%02x", (unsigned char)node_data->buff[i]);
+ for (j = 0; j < len; j++) {
+ snprintf(val, 4, "%02x", (unsigned char)node_data->buff[j]);
str_buf_append(*outbuf, val, 2);
}
} else {
- for (i = 0; i < 16; i++) {
- if (i > 0 && (i % 4 == 0))
+ for (j = 0; j < 16; j++) {
+ if (j > 0 && (j % 4 == 0))
str_buf_append(*outbuf, " ", 1);
- sprintf(val, "%02x", (unsigned char)node_data->buff[i]);
+ snprintf(val, 4, "%02x", (unsigned char)node_data->buff[j]);
str_buf_append(*outbuf, val, 2);
}
str_buf_append(*outbuf, " ... ", 5);
- for (i = len - 8; i < len; i++) {
- sprintf(val, "%02x", (unsigned char)node_data->buff[i]);
+ for (j = len - 8; j < len; j++) {
+ snprintf(val, 4, "%02x", (unsigned char)node_data->buff[j]);
str_buf_append(*outbuf, val, 2);
- if (i > 0 && (i % 4 == 0))
+ if (j > 0 && (j % 4 == 0))
str_buf_append(*outbuf, " ", 1);
}
}
@@ -240,6 +242,7 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
struct TM *btime = gmtime64_r(&timev, &_btime);
if (btime) {
val = (char*)calloc(1, 26);
+ if (!val) return PLIST_ERR_NO_MEM;
struct tm _tmcopy;
copy_TM64_to_tm(btime, &_tmcopy);
val_len = strftime(val, 26, "%Y-%m-%d %H:%M:%S +0000", &_tmcopy);
@@ -253,11 +256,24 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
break;
case PLIST_UID:
{
- val = (char*)malloc(88);
- val_len = sprintf(val, "<CFKeyedArchiverUID %p [%p]>{value = %" PRIu64 "}", node, node_data, node_data->intval);
+#define UID_FMT "<CFKeyedArchiverUID %p [%p]>{value = %" PRIu64 "}"
+ slen = snprintf(NULL, 0, UID_FMT, node, node_data, node_data->intval);
+ if (slen < 0) {
+ return PLIST_ERR_UNKNOWN;
+ }
+ val_len = (size_t)slen;
+ val = (char*)malloc(val_len + 1);
+ if (!val) return PLIST_ERR_NO_MEM;
+ slen = snprintf(val, val_len+1, UID_FMT, node, node_data, node_data->intval);
+ if (slen < 0 || (size_t)slen > val_len) {
+ free(val);
+ return PLIST_ERR_UNKNOWN;
+ }
+ val_len = (size_t)slen;
str_buf_append(*outbuf, val, val_len);
free(val);
val = NULL;
+#undef UID_FMT
}
break;
default:
@@ -267,44 +283,6 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de
return PLIST_ERR_SUCCESS;
}
-#define PO10i_LIMIT (INT64_MAX/10)
-
-/* based on https://stackoverflow.com/a/4143288 */
-static int num_digits_i(int64_t i)
-{
- int n;
- int64_t po10;
- n=1;
- if (i < 0) {
- i = (i == INT64_MIN) ? INT64_MAX : -i;
- n++;
- }
- po10=10;
- while (i>=po10) {
- n++;
- if (po10 > PO10i_LIMIT) break;
- po10*=10;
- }
- return n;
-}
-
-#define PO10u_LIMIT (UINT64_MAX/10)
-
-/* based on https://stackoverflow.com/a/4143288 */
-static int num_digits_u(uint64_t i)
-{
- int n;
- uint64_t po10;
- n=1;
- po10=10;
- while (i>=po10) {
- n++;
- if (po10 > PO10u_LIMIT) break;
- po10*=10;
- }
- return n;
-}
-
static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, hashtable_t *visited)
{
plist_data_t data;