summaryrefslogtreecommitdiffstats
path: root/src/plist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plist.c')
-rw-r--r--src/plist.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/src/plist.c b/src/plist.c
index 37edfa4..e696f70 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -34,6 +34,7 @@
34#include <assert.h> 34#include <assert.h>
35#include <limits.h> 35#include <limits.h>
36#include <float.h> 36#include <float.h>
37#include <ctype.h>
37 38
38#ifdef WIN32 39#ifdef WIN32
39#include <windows.h> 40#include <windows.h>
@@ -51,12 +52,15 @@ extern void plist_bin_init(void);
51extern void plist_bin_deinit(void); 52extern void plist_bin_deinit(void);
52extern void plist_json_init(void); 53extern void plist_json_init(void);
53extern void plist_json_deinit(void); 54extern void plist_json_deinit(void);
55extern void plist_ostep_init(void);
56extern void plist_ostep_deinit(void);
54 57
55static void internal_plist_init(void) 58static void internal_plist_init(void)
56{ 59{
57 plist_bin_init(); 60 plist_bin_init();
58 plist_xml_init(); 61 plist_xml_init();
59 plist_json_init(); 62 plist_json_init();
63 plist_ostep_init();
60} 64}
61 65
62static void internal_plist_deinit(void) 66static void internal_plist_deinit(void)
@@ -64,6 +68,7 @@ static void internal_plist_deinit(void)
64 plist_bin_deinit(); 68 plist_bin_deinit();
65 plist_xml_deinit(); 69 plist_xml_deinit();
66 plist_json_deinit(); 70 plist_json_deinit();
71 plist_ostep_deinit();
67} 72}
68 73
69#ifdef WIN32 74#ifdef WIN32
@@ -186,6 +191,10 @@ PLIST_API int plist_is_binary(const char *plist_data, uint32_t length)
186 return (memcmp(plist_data, "bplist00", 8) == 0); 191 return (memcmp(plist_data, "bplist00", 8) == 0);
187} 192}
188 193
194#define SKIP_WS(blob, pos, len) \
195 while (pos < len && ((blob[pos] == ' ') || (blob[pos] == '\t') || (blob[pos] == '\r') || (blob[pos] == '\n'))) pos++;
196#define FIND_NEXT(blob, pos, len, chr) \
197 while (pos < len && (blob[pos] != chr)) pos++;
189 198
190PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist) 199PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist)
191{ 200{
@@ -194,19 +203,54 @@ PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length,
194 return PLIST_ERR_INVALID_ARG; 203 return PLIST_ERR_INVALID_ARG;
195 } 204 }
196 *plist = NULL; 205 *plist = NULL;
197 if (!plist_data || length < 8) { 206 if (!plist_data || length == 0) {
198 return PLIST_ERR_INVALID_ARG; 207 return PLIST_ERR_INVALID_ARG;
199 } 208 }
200 if (plist_is_binary(plist_data, length)) { 209 if (plist_is_binary(plist_data, length)) {
201 res = plist_from_bin(plist_data, length, plist); 210 res = plist_from_bin(plist_data, length, plist);
202 } else { 211 } else {
203 /* skip whitespace before checking */
204 uint32_t pos = 0; 212 uint32_t pos = 0;
205 while (pos < length && ((plist_data[pos] == ' ') || (plist_data[pos] == '\t') || (plist_data[pos] == '\r') || (plist_data[pos] == '\n'))) pos++; 213 int is_json = 0;
206 if (plist_data[pos] == '[' || plist_data[pos] == '{') { 214 int is_xml = 0;
215 /* skip whitespace */
216 SKIP_WS(plist_data, pos, length);
217 if (plist_data[pos] == '<' && (length-pos > 3) && !isxdigit(plist_data[pos+1]) && !isxdigit(plist_data[pos+2]) && !isxdigit(plist_data[pos+3])) {
218 is_xml = 1;
219 } else if (plist_data[pos] == '[') {
220 /* only valid for json */
221 is_json = 1;
222 } else if (plist_data[pos] == '(') {
223 /* only valid for openstep */
224 } else if (plist_data[pos] == '{') {
225 /* this could be json or openstep */
226 pos++;
227 SKIP_WS(plist_data, pos, length);
228 if (plist_data[pos] == '"') {
229 /* still could be both */
230 pos++;
231 do {
232 FIND_NEXT(plist_data, pos, length, '"');
233 if (plist_data[pos-1] != '\\') {
234 break;
235 }
236 pos++;
237 } while (pos < length);
238 if (plist_data[pos] == '"') {
239 pos++;
240 SKIP_WS(plist_data, pos, length);
241 if (plist_data[pos] == ':') {
242 /* this is definitely json */
243 is_json = 1;
244 }
245 }
246 }
247 }
248 if (is_xml) {
249 res = plist_from_xml(plist_data, length, plist);
250 } else if (is_json) {
207 res = plist_from_json(plist_data, length, plist); 251 res = plist_from_json(plist_data, length, plist);
208 } else { 252 } else {
209 res = plist_from_xml(plist_data, length, plist); 253 res = plist_from_openstep(plist_data, length, plist);
210 } 254 }
211 } 255 }
212 return res; 256 return res;