diff options
| -rw-r--r-- | src/out-default.c | 86 |
1 files changed, 63 insertions, 23 deletions
diff --git a/src/out-default.c b/src/out-default.c index fb57bcf..676a677 100644 --- a/src/out-default.c +++ b/src/out-default.c | |||
| @@ -44,17 +44,27 @@ | |||
| 44 | 44 | ||
| 45 | static size_t dtostr(char *buf, size_t bufsize, double realval) | 45 | static size_t dtostr(char *buf, size_t bufsize, double realval) |
| 46 | { | 46 | { |
| 47 | size_t len = 0; | 47 | int slen = 0; |
| 48 | if (isnan(realval)) { | 48 | if (isnan(realval)) { |
| 49 | len = snprintf(buf, bufsize, "nan"); | 49 | slen = snprintf(buf, bufsize, "nan"); |
| 50 | } else if (isinf(realval)) { | 50 | } else if (isinf(realval)) { |
| 51 | len = snprintf(buf, bufsize, "%cinfinity", (realval > 0.0) ? '+' : '-'); | 51 | slen = snprintf(buf, bufsize, "%cinfinity", (realval > 0.0) ? '+' : '-'); |
| 52 | } else if (realval == 0.0f) { | 52 | } else if (realval == 0.0f) { |
| 53 | len = snprintf(buf, bufsize, "0.0"); | 53 | slen = snprintf(buf, bufsize, "0.0"); |
| 54 | } else { | 54 | } else { |
| 55 | slen = snprintf(buf, bufsize, "%.*g", 17, realval); | ||
| 56 | if (slen < 0) { | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | if (!buf || bufsize == 0) { | ||
| 60 | return (size_t)slen; | ||
| 61 | } | ||
| 62 | size_t len = (size_t)slen; | ||
| 63 | if (len >= bufsize) { | ||
| 64 | len = bufsize - 1; | ||
| 65 | } | ||
| 55 | size_t i = 0; | 66 | size_t i = 0; |
| 56 | len = snprintf(buf, bufsize, "%.*g", 17, realval); | 67 | for (i = 0; i < len; i++) { |
| 57 | for (i = 0; buf && i < len; i++) { | ||
| 58 | if (buf[i] == ',') { | 68 | if (buf[i] == ',') { |
| 59 | buf[i] = '.'; | 69 | buf[i] = '.'; |
| 60 | break; | 70 | break; |
| @@ -62,8 +72,12 @@ static size_t dtostr(char *buf, size_t bufsize, double realval) | |||
| 62 | break; | 72 | break; |
| 63 | } | 73 | } |
| 64 | } | 74 | } |
| 75 | return len; | ||
| 76 | } | ||
| 77 | if (slen < 0) { | ||
| 78 | return 0; | ||
| 65 | } | 79 | } |
| 66 | return len; | 80 | return (size_t)slen; |
| 67 | } | 81 | } |
| 68 | 82 | ||
| 69 | static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t depth, uint32_t indent, int partial_data) | 83 | static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t depth, uint32_t indent, int partial_data) |
| @@ -71,14 +85,19 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de | |||
| 71 | plist_data_t node_data = NULL; | 85 | plist_data_t node_data = NULL; |
| 72 | 86 | ||
| 73 | char *val = NULL; | 87 | char *val = NULL; |
| 88 | int slen = 0; | ||
| 74 | size_t val_len = 0; | 89 | size_t val_len = 0; |
| 75 | 90 | ||
| 76 | uint32_t i = 0; | 91 | uint32_t i = 0; |
| 77 | 92 | ||
| 78 | if (!node) | 93 | if (!node || !outbuf || !*outbuf) { |
| 79 | return PLIST_ERR_INVALID_ARG; | 94 | return PLIST_ERR_INVALID_ARG; |
| 95 | } | ||
| 80 | 96 | ||
| 81 | node_data = plist_get_data(node); | 97 | node_data = plist_get_data(node); |
| 98 | if (!node_data) { | ||
| 99 | return PLIST_ERR_INVALID_ARG; | ||
| 100 | } | ||
| 82 | 101 | ||
| 83 | switch (node_data->type) | 102 | switch (node_data->type) |
| 84 | { | 103 | { |
| @@ -98,17 +117,24 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de | |||
| 98 | 117 | ||
| 99 | case PLIST_INT: | 118 | case PLIST_INT: |
| 100 | val = (char*)malloc(64); | 119 | val = (char*)malloc(64); |
| 120 | if (!val) return PLIST_ERR_NO_MEM; | ||
| 101 | if (node_data->length == 16) { | 121 | if (node_data->length == 16) { |
| 102 | val_len = snprintf(val, 64, "%" PRIu64, node_data->intval); | 122 | slen = snprintf(val, 64, "%" PRIu64, node_data->intval); |
| 103 | } else { | 123 | } else { |
| 104 | val_len = snprintf(val, 64, "%" PRIi64, node_data->intval); | 124 | slen = snprintf(val, 64, "%" PRIi64, node_data->intval); |
| 105 | } | 125 | } |
| 126 | if (slen < 0) { | ||
| 127 | free(val); | ||
| 128 | return PLIST_ERR_UNKNOWN; | ||
| 129 | } | ||
| 130 | val_len = (size_t)slen; | ||
| 106 | str_buf_append(*outbuf, val, val_len); | 131 | str_buf_append(*outbuf, val, val_len); |
| 107 | free(val); | 132 | free(val); |
| 108 | break; | 133 | break; |
| 109 | 134 | ||
| 110 | case PLIST_REAL: | 135 | case PLIST_REAL: |
| 111 | val = (char*)malloc(64); | 136 | val = (char*)malloc(64); |
| 137 | if (!val) return PLIST_ERR_NO_MEM; | ||
| 112 | val_len = dtostr(val, 64, node_data->realval); | 138 | val_len = dtostr(val, 64, node_data->realval); |
| 113 | str_buf_append(*outbuf, val, val_len); | 139 | str_buf_append(*outbuf, val, val_len); |
| 114 | free(val); | 140 | free(val); |
| @@ -116,6 +142,9 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de | |||
| 116 | 142 | ||
| 117 | case PLIST_STRING: | 143 | case PLIST_STRING: |
| 118 | case PLIST_KEY: { | 144 | case PLIST_KEY: { |
| 145 | if (!node_data->strval && node_data->length > 0) { | ||
| 146 | return PLIST_ERR_INVALID_ARG; | ||
| 147 | } | ||
| 119 | const char *charmap[32] = { | 148 | const char *charmap[32] = { |
| 120 | "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", | 149 | "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", |
| 121 | "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", | 150 | "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", |
| @@ -124,8 +153,8 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de | |||
| 124 | }; | 153 | }; |
| 125 | size_t j = 0; | 154 | size_t j = 0; |
| 126 | size_t len = 0; | 155 | size_t len = 0; |
| 127 | off_t start = 0; | 156 | size_t start = 0; |
| 128 | off_t cur = 0; | 157 | size_t cur = 0; |
| 129 | 158 | ||
| 130 | str_buf_append(*outbuf, "\"", 1); | 159 | str_buf_append(*outbuf, "\"", 1); |
| 131 | 160 | ||
| @@ -207,28 +236,32 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de | |||
| 207 | } break; | 236 | } break; |
| 208 | case PLIST_DATA: | 237 | case PLIST_DATA: |
| 209 | { | 238 | { |
| 239 | if (!node_data->buff && node_data->length > 0) { | ||
| 240 | return PLIST_ERR_INVALID_ARG; | ||
| 241 | } | ||
| 210 | str_buf_append(*outbuf, "<", 1); | 242 | str_buf_append(*outbuf, "<", 1); |
| 211 | size_t len = node_data->length; | 243 | size_t len = node_data->length; |
| 212 | char charb[4]; | 244 | char charb[4]; |
| 245 | size_t j; | ||
| 213 | if (!partial_data || len <= 24) { | 246 | if (!partial_data || len <= 24) { |
| 214 | for (i = 0; i < len; i++) { | 247 | for (j = 0; j < len; j++) { |
| 215 | if (i > 0 && (i % 4 == 0)) | 248 | if (j > 0 && (j % 4 == 0)) |
| 216 | str_buf_append(*outbuf, " ", 1); | 249 | str_buf_append(*outbuf, " ", 1); |
| 217 | sprintf(charb, "%02x", (unsigned char)node_data->buff[i]); | 250 | snprintf(charb, sizeof(charb), "%02x", (unsigned char)node_data->buff[j]); |
| 218 | str_buf_append(*outbuf, charb, 2); | 251 | str_buf_append(*outbuf, charb, 2); |
| 219 | } | 252 | } |
| 220 | } else { | 253 | } else { |
| 221 | for (i = 0; i < 16; i++) { | 254 | for (j = 0; j < 16; j++) { |
| 222 | if (i > 0 && (i % 4 == 0)) | 255 | if (j > 0 && (j % 4 == 0)) |
| 223 | str_buf_append(*outbuf, " ", 1); | 256 | str_buf_append(*outbuf, " ", 1); |
| 224 | sprintf(charb, "%02x", (unsigned char)node_data->buff[i]); | 257 | snprintf(charb, sizeof(charb), "%02x", (unsigned char)node_data->buff[j]); |
| 225 | str_buf_append(*outbuf, charb, 2); | 258 | str_buf_append(*outbuf, charb, 2); |
| 226 | } | 259 | } |
| 227 | str_buf_append(*outbuf, " ... ", 5); | 260 | str_buf_append(*outbuf, " ... ", 5); |
| 228 | for (i = len - 8; i < len; i++) { | 261 | for (j = len - 8; j < len; j++) { |
| 229 | sprintf(charb, "%02x", (unsigned char)node_data->buff[i]); | 262 | snprintf(charb, sizeof(charb), "%02x", (unsigned char)node_data->buff[j]); |
| 230 | str_buf_append(*outbuf, charb, 2); | 263 | str_buf_append(*outbuf, charb, 2); |
| 231 | if (i > 0 && i < len-1 && (i % 4 == 0)) | 264 | if (j > 0 && j < len-1 && (j % 4 == 0)) |
| 232 | str_buf_append(*outbuf, " ", 1); | 265 | str_buf_append(*outbuf, " ", 1); |
| 233 | } | 266 | } |
| 234 | } | 267 | } |
| @@ -242,6 +275,7 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de | |||
| 242 | struct TM *btime = gmtime64_r(&timev, &_btime); | 275 | struct TM *btime = gmtime64_r(&timev, &_btime); |
| 243 | if (btime) { | 276 | if (btime) { |
| 244 | val = (char*)calloc(1, 26); | 277 | val = (char*)calloc(1, 26); |
| 278 | if (!val) return PLIST_ERR_NO_MEM; | ||
| 245 | struct tm _tmcopy; | 279 | struct tm _tmcopy; |
| 246 | copy_TM64_to_tm(btime, &_tmcopy); | 280 | copy_TM64_to_tm(btime, &_tmcopy); |
| 247 | val_len = strftime(val, 26, "%Y-%m-%d %H:%M:%S +0000", &_tmcopy); | 281 | val_len = strftime(val, 26, "%Y-%m-%d %H:%M:%S +0000", &_tmcopy); |
| @@ -257,11 +291,17 @@ static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t de | |||
| 257 | { | 291 | { |
| 258 | str_buf_append(*outbuf, "CF$UID:", 7); | 292 | str_buf_append(*outbuf, "CF$UID:", 7); |
| 259 | val = (char*)malloc(64); | 293 | val = (char*)malloc(64); |
| 294 | if (!val) return PLIST_ERR_NO_MEM; | ||
| 260 | if (node_data->length == 16) { | 295 | if (node_data->length == 16) { |
| 261 | val_len = snprintf(val, 64, "%" PRIu64, node_data->intval); | 296 | slen = snprintf(val, 64, "%" PRIu64, node_data->intval); |
| 262 | } else { | 297 | } else { |
| 263 | val_len = snprintf(val, 64, "%" PRIi64, node_data->intval); | 298 | slen = snprintf(val, 64, "%" PRIi64, node_data->intval); |
| 299 | } | ||
| 300 | if (slen < 0) { | ||
| 301 | free(val); | ||
| 302 | return PLIST_ERR_UNKNOWN; | ||
| 264 | } | 303 | } |
| 304 | val_len = (size_t)slen; | ||
| 265 | str_buf_append(*outbuf, val, val_len); | 305 | str_buf_append(*outbuf, val, val_len); |
| 266 | free(val); | 306 | free(val); |
| 267 | } | 307 | } |
