unsigned char *cli_mpool_hex2str(mpool_t *mp, const unsigned char *hex) { unsigned char *str; size_t len = strlen((const char*)hex); if (len&1) { cli_errmsg("cli_hex2str(): Malformed hexstring: %s (length: %u)\n", hex, (unsigned)len); return NULL; } str = mpool_malloc(mp, (len/2) + 1); if (cli_hex2str_to(hex, str, len) == -1) { mpool_free(mp, str); return NULL; } str[len/2] = '\0'; return str; }
char *cli_hex2str(const char *hex) { char *str; size_t len; len = strlen(hex); if(len % 2 != 0) { cli_errmsg("cli_hex2str(): Malformed hexstring: %s (length: %u)\n", hex, (unsigned)len); return NULL; } str = cli_calloc((len / 2) + 1, sizeof(char)); if(!str) return NULL; if (cli_hex2str_to(hex, str, len) == -1) { free(str); return NULL; } return str; }
int hm_addhash_str(struct cli_matcher *root, const char *strhash, uint32_t size, const char *virusname) { enum CLI_HASH_TYPE type; char binhash[CLI_HASHLEN_MAX]; int hlen; if(!root || !strhash) { cli_errmsg("hm_addhash_str: NULL root or hash\n"); return CL_ENULLARG; } /* size 0 here is now a wildcard size match */ if(size == (uint32_t)-1) { cli_errmsg("hm_addhash_str: null or invalid size (%u)\n", size); return CL_EARG; } hlen = strlen(strhash); switch(hlen) { case 32: type = CLI_HASH_MD5; break; case 40: type = CLI_HASH_SHA1; break; case 64: type = CLI_HASH_SHA256; break; default: cli_errmsg("hm_addhash_str: invalid hash %s -- FIXME!\n", strhash); return CL_EARG; } if(cli_hex2str_to(strhash, (char *)binhash, hlen)) { cli_errmsg("hm_addhash_str: invalid hash %s\n", strhash); return CL_EARG; } return hm_addhash_bin(root, binhash, type, size, virusname); }
struct pdf_dict *pdf_parse_dict(struct pdf_struct *pdf, struct pdf_obj *obj, size_t objsz, char *begin, char **endchar) { struct pdf_dict *res=NULL; struct pdf_dict_node *node=NULL; const char *objstart; char *end; unsigned int in_string=0, ninner=0; /* Sanity checking */ if (!(pdf) || !(obj) || !(begin)) return NULL; objstart = (const char *)(obj->start + pdf->map); if (begin < objstart || (size_t)(begin - objstart) >= objsz - 2) return NULL; if (begin[0] != '<' || begin[1] != '<') return NULL; /* Find the end of the dictionary */ end = begin; while ((size_t)(end - objstart) < objsz) { int increment=1; if (in_string) { if (*end == '\\') { end += 2; continue; } if (*end == ')') in_string = 0; end++; continue; } switch (*end) { case '(': in_string=1; break; case '<': if ((size_t)(end - objstart) <= objsz - 2 && end[1] == '<') ninner++; increment=2; break; case '>': if ((size_t)(end - objstart) <= objsz - 2 && end[1] == '>') ninner--; increment=2; break; } if ((size_t)(end - objstart) <= objsz - 2) if (end[0] == '>' && end[1] == '>' && ninner == 0) break; end += increment; } /* More sanity checking */ if ((size_t)(end - objstart) >= objsz - 2) return NULL; if (end[0] != '>' || end[1] != '>') return NULL; res = cli_calloc(1, sizeof(struct pdf_dict)); if (!(res)) return NULL; /* Loop through each element of the dictionary */ begin += 2; while (begin < end) { char *val=NULL, *key=NULL, *p1, *p2; struct pdf_dict *dict=NULL; struct pdf_array *arr=NULL; unsigned int nhex=0, i; /* Skip any whitespaces */ while (begin < end && isspace(begin[0])) begin++; if (begin == end) break; /* Get the key */ p1 = begin+1; while (p1 < end && !isspace(p1[0])) { int breakout=0; switch (*p1) { case '<': case '[': case '(': case '/': case '\r': case '\n': case ' ': case '\t': breakout=1; break; case '#': /* Key name obfuscated with hex characters */ nhex++; if (p1 > end-3) { return res; } break; } if (breakout) break; p1++; } if (p1 == end) break; key = cli_calloc((p1 - begin) + 2, 1); if (!(key)) break; if (nhex == 0) { /* Key isn't obfuscated with hex. Just copy the string */ strncpy(key, begin, p1 - begin); key[p1 - begin] = '\0'; } else { for (i=0, p2 = begin; p2 < p1; p2++, i++) { if (*p2 == '#') { cli_hex2str_to(p2+1, key+i, 2); p2 += 2; } else { key[i] = *p2; } } } /* Now for the value */ begin = p1; /* Skip any whitespaces */ while (begin < end && isspace(begin[0])) begin++; if (begin == end) { free(key); break; } switch (begin[0]) { case '(': val = pdf_parse_string(pdf, obj, begin, objsz, NULL, &p1, NULL); begin = p1+2; break; case '[': arr = pdf_parse_array(pdf, obj, objsz, begin, &p1); begin = p1+1; break; case '<': if ((size_t)(begin - objstart) < objsz - 2) { if (begin[1] == '<') { dict = pdf_parse_dict(pdf, obj, objsz, begin, &p1); begin = p1+2; break; } } val = pdf_parse_string(pdf, obj, begin, objsz, NULL, &p1, NULL); begin = p1+2; break; default: p1 = (begin[0] == '/') ? begin+1 : begin; while (p1 < end) { int shouldbreak = 0; switch (p1[0]) { case '>': case '/': shouldbreak=1; break; } if (shouldbreak) break; p1++; } is_object_reference(begin, &p1, NULL); val = cli_calloc((p1 - begin) + 2, 1); if (!(val)) break; strncpy(val, begin, p1 - begin); val[p1 - begin] = '\0'; if (p1[0] != '/') begin = p1+1; else begin = p1; break; } if (!(val) && !(dict) && !(arr)) { free(key); break; } if (!(res->nodes)) { res->nodes = res->tail = node = cli_calloc(1, sizeof(struct pdf_dict_node)); if (!(node)) { free(key); if (dict) pdf_free_dict(dict); if (val) free(val); if (arr) pdf_free_array(arr); break; } } else { node = calloc(1, sizeof(struct pdf_dict_node)); if (!(node)) { free(key); if (dict) pdf_free_dict(dict); if (val) free(val); if (arr) pdf_free_array(arr); break; } node->prev = res->tail; if (res->tail) res->tail->next = node; res->tail = node; } node->key = key; if ((val)) { node->value = val; node->valuesz = strlen(val); node->type = PDF_DICT_STRING; } else if ((arr)) { node->value = arr; node->valuesz = sizeof(struct pdf_array); node->type = PDF_DICT_ARRAY; } else if ((dict)) { node->value = dict; node->valuesz = sizeof(struct pdf_dict); node->type = PDF_DICT_DICT; } } if (endchar) *endchar = end; return res; }