diff options
-rw-r--r-- | src/xplist.c | 111 |
1 files changed, 66 insertions, 45 deletions
diff --git a/src/xplist.c b/src/xplist.c index 9dd43fe..1fc3fc1 100644 --- a/src/xplist.c +++ b/src/xplist.c @@ -47,17 +47,26 @@ #include "strbuf.h" #include "time64.h" -#define XPLIST_TEXT "text" #define XPLIST_KEY "key" +#define XPLIST_KEY_LEN 3 #define XPLIST_FALSE "false" +#define XPLIST_FALSE_LEN 5 #define XPLIST_TRUE "true" +#define XPLIST_TRUE_LEN 4 #define XPLIST_INT "integer" +#define XPLIST_INT_LEN 7 #define XPLIST_REAL "real" +#define XPLIST_REAL_LEN 4 #define XPLIST_DATE "date" +#define XPLIST_DATE_LEN 4 #define XPLIST_DATA "data" +#define XPLIST_DATA_LEN 4 #define XPLIST_STRING "string" +#define XPLIST_STRING_LEN 6 #define XPLIST_ARRAY "array" +#define XPLIST_ARRAY_LEN 5 #define XPLIST_DICT "dict" +#define XPLIST_DICT_LEN 4 #define MAC_EPOCH 978307200 @@ -89,7 +98,7 @@ void plist_xml_deinit(void) /* deinit XML stuff */ } -static void dtostr(char *buf, size_t bufsize, double realval) +static size_t dtostr(char *buf, size_t bufsize, double realval) { double f = realval; double ip = 0.0; @@ -100,7 +109,7 @@ static void dtostr(char *buf, size_t bufsize, double realval) f = modf(f, &ip); len = snprintf(buf, bufsize, "%s%"PRIi64, ((f < 0) && (ip >= 0)) ? "-" : "", (int64_t)ip); if (len >= bufsize) { - return; + return 0; } if (f < 0) { @@ -117,6 +126,7 @@ static void dtostr(char *buf, size_t bufsize, double realval) buf[p++] = (v + 0x30); } buf[p] = '\0'; + return p; } static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) @@ -127,7 +137,9 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) char tagOpen = FALSE; const char *tag = NULL; + size_t tag_len = 0; char *val = NULL; + size_t val_len = 0; uint32_t i = 0; @@ -140,53 +152,64 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) { case PLIST_BOOLEAN: { - if (node_data->boolval) + if (node_data->boolval) { tag = XPLIST_TRUE; - else + tag_len = XPLIST_TRUE_LEN; + } else { tag = XPLIST_FALSE; + tag_len = XPLIST_FALSE_LEN; + } } break; case PLIST_UINT: tag = XPLIST_INT; + tag_len = XPLIST_INT_LEN; val = (char*)malloc(64); if (node_data->length == 16) { - (void)snprintf(val, 64, "%"PRIu64, node_data->intval); - } else { - (void)snprintf(val, 64, "%"PRIi64, node_data->intval); - } + val_len = snprintf(val, 64, "%"PRIu64, node_data->intval); + } else { + val_len = snprintf(val, 64, "%"PRIi64, node_data->intval); + } break; case PLIST_REAL: tag = XPLIST_REAL; + tag_len = XPLIST_REAL_LEN; val = (char*)malloc(64); - dtostr(val, 64, node_data->realval); + val_len = dtostr(val, 64, node_data->realval); break; case PLIST_STRING: tag = XPLIST_STRING; + tag_len = XPLIST_STRING_LEN; /* contents processed directly below */ break; case PLIST_KEY: tag = XPLIST_KEY; + tag_len = XPLIST_KEY_LEN; /* contents processed directly below */ break; case PLIST_DATA: tag = XPLIST_DATA; + tag_len = XPLIST_DATA_LEN; /* contents processed directly below */ break; case PLIST_ARRAY: tag = XPLIST_ARRAY; + tag_len = XPLIST_ARRAY_LEN; isStruct = TRUE; break; case PLIST_DICT: tag = XPLIST_DICT; + tag_len = XPLIST_DICT_LEN; isStruct = TRUE; break; case PLIST_DATE: tag = XPLIST_DATE; + tag_len = XPLIST_DATE_LEN; { Time64_T timev = (Time64_T)node_data->realval + MAC_EPOCH; struct TM _btime; @@ -196,7 +219,8 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) memset(val, 0, 24); struct tm _tmcopy; copy_TM64_to_tm(btime, &_tmcopy); - if (strftime(val, 24, "%Y-%m-%dT%H:%M:%SZ", &_tmcopy) <= 0) { + val_len = strftime(val, 24, "%Y-%m-%dT%H:%M:%SZ", &_tmcopy); + if (val_len <= 0) { free (val); val = NULL; } @@ -205,12 +229,13 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) break; case PLIST_UID: tag = XPLIST_DICT; + tag_len = XPLIST_DICT_LEN; val = (char*)malloc(64); if (node_data->length == 16) { - (void)snprintf(val, 64, "%"PRIu64, node_data->intval); - } else { - (void)snprintf(val, 64, "%"PRIi64, node_data->intval); - } + val_len = snprintf(val, 64, "%"PRIu64, node_data->intval); + } else { + val_len = snprintf(val, 64, "%"PRIi64, node_data->intval); + } break; default: break; @@ -222,7 +247,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) /* append tag */ str_buf_append(*outbuf, "<", 1); - str_buf_append(*outbuf, tag, strlen(tag)); + str_buf_append(*outbuf, tag, tag_len); if (node_data->type == PLIST_STRING || node_data->type == PLIST_KEY) { size_t j; size_t len; @@ -233,8 +258,8 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) tagOpen = TRUE; /* make sure we convert the following predefined xml entities */ - /* < = < > = > ' = ' " = " & = & */ - len = strlen(node_data->strval); + /* < = < > = > & = & */ + len = node_data->length; for (j = 0; j < len; j++) { switch (node_data->strval[j]) { case '<': @@ -302,7 +327,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) str_buf_append(*outbuf, "\t", 1); } str_buf_append(*outbuf, "<integer>", 9); - str_buf_append(*outbuf, val, strlen(val)); + str_buf_append(*outbuf, val, val_len); str_buf_append(*outbuf, "</integer>", 10); str_buf_append(*outbuf, "\n", 1); @@ -312,7 +337,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) } else if (val) { str_buf_append(*outbuf, ">", 1); tagOpen = TRUE; - str_buf_append(*outbuf, val, strlen(val)); + str_buf_append(*outbuf, val, val_len); } else if (isStruct) { tagOpen = TRUE; str_buf_append(*outbuf, ">", 1); @@ -345,7 +370,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) if (tagOpen) { /* add closing tag */ str_buf_append(*outbuf, "</", 2); - str_buf_append(*outbuf, tag, strlen(tag)); + str_buf_append(*outbuf, tag, tag_len); str_buf_append(*outbuf, ">", 1); } str_buf_append(*outbuf, "\n", 1); @@ -419,9 +444,8 @@ static void find_char(parse_ctx ctx, char c, int skip_quotes) } } -static void find_str(parse_ctx ctx, const char *str, int skip_quotes) +static void find_str(parse_ctx ctx, const char *str, size_t len, int skip_quotes) { - size_t len = strlen(str); while (ctx->pos < (ctx->end - len)) { if (!strncmp(ctx->pos, str, len)) { break; @@ -438,9 +462,8 @@ static void find_str(parse_ctx ctx, const char *str, int skip_quotes) } } -static void find_next(parse_ctx ctx, const char *nextchars, int skip_quotes) +static void find_next(parse_ctx ctx, const char *nextchars, int numchars, int skip_quotes) { - int numchars = strlen(nextchars); int i = 0; while (ctx->pos < ctx->end) { if (skip_quotes && (*(ctx->pos) == '"')) { @@ -493,11 +516,10 @@ static text_part_t* text_part_append(text_part_t* parts, const char *begin, size return newpart; } -static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, int skip_ws, text_part_t *parts) +static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, size_t tag_len, int skip_ws, text_part_t *parts) { const char *p = NULL; const char *q = NULL; - int taglen = 0; text_part_t *last = NULL; if (skip_ws) { @@ -527,7 +549,7 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, int skip_ws, last = text_part_init(parts, p, q-p, 0); } ctx->pos += 2; - find_str(ctx, "-->", 0); + find_str(ctx, "-->", 3, 0); if (ctx->pos >= ctx->end || strncmp(ctx->pos, "-->", 3) != 0) { PLIST_XML_ERR("EOF while looking for end of comment\n"); ctx->err++; @@ -551,7 +573,7 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, int skip_ws, } ctx->pos+=6; p = ctx->pos; - find_str(ctx, "]]>", 0); + find_str(ctx, "]]>", 3, 0); if (ctx->pos >= ctx->end || strncmp(ctx->pos, "]]>", 3) != 0) { PLIST_XML_ERR("EOF while looking for end of CDATA block\n"); ctx->err++; @@ -579,13 +601,12 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, int skip_ws, } } while (1); ctx->pos++; - taglen = strlen(tag); - if (ctx->pos >= ctx->end-taglen || strncmp(ctx->pos, tag, taglen)) { + if (ctx->pos >= ctx->end-tag_len || strncmp(ctx->pos, tag, tag_len)) { PLIST_XML_ERR("EOF or end tag mismatch\n"); ctx->err++; return NULL; } - ctx->pos+=taglen; + ctx->pos+=tag_len; if (ctx->pos >= ctx->end || *ctx->pos != '>') { PLIST_XML_ERR("EOF or no '>' after tag name\n"); ctx->err++; @@ -760,7 +781,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) } if (*(ctx->pos) == '?') { - find_str(ctx, "?>", 1); + find_str(ctx, "?>", 2, 1); if (ctx->pos >= ctx->end) { break; } @@ -775,7 +796,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) /* comment or DTD */ if (((ctx->end - ctx->pos) > 3) && !strncmp(ctx->pos, "!--", 3)) { ctx->pos += 3; - find_str(ctx,"-->", 0); + find_str(ctx,"-->", 3, 0); if (strncmp(ctx->pos, "-->", 3)) { PLIST_XML_ERR("Couldn't find end of comment\n"); ctx->pos = ctx->end; @@ -786,7 +807,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) int embedded_dtd = 0; ctx->pos+=8; while (ctx->pos < ctx->end) { - find_next(ctx, " \t\r\n[>", 1); + find_next(ctx, " \t\r\n[>", 6, 1); if (*ctx->pos == '[') { embedded_dtd = 1; break; @@ -799,7 +820,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) } } if (embedded_dtd) { - find_str(ctx, "]>", 1); + find_str(ctx, "]>", 2, 1); if (strncmp(ctx->pos, "]>", 2)) { PLIST_XML_ERR("Couldn't find end of DOCTYPE\n"); ctx->pos = ctx->end; @@ -816,7 +837,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) int is_empty = 0; int closing_tag = 0; const char *p = ctx->pos; - find_next(ctx," \r\n\t<>",0); + find_next(ctx," \r\n\t<>", 6, 0); if (ctx->pos >= ctx->end) { PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); ctx->pos = ctx->end; @@ -829,7 +850,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) strncpy(tag, p, taglen); tag[taglen] = '\0'; if (*ctx->pos != '>') { - find_next(ctx, "<>", 1); + find_next(ctx, "<>", 2, 1); } if (ctx->pos >= ctx->end) { PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); @@ -876,7 +897,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) } else if (!strcmp(tag, XPLIST_INT)) { if (!is_empty) { text_part_t first_part = { NULL, 0, 0, NULL }; - text_part_t *tp = get_text_parts(ctx, tag, 1, &first_part); + text_part_t *tp = get_text_parts(ctx, tag, taglen, 1, &first_part); if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); @@ -930,7 +951,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) } else if (!strcmp(tag, XPLIST_REAL)) { if (!is_empty) { text_part_t first_part = { NULL, 0, 0, NULL }; - text_part_t *tp = get_text_parts(ctx, tag, 1, &first_part); + text_part_t *tp = get_text_parts(ctx, tag, taglen, 1, &first_part); if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); @@ -960,14 +981,14 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) data->length = 8; } else if (!strcmp(tag, XPLIST_TRUE)) { if (!is_empty) { - get_text_parts(ctx, tag, 1, NULL); + get_text_parts(ctx, tag, taglen, 1, NULL); } data->type = PLIST_BOOLEAN; data->boolval = 1; data->length = 1; } else if (!strcmp(tag, XPLIST_FALSE)) { if (!is_empty) { - get_text_parts(ctx, tag, 1, NULL); + get_text_parts(ctx, tag, taglen, 1, NULL); } data->type = PLIST_BOOLEAN; data->boolval = 0; @@ -975,7 +996,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) } else if (!strcmp(tag, XPLIST_STRING) || !strcmp(tag, XPLIST_KEY)) { if (!is_empty) { text_part_t first_part = { NULL, 0, 0, NULL }; - text_part_t *tp = get_text_parts(ctx, tag, 0, &first_part); + text_part_t *tp = get_text_parts(ctx, tag, taglen, 0, &first_part); char *str = NULL; size_t length = 0; if (!tp) { @@ -1012,7 +1033,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) } else if (!strcmp(tag, XPLIST_DATA)) { if (!is_empty) { text_part_t first_part = { NULL, 0, 0, NULL }; - text_part_t *tp = get_text_parts(ctx, tag, 1, &first_part); + text_part_t *tp = get_text_parts(ctx, tag, taglen, 1, &first_part); if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); @@ -1045,7 +1066,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) } else if (!strcmp(tag, XPLIST_DATE)) { if (!is_empty) { text_part_t first_part = { NULL, 0, 0, NULL }; - text_part_t *tp = get_text_parts(ctx, tag, 1, &first_part); + text_part_t *tp = get_text_parts(ctx, tag, taglen, 1, &first_part); if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); |