int cli_json_parse_error(json_object *root, const char *errstr) { json_object *perr; if (!root) return CL_SUCCESS; /* CL_ENULLARG? */ perr = cli_jsonarray(root, "ParseErrors"); if (perr == NULL) { return CL_EMEM; } return cli_jsonstr(perr, NULL, errstr); }
static int ooxml_basic_json(int fd, cli_ctx *ctx, const char *key) { int ret = CL_SUCCESS; const xmlChar *stack[OOXML_JSON_RECLEVEL]; json_object *summary, *wrkptr; int type, rlvl = 0; int32_t val2; const xmlChar *name, *value; xmlTextReaderPtr reader = NULL; cli_dbgmsg("in ooxml_basic_json\n"); reader = xmlReaderForFd(fd, "properties.xml", NULL, 0); if (reader == NULL) { cli_dbgmsg("ooxml_basic_json: xmlReaderForFd error for %s\n", key); return CL_SUCCESS; // libxml2 failed! } summary = json_object_new_object(); if (NULL == summary) { cli_errmsg("ooxml_basic_json: no memory for json object.\n"); ret = CL_EFORMAT; goto ooxml_basic_exit; } while (xmlTextReaderRead(reader) == 1) { name = xmlTextReaderConstLocalName(reader); value = xmlTextReaderConstValue(reader); type = xmlTextReaderNodeType(reader); cli_dbgmsg("%s [%i]: %s\n", name, type, value); switch (type) { case XML_READER_TYPE_ELEMENT: stack[rlvl] = name; rlvl++; break; case XML_READER_TYPE_TEXT: { wrkptr = summary; if (rlvl > 2) { /* 0 is root xml object */ int i; for (i = 1; i < rlvl-1; ++i) { json_object *newptr = json_object_object_get(wrkptr, stack[i]); if (!newptr) { newptr = json_object_new_object(); if (NULL == newptr) { cli_errmsg("ooxml_basic_json: no memory for json object.\n"); ret = CL_EMEM; goto ooxml_basic_exit; } json_object_object_add(wrkptr, stack[i], newptr); } else { /* object already exists */ if (!json_object_is_type(newptr, json_type_object)) { cli_warnmsg("ooxml_content_cb: json object already exists as not an object\n"); ret = CL_EFORMAT; goto ooxml_basic_exit; } } wrkptr = newptr; cli_dbgmsg("stack %d: %s\n", i, stack[i]); } } if (ooxml_is_int(value, xmlStrlen(value), &val2)) { ret = cli_jsonint(wrkptr, stack[rlvl-1], val2); } else if (!xmlStrcmp(value, "true")) { ret = cli_jsonbool(wrkptr, stack[rlvl-1], 1); } else if (!xmlStrcmp(value, "false")) { ret = cli_jsonbool(wrkptr, stack[rlvl-1], 0); } else { ret = cli_jsonstr(wrkptr, stack[rlvl-1], value); } if (ret != CL_SUCCESS) goto ooxml_basic_exit; } break; case XML_READER_TYPE_END_ELEMENT: rlvl--; break; default: cli_dbgmsg("ooxml_content_cb: unhandled xml node %s [%i]: %s\n", name, type, value); ret = CL_EFORMAT; goto ooxml_basic_exit; } } json_object_object_add(ctx->wrkproperty, key, summary); if (rlvl != 0) { cli_warnmsg("ooxml_basic_json: office property file has unbalanced tags\n"); /* FAIL */ } ooxml_basic_exit: xmlTextReaderClose(reader); xmlFreeTextReader(reader); return ret; }
static int ooxml_parse_element(xmlTextReaderPtr reader, json_object *wrkptr, int rlvl, int skip) { const char *element_tag = NULL, *end_tag = NULL; const xmlChar *node_name = NULL, *node_value = NULL; json_object *njptr; int node_type, ret = CL_SUCCESS; int32_t val2; cli_dbgmsg("in ooxml_parse_element @ layer %d\n", rlvl); /* check recursion level */ if (rlvl >= OOXML_JSON_RECLEVEL_MAX) { return CL_EMAXREC; } if (wrkptr == NULL) { skip = 1; } /* acquire element type */ node_type = xmlTextReaderNodeType(reader); if (node_type != XML_READER_TYPE_ELEMENT) { cli_dbgmsg("ooxml_parse_element: first node typed %d, not %d\n", node_type, XML_READER_TYPE_ELEMENT); return CL_EPARSE; /* first type is not an element */ } /* acquire element tag */ node_name = xmlTextReaderConstLocalName(reader); if (!node_name) { cli_dbgmsg("ooxml_parse_element: element tag node nameless\n"); return CL_EPARSE; /* no name, nameless */ } element_tag = ooxml_check_key(node_name, xmlStrlen(node_name)); if (!element_tag) { cli_dbgmsg("ooxml_parse_element: invalid element tag [%s]\n", node_name); skip = 1; /* skipping element */ //return CL_EFORMAT; /* REMOVE */ } /* handle attributes if you want */ /* loop across all element contents */ while (xmlTextReaderRead(reader) == 1) { node_type = xmlTextReaderNodeType(reader); switch (node_type) { case XML_READER_TYPE_ELEMENT: if (!skip) { njptr = json_object_object_get(wrkptr, element_tag); if (!njptr) { njptr = json_object_new_object(); if (NULL == njptr) { cli_errmsg("ooxml_basic_json: no memory for json object.\n"); return CL_EMEM; } cli_dbgmsg("ooxml_basic_json: added json object [%s]\n", element_tag); json_object_object_add(wrkptr, element_tag, njptr); } else { if (!json_object_is_type(njptr, json_type_object)) { cli_warnmsg("ooxml_content_cb: json object [%s] already exists as not an object\n", element_tag); return CL_EFORMAT; } } } else { njptr = NULL; } ret = ooxml_parse_element(reader, njptr, rlvl+1, skip); if (ret != CL_SUCCESS) { return ret; } break; case XML_READER_TYPE_END_ELEMENT: cli_dbgmsg("in ooxml_parse_element @ layer %d closed\n", rlvl); node_name = xmlTextReaderConstLocalName(reader); if (!node_name) { cli_dbgmsg("ooxml_parse_element: element end tag node nameless\n"); return CL_EPARSE; /* no name, nameless */ } if (!skip) { end_tag = ooxml_check_key(node_name, xmlStrlen(node_name)); if (!end_tag) { cli_dbgmsg("ooxml_parse_element: invalid element end tag [%s]\n", node_name); return CL_EFORMAT; /* unrecognized element tag */ } if (strncmp(element_tag, end_tag, strlen(element_tag))) { cli_dbgmsg("ooxml_parse_element: element tag does not match end tag\n"); return CL_EFORMAT; } } return CL_SUCCESS; case XML_READER_TYPE_TEXT: if (!skip) { node_value = xmlTextReaderConstValue(reader); njptr = json_object_object_get(wrkptr, element_tag); if (njptr) { cli_warnmsg("ooxml_parse_element: json object [%s] already exists\n", element_tag); } if (ooxml_is_int(node_value, xmlStrlen(node_value), &val2)) { ret = cli_jsonint(wrkptr, element_tag, val2); } else if (!xmlStrcmp(node_value, "true")) { ret = cli_jsonbool(wrkptr, element_tag, 1); } else if (!xmlStrcmp(node_value, "false")) { ret = cli_jsonbool(wrkptr, element_tag, 0); } else { ret = cli_jsonstr(wrkptr, element_tag, node_value); } if (ret != CL_SUCCESS) return ret; cli_dbgmsg("ooxml_basic_json: added json value [%s: %s]\n", element_tag, node_value); } else { node_name = xmlTextReaderConstLocalName(reader); node_value = xmlTextReaderConstValue(reader); cli_dbgmsg("ooxml_parse_element: not adding xml node %s [%d]: %s\n", node_name, node_type, node_value); } break; default: node_name = xmlTextReaderConstLocalName(reader); node_value = xmlTextReaderConstValue(reader); cli_dbgmsg("ooxml_parse_element: unhandled xml node %s [%d]: %s\n", node_name, node_type, node_value); return CL_EPARSE; } } return CL_SUCCESS; }