added changes from peer code review

pull/6/head
Kevin Lin 12 years ago
parent 02a2258205
commit 871b862eb5
  1. 281
      libclamav/ooxml.c
  2. 6
      libclamav/unzip.c

@ -44,6 +44,8 @@
#include <libxml/xmlreader.h>
#endif
#define OOXML_DEBUG 0
#if HAVE_LIBXML2 && HAVE_JSON
#define OOXML_JSON_RECLEVEL 16
@ -141,7 +143,7 @@ static const char *ooxml_json_keys[] = {
"Lines",
"LinksUpToDate",
"Manager",
"MMClips",
"MultimediaClips",
"Notes",
"Pages",
"Paragraphs",
@ -160,26 +162,15 @@ static size_t num_ooxml_keys = 40; //42
static const char *ooxml_check_key(const char* key, size_t keylen)
{
unsigned i;
char keycmp[OOXML_JSON_STRLEN_MAX];
if (keylen > OOXML_JSON_STRLEN_MAX-1) {
cli_dbgmsg("ooxml_check_key: key name too long\n");
return NULL;
}
for (i = 0; i < keylen; i++) {
if (key[i] >= 'A' && key[i] <= 'Z') {
keycmp[i] = key[i] - 'A' + 'a';
}
else {
keycmp[i] = key[i];
}
}
keycmp[keylen] = '\0';
for (i = 0; i < num_ooxml_keys; ++i) {
//cli_dbgmsg("%d %d %s %s %s %s\n", keylen, strlen(ooxml_keys[i]), key, keycmp, ooxml_keys[i], ooxml_json_keys[i]);
if (keylen == strlen(ooxml_keys[i]) && !strncmp(keycmp, ooxml_keys[i], keylen)) {
if (keylen == strlen(ooxml_keys[i]) && !strncasecmp(key, ooxml_keys[i], keylen)) {
return ooxml_json_keys[i];
}
}
@ -223,7 +214,6 @@ static int ooxml_parse_element(cli_ctx *ctx, xmlTextReaderPtr reader, json_objec
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 */
@ -244,23 +234,6 @@ static int ooxml_parse_element(cli_ctx *ctx, xmlTextReaderPtr reader, json_objec
return CL_EFORMAT;
}
cli_dbgmsg("ooxml_parse_element: added json object [%s]\n", element_tag);
/*
if (!json_object_object_get_ex(wrkptr, element_tag, &njptr)) {
njptr = json_object_new_object();
if (NULL == njptr) {
cli_errmsg("ooxml_parse_element: no memory for json object.\n");
return CL_EMEM;
}
json_object_object_add(wrkptr, element_tag, njptr);
}
else {
if (!json_object_is_type(njptr, json_type_object)) {
cli_warnmsg("ooxml_parse_element: json object [%s] already exists as not an object\n", element_tag);
return CL_EFORMAT;
}
}
*/
}
else {
njptr = NULL;
@ -293,11 +266,6 @@ static int ooxml_parse_element(cli_ctx *ctx, xmlTextReaderPtr reader, json_objec
case XML_READER_TYPE_TEXT:
if (!skip) {
node_value = xmlTextReaderConstValue(reader);
/*
if (json_object_object_get_ex(wrkptr, element_tag, &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);
@ -317,18 +285,22 @@ static int ooxml_parse_element(cli_ctx *ctx, xmlTextReaderPtr reader, json_objec
cli_dbgmsg("ooxml_parse_element: added json value [%s: %s]\n", element_tag, node_value);
}
#if OOXML_DEBUG
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);
}
#endif
break;
default:
#if OOXML_DEBUG
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);
#endif
return CL_EPARSE;
}
}
@ -360,118 +332,7 @@ static int ooxml_parse_document(int fd, cli_ctx *ctx)
xmlFreeTextReader(reader);
return ret;
}
/*
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, toval = 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) {
if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS) {
ret = CL_ETIMEOUT;
goto ooxml_basic_exit;
}
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;
if (!json_object_object_get_ex(wrkptr, stack[i], &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_core_cb(int fd, cli_ctx *ctx)
{
cli_dbgmsg("in ooxml_core_cb\n");
@ -516,7 +377,7 @@ static int ooxml_content_cb(int fd, cli_ctx *ctx)
if (!xmlTextReaderHasAttributes(reader)) continue;
CT = NULL; PN = NULL;
CT = PN = NULL;
while (xmlTextReaderMoveToNextAttribute(reader) == 1) {
name = xmlTextReaderConstLocalName(reader);
value = xmlTextReaderConstValue(reader);
@ -534,86 +395,86 @@ static int ooxml_content_cb(int fd, cli_ctx *ctx)
if (!CT && !PN) continue;
if (!core && !xmlStrcmp(CT, "application/vnd.openxmlformats-package.core-properties+xml")) {
/* default: /docProps/core.xml*/
tmp = unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff);
if (tmp == CL_ETIMEOUT) {
ret = tmp;
}
else if (tmp != CL_VIRUS) {
cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
}
else {
cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
ret = unzip_single_internal(ctx, loff, ooxml_core_cb);
if (!xmlStrcmp(CT, "application/vnd.openxmlformats-package.core-properties+xml")) {
if (!core) {
/* default: /docProps/core.xml*/
tmp = unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff);
if (tmp == CL_ETIMEOUT) {
ret = tmp;
}
else if (tmp != CL_VIRUS) {
cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
}
else {
cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
ret = unzip_single_internal(ctx, loff, ooxml_core_cb);
}
}
core = 1;
core++;
}
else if (!extn && !xmlStrcmp(CT, "application/vnd.openxmlformats-officedocument.extended-properties+xml")) {
/* default: /docProps/app.xml */
tmp = unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff);
if (tmp == CL_ETIMEOUT) {
ret = tmp;
}
else if (tmp != CL_VIRUS) {
cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
}
else {
cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
ret = unzip_single_internal(ctx, loff, ooxml_extn_cb);
else if (!xmlStrcmp(CT, "application/vnd.openxmlformats-officedocument.extended-properties+xml")) {
if (!extn) {
/* default: /docProps/app.xml */
tmp = unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff);
if (tmp == CL_ETIMEOUT) {
ret = tmp;
}
else if (tmp != CL_VIRUS) {
cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
}
else {
cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
ret = unzip_single_internal(ctx, loff, ooxml_extn_cb);
}
}
extn = 1;
extn++;
}
else if (!cust && !xmlStrcmp(CT, "application/vnd.openxmlformats-officedocument.custom-properties+xml")) {
/* default: /docProps/custom.xml */
tmp = unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff);
if (tmp == CL_ETIMEOUT) {
ret = tmp;
}
else if (tmp != CL_VIRUS) {
cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
}
else {
cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
/* custom properties ignored for now */
cli_jsonbool(ctx->wrkproperty, "CustomProperties", 1);
//ret = unzip_single_internal(ctx, loff, ooxml_cust_cb);
else if (!xmlStrcmp(CT, "application/vnd.openxmlformats-officedocument.custom-properties+xml")) {
if (!cust) {
/* default: /docProps/custom.xml */
tmp = unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff);
if (tmp == CL_ETIMEOUT) {
ret = tmp;
}
else if (tmp != CL_VIRUS) {
cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
}
else {
cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
//ret = unzip_single_internal(ctx, loff, ooxml_cust_cb);
}
}
cust = 1;
cust++;
}
else if (!dsig && !xmlStrcmp(CT, "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")) {
tmp = unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff);
if (tmp == CL_ETIMEOUT) {
ret = tmp;
}
else if (tmp != CL_VIRUS) {
cli_dbgmsg("cli_process_ooxml: failed to find digital signature file \"%s\"!\n", PN);
}
else {
cli_dbgmsg("ooxml_content_cb: found digital signature file \"%s\" @ %x\n", PN, loff);
/* digital signatures ignored for now */
cli_jsonbool(ctx->wrkproperty, "DigitalSignatures", 1);
//ret = unzip_single_internal(ctx, loff, ooxml_dsig_cb);
}
dsig = 1;
else if (!xmlStrcmp(CT, "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")) {
dsig++;
}
if (ret != CL_SUCCESS)
goto ooxml_content_exit;
}
if (!core) {
if (core) {
cli_jsonint(ctx->wrkproperty, "CorePropertiesFileCount", core);
}
else {
cli_dbgmsg("cli_process_ooxml: file does not contain core properties file\n");
}
if (!extn) {
if (extn) {
cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesFileCount", extn);
}
else {
cli_dbgmsg("cli_process_ooxml: file does not contain extended properties file\n");
}
if (!cust) {
if (cust) {
cli_jsonint(ctx->wrkproperty, "CustomPropertiesFileCount", cust);
}
else {
cli_dbgmsg("cli_process_ooxml: file does not contain custom properties file\n");
}
if (dsig) {
cli_jsonint(ctx->wrkproperty, "DigitalSignaturesCount", dsig);
}
ooxml_content_exit:
xmlTextReaderClose(reader);

@ -480,15 +480,15 @@ static unsigned int chdr(fmap_t *map, uint32_t coff, uint32_t zsize, unsigned in
} else cli_dbgmsg("cli_unzip: ch - local hdr out of file\n");
}
else {
if (!last && !strncmp(request->name, name,
(request->namelen>=sizeof(name))?sizeof(name)-1:request->namelen)) {
size_t len = MIN(sizeof(name)-1, request->namelen);
if (!last && !strncmp(request->name, name, len)) {
request->found = 1;
request->loff = CH_off;
}
}
fmap_unneed_ptr(map, ch, SIZEOF_CH);
return last?0:coff;
return (last?0:coff);
}
int cli_unzip(cli_ctx *ctx) {

Loading…
Cancel
Save