summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2021-12-19 16:13:07 +0100
committerGravatar Nikias Bassen2021-12-19 16:13:07 +0100
commit810e1a5936867a9f2c9f07df3a33a9d02fc03466 (patch)
treec561f0301b98a95fddc32259978345eed8eb5cc5
parentc81471ce6e8821ba03427824217612dcab8e091b (diff)
downloadlibplist-810e1a5936867a9f2c9f07df3a33a9d02fc03466.tar.gz
libplist-810e1a5936867a9f2c9f07df3a33a9d02fc03466.tar.bz2
Add support for PLIST_NULL type
-rw-r--r--include/plist/plist.h30
-rw-r--r--src/bplist.c12
-rw-r--r--src/plist.c9
-rw-r--r--src/xplist.c24
4 files changed, 60 insertions, 15 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h
index 67050ee..0f69d40 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -103,17 +103,18 @@ extern "C"
*/
typedef enum
{
- PLIST_BOOLEAN, /**< Boolean, scalar type */
- PLIST_UINT, /**< Unsigned integer, scalar type */
- PLIST_REAL, /**< Real, scalar type */
- PLIST_STRING, /**< ASCII string, scalar type */
- PLIST_ARRAY, /**< Ordered array, structured type */
- PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */
- PLIST_DATE, /**< Date, scalar type */
- PLIST_DATA, /**< Binary data, scalar type */
- PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */
+ PLIST_BOOLEAN, /**< Boolean, scalar type */
+ PLIST_UINT, /**< Unsigned integer, scalar type */
+ PLIST_REAL, /**< Real, scalar type */
+ PLIST_STRING, /**< ASCII string, scalar type */
+ PLIST_ARRAY, /**< Ordered array, structured type */
+ PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */
+ PLIST_DATE, /**< Date, scalar type */
+ PLIST_DATA, /**< Binary data, scalar type */
+ PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */
PLIST_UID, /**< Special type used for 'keyed encoding' */
- PLIST_NONE /**< No type */
+ PLIST_NULL, /**< NULL type */
+ PLIST_NONE /**< No type */
} plist_type;
@@ -205,6 +206,15 @@ extern "C"
plist_t plist_new_uid(uint64_t val);
/**
+ * Create a new plist_t type #PLIST_NULL
+ * @return the created item
+ * @sa #plist_type
+ * @note This type is not valid for all formats, e.g. the XML format
+ * does not support it.
+ */
+ plist_t plist_new_null(void);
+
+ /**
* Destruct a plist_t node and all its children recursively
*
* @param plist the plist to free
diff --git a/src/bplist.c b/src/bplist.c
index a41ce1a..a6e6ded 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -630,6 +630,13 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
}
case BPLIST_NULL:
+ {
+ plist_data_t data = plist_new_plist_data();
+ data->type = PLIST_NULL;
+ data->length = 0;
+ return node_create(NULL, data);
+ }
+
default:
return NULL;
}
@@ -1295,6 +1302,11 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
switch (data->type)
{
+ case PLIST_NULL: {
+ uint8_t b = 0;
+ byte_array_append(bplist_buff, &b, 1);
+ break;
+ }
case PLIST_BOOLEAN: {
uint8_t b = data->boolval ? BPLIST_TRUE : BPLIST_FALSE;
byte_array_append(bplist_buff, &b, 1);
diff --git a/src/plist.c b/src/plist.c
index 386b04e..5453176 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -374,6 +374,15 @@ PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec)
return plist_new_node(data);
}
+PLIST_API plist_t plist_new_null(void)
+{
+ plist_data_t data = plist_new_plist_data();
+ data->type = PLIST_NULL;
+ data->intval = 0;
+ data->length = 0;
+ return plist_new_node(data);
+}
+
PLIST_API void plist_free(plist_t plist)
{
if (plist)
diff --git a/src/xplist.c b/src/xplist.c
index c45a984..94006f1 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -81,8 +81,10 @@ static const char XML_PLIST_EPILOG[] = "</plist>\n";
#ifdef DEBUG
static int plist_xml_debug = 0;
#define PLIST_XML_ERR(...) if (plist_xml_debug) { fprintf(stderr, "libplist[xmlparser] ERROR: " __VA_ARGS__); }
+#define PLIST_XML_WRITE_ERR(...) if (plist_xml_debug) { fprintf(stderr, "libplist[xmlwriter] ERROR: " __VA_ARGS__); }
#else
#define PLIST_XML_ERR(...)
+#define PLIST_XML_WRITE_ERR(...)
#endif
void plist_xml_init(void)
@@ -125,7 +127,7 @@ static size_t dtostr(char *buf, size_t bufsize, double realval)
return len;
}
-static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
+static int node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
{
plist_data_t node_data = NULL;
@@ -139,8 +141,10 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
uint32_t i = 0;
- if (!node)
- return;
+ if (!node) {
+ PLIST_XML_WRITE_ERR("Encountered invalid empty node in property list\n");
+ return -1;
+ }
node_data = plist_get_data(node);
@@ -232,6 +236,9 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
val_len = snprintf(val, 64, "%"PRIi64, node_data->intval);
}
break;
+ case PLIST_NULL:
+ PLIST_XML_WRITE_ERR("PLIST_NULL type is not valid for XML format\n");
+ return -1;
default:
break;
}
@@ -353,7 +360,8 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
}
node_t *ch;
for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
- node_to_xml(ch, outbuf, depth+1);
+ int res = node_to_xml(ch, outbuf, depth+1);
+ if (res < 0) return res;
}
/* fix indent for structured types */
@@ -369,6 +377,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
str_buf_append(*outbuf, ">", 1);
}
str_buf_append(*outbuf, "\n", 1);
+ return 0;
}
static void parse_date(const char *strval, struct TM *btime)
@@ -519,7 +528,12 @@ PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)
str_buf_append(outbuf, XML_PLIST_PROLOG, sizeof(XML_PLIST_PROLOG)-1);
- node_to_xml(plist, &outbuf, 0);
+ if (node_to_xml(plist, &outbuf, 0) < 0) {
+ str_buf_free(outbuf);
+ *plist_xml = NULL;
+ *length = 0;
+ return;
+ }
str_buf_append(outbuf, XML_PLIST_EPILOG, sizeof(XML_PLIST_EPILOG));