|
47 | 47 | #include <errno.h> |
48 | 48 | #endif |
49 | 49 |
|
| 50 | +#ifdef FEATURE_XML |
| 51 | +#include <libxml/xmlmemory.h> |
| 52 | +#include <libxml/parser.h> |
| 53 | +#endif |
| 54 | + |
50 | 55 |
|
51 | 56 | /* how should output values be formatted? */ |
52 | 57 | enum FMT_MODE { |
@@ -75,6 +80,41 @@ hParseInt(const unsigned char **buf, size_t *lenBuf) |
75 | 80 | return i; |
76 | 81 | } |
77 | 82 |
|
| 83 | + |
| 84 | +#ifdef FEATURE_XML |
| 85 | +/* Credits to https://github.com/katie-snow/xml2json-c |
| 86 | + This code is under GPL-3.0 License |
| 87 | +*/ |
| 88 | +static inline void |
| 89 | +xml2jsonc_convert_elements(xmlNode *anode, json_object *jobj) |
| 90 | +{ |
| 91 | + xmlNode *cur_node = NULL; |
| 92 | + json_object *cur_jobj = NULL; |
| 93 | + json_object *cur_jstr = NULL; |
| 94 | + |
| 95 | + for (cur_node = anode; cur_node; cur_node = cur_node->next) |
| 96 | + { |
| 97 | + if (cur_node->type == XML_ELEMENT_NODE) |
| 98 | + { |
| 99 | + if (xmlChildElementCount(cur_node) == 0) |
| 100 | + { |
| 101 | + /* JSON string object */ |
| 102 | + cur_jobj = json_object_new_object(); |
| 103 | + cur_jstr = json_object_new_string((const char *)xmlNodeGetContent(cur_node)); |
| 104 | + json_object_object_add(jobj, (const char *)cur_node->name, cur_jstr); |
| 105 | + } |
| 106 | + else |
| 107 | + { |
| 108 | + /* JSON object */ |
| 109 | + cur_jobj = json_object_new_object(); |
| 110 | + json_object_object_add(jobj, (const char *)cur_node->name, json_object_get(cur_jobj)); |
| 111 | + } |
| 112 | + } |
| 113 | + xml2jsonc_convert_elements(cur_node->children, cur_jobj); |
| 114 | + } |
| 115 | +} |
| 116 | +#endif /* #ifdef FEATURE_XML */ |
| 117 | + |
78 | 118 | /* parser _parse interface |
79 | 119 | * |
80 | 120 | * All parsers receive |
@@ -2325,6 +2365,71 @@ PARSER_Parse(v2IPTables) |
2325 | 2365 | return r; |
2326 | 2366 | } |
2327 | 2367 |
|
| 2368 | +#ifdef FEATURE_XML |
| 2369 | +/** |
| 2370 | + * Parse XML. This parser tries to find XML data inside a message. |
| 2371 | + * If it finds valid XML, it will extract it. |
| 2372 | + * |
| 2373 | + * Note: The XML Parser expects a string that begins with '<' and |
| 2374 | + * ends with '>'. whitespace or any other character at the |
| 2375 | + * beginning or at the end of the string will cause a parse failure |
| 2376 | + * |
| 2377 | + * Note: Is there is extra content after the XML content |
| 2378 | + * the parser will fail. A hack consist of finding the |
| 2379 | + * last '>' in the string and ignore the rest. |
| 2380 | + * |
| 2381 | + * added 2021-02-01 by [email protected] |
| 2382 | + */ |
| 2383 | +PARSER_Parse(XML) |
| 2384 | + xmlDocPtr doc = NULL; |
| 2385 | + xmlNodePtr root_element = NULL; |
| 2386 | + |
| 2387 | + /* Find the last occurence of '>' in the string */ |
| 2388 | + char * pch; |
| 2389 | + pch=strrchr((const char *) npb->str + *offs, '>'); |
| 2390 | + |
| 2391 | + /* Truncate the string after the last occurence of '>' */ |
| 2392 | + int newLen = pch - (npb->str + *offs) + 1; |
| 2393 | + char *cstr = strndup(npb->str + *offs, newLen); |
| 2394 | + CHKN(cstr); |
| 2395 | + |
| 2396 | + doc=xmlParseDoc((xmlChar*) cstr); |
| 2397 | + free(cstr); |
| 2398 | + |
| 2399 | + /* Invalid XML string */ |
| 2400 | + if (doc == NULL) { |
| 2401 | + goto done; |
| 2402 | + } |
| 2403 | + |
| 2404 | + /* Now convert XML document into JSON document */ |
| 2405 | + root_element = xmlDocGetRootElement(doc); |
| 2406 | + json_object *json = NULL; |
| 2407 | + json = json_object_new_object(); |
| 2408 | + xml2jsonc_convert_elements(root_element, json); |
| 2409 | + |
| 2410 | + if(json == NULL) |
| 2411 | + goto done; |
| 2412 | + |
| 2413 | + /* parsing OK */ |
| 2414 | + *parsed = newLen ; |
| 2415 | + r = 0; |
| 2416 | + |
| 2417 | + if(value == NULL) { |
| 2418 | + json_object_put(json); |
| 2419 | + } else { |
| 2420 | + *value = json; |
| 2421 | + } |
| 2422 | + |
| 2423 | +done: |
| 2424 | + if(doc != NULL) |
| 2425 | + xmlFreeDoc(doc); |
| 2426 | + xmlCleanupParser(); |
| 2427 | + return r; |
| 2428 | +} |
| 2429 | +#endif /* #ifdef FEATURE_XML */ |
| 2430 | + |
| 2431 | + |
| 2432 | + |
2328 | 2433 | /** |
2329 | 2434 | * Parse JSON. This parser tries to find JSON data inside a message. |
2330 | 2435 | * If it finds valid JSON, it will extract it. Extra data after the |
|
0 commit comments