static void on_im_generic_profile_keyword(deark *c, lctx *d, struct text_chunk_ctx *tcc, struct de_stringreaderdata *srd) { char typestr[32]; tcc->is_im_generic_profile = 1; tcc->im_generic_profile_type = 0; tcc->im_generic_profile_type_name = NULL; tcc->suppress_debugstr = 1; de_bytes_to_printable_sz((const u8*)(srd->sz+17), de_strlen(srd->sz+17), typestr, sizeof(typestr), 0, DE_ENCODING_ASCII); if(!de_strcmp(typestr, "8bim")) { tcc->im_generic_profile_type = PROFILETYPE_8BIM; tcc->im_generic_profile_type_name = "Photoshop"; } else if(!de_strcmp(typestr, "iptc")) { tcc->im_generic_profile_type = PROFILETYPE_IPTC; tcc->im_generic_profile_type_name = "IPTC"; } else if(!de_strcmp(typestr, "xmp")) { tcc->im_generic_profile_type = PROFILETYPE_XMP; tcc->im_generic_profile_type_name = "XMP"; } else if(!de_strcmp(typestr, "icc")) { tcc->im_generic_profile_type = PROFILETYPE_ICC; tcc->im_generic_profile_type_name = "ICC"; } else { if(c->extract_level<2) { tcc->suppress_debugstr = 0; } } }
static int do_picture_ole_static_rendition(deark *c, lctx *d, struct para_info *pinfo, int rendition_idx, i64 pos1, i64 *bytes_consumed) { i64 pos = pos1; i64 stringlen; struct de_stringreaderdata *srd_typename = NULL; pos += 4; // 0x00000501 pos += 4; // "type" (probably already read by caller) stringlen = de_getu32le_p(&pos); srd_typename = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); de_dbg(c, "typename: \"%s\"", ucstring_getpsz(srd_typename->str)); pos += stringlen; if(!de_strcmp(srd_typename->sz, "DIB")) { pos += 12; de_dbg_indent(c, 1); de_run_module_by_id_on_slice(c, "dib", NULL, c->infile, pos, pinfo->thisparapos+pinfo->thisparalen-pos); de_dbg_indent(c, -1); } else if(!de_strcmp(srd_typename->sz, "METAFILEPICT")) { i64 dlen; pos += 8; // ?? dlen = de_getu32le_p(&pos); de_dbg(c, "metafile size: %d", (int)dlen); // Includes "mfp", apparently pos += 8; // "mfp" struct dbuf_create_file_from_slice(c->infile, pos, dlen-8, "wmf", NULL, 0); } else if(!de_strcmp(srd_typename->sz, "BITMAP")) { do_static_bitmap(c, d, pinfo, pos); } else { de_warn(c, "Static OLE picture type \"%s\" is not supported", ucstring_getpsz(srd_typename->str)); } de_destroy_stringreaderdata(c, srd_typename); return 0; }
static int module_compare_fn(const void *a, const void *b) { struct sort_data_struct *m1, *m2; deark *c; m1 = (struct sort_data_struct *)a; m2 = (struct sort_data_struct *)b; c = m1->c; return de_strcmp(c->module_info[m1->module_index].id, c->module_info[m2->module_index].id); }
static int read_pam_header(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1) { int ret; de_int64 pos = pos1; int retval = 0; char linebuf[200]; char token1buf[200]; //char token2buf[200]; de_dbg(c, "header at %d\n", (int)pos1); de_dbg_indent(c, 1); de_err(c, "PAM format not supported\n"); goto done; pos += 3; // Skip "P7\n" while(1) { de_int64 content_len; de_int64 total_len; de_int64 curpos; //ret = dbuf_find_line(c->infile, pos, // &content_len, &total_len); ret = read_pam_header_line(c, d, pg, pos, &content_len, &total_len, linebuf, sizeof(linebuf)); if(!ret) { de_err(c, "Invalid PAM header\n"); break; } if(content_len>0 && (de_getbyte(pos)=='#')) { // comment line pos += total_len; continue; } curpos = 0; if(!read_next_pam_token(c, d, pg, linebuf, token1buf, sizeof(token1buf), &curpos)) goto done; if(!de_strcmp(token1buf,"ENDHDR")) { break; } pos += total_len; continue; } retval = 1; done: de_dbg_indent(c, -1); return retval; }
int ucstring_strcmp(de_ucstring *s, const char *s2, int encoding) { size_t s2len; char *tmpbuf; int ret; if(!s && !s2) return 0; if(!s || !s2) return 1; s2len = de_strlen(s2); tmpbuf = de_malloc(s->c, s2len+1); ucstring_to_sz(s, tmpbuf, s2len+1, encoding); ret = de_strcmp(tmpbuf, tmpbuf); de_free(s->c, tmpbuf); return ret; }
// An internal function that does the main work of do_text_field(). // TODO: Clean up the text field processing code. It's gotten too messy. static int do_unc_text_field(deark *c, lctx *d, struct text_chunk_ctx *tcc, int which_field, dbuf *srcdbuf, i64 pos, i64 bytes_avail, int is_nul_terminated, int encoding, i64 *bytes_consumed) { const char *name; int retval = 0; struct de_stringreaderdata *srd = NULL; *bytes_consumed = 0; if(bytes_avail<0) return 0; if(which_field==FIELD_MAIN && tcc->is_xmp) { // The main field is never NUL terminated, so we can do this right away. dbuf_create_file_from_slice(srcdbuf, pos, bytes_avail, "xmp", NULL, DE_CREATEFLAG_IS_AUX); retval = 1; goto done; } if(is_nul_terminated) { srd = dbuf_read_string(srcdbuf, pos, bytes_avail, DE_DBG_MAX_STRLEN, DE_CONVFLAG_STOP_AT_NUL, encoding); if(!srd->found_nul) goto done; *bytes_consumed = srd->bytes_consumed - 1; } else { i64 bytes_to_scan; *bytes_consumed = bytes_avail; bytes_to_scan = bytes_avail; if(bytes_to_scan>DE_DBG_MAX_STRLEN) bytes_to_scan = DE_DBG_MAX_STRLEN; srd = dbuf_read_string(srcdbuf, pos, bytes_to_scan, bytes_to_scan, 0, encoding); } if(which_field==FIELD_KEYWORD) { if(!de_strcmp(srd->sz, "XML:com.adobe.xmp")) { tcc->is_xmp = 1; } } switch(which_field) { case FIELD_KEYWORD: name="keyword"; break; case FIELD_LANG: name="language"; break; case FIELD_XKEYWORD: name="translated keyword"; break; default: name="text"; } if(which_field==FIELD_MAIN && tcc->is_im_generic_profile) { de_dbg(c, "generic profile type: %s", tcc->im_generic_profile_type_name?tcc->im_generic_profile_type_name:"?"); } if(!(which_field==FIELD_MAIN && tcc->suppress_debugstr)) { de_dbg(c, "%s: \"%s\"", name, ucstring_getpsz(srd->str)); } retval = 1; if(which_field==FIELD_KEYWORD) { if(!de_strncmp(srd->sz, "Raw profile type ", 17)) { on_im_generic_profile_keyword(c, d, tcc, srd); } } if(which_field==FIELD_MAIN && tcc->is_im_generic_profile) { de_dbg_indent(c, 1); on_im_generic_profile_main(c, d, tcc, srcdbuf, pos, bytes_avail); de_dbg_indent(c, -1); goto done; } done: de_destroy_stringreaderdata(c, srd); return retval; }
// pos1 points to the ole_id field (should be 0x00000501). // Caller must have looked ahead to check the type. static int do_picture_ole_embedded_rendition(deark *c, lctx *d, struct para_info *pinfo, int rendition_idx, i64 pos1, i64 *bytes_consumed) { i64 pos = pos1; i64 stringlen; i64 data_len; u8 buf[16]; struct de_stringreaderdata *srd_typename = NULL; struct de_stringreaderdata *srd_filename = NULL; struct de_stringreaderdata *srd_params = NULL; pos += 4; // 0x00000501 pos += 4; // "type" (probably already read by caller) stringlen = de_getu32le_p(&pos); srd_typename = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); de_dbg(c, "typename: \"%s\"", ucstring_getpsz(srd_typename->str)); pos += stringlen; stringlen = de_getu32le_p(&pos); srd_filename = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); de_dbg(c, "filename: \"%s\"", ucstring_getpsz(srd_filename->str)); pos += stringlen; stringlen = de_getu32le_p(&pos); srd_params = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); de_dbg(c, "params: \"%s\"", ucstring_getpsz(srd_params->str)); pos += stringlen; data_len = de_getu32le_p(&pos); de_dbg(c, "embedded ole rendition data: pos=%d, len=%d", (int)pos, (int)data_len); // TODO: I don't know the extent to which it's better to sniff the data, or // rely on the typename. de_read(buf, pos, sizeof(buf)); if(!de_strcmp(srd_typename->sz, "CDraw") && !de_memcmp(&buf[0], (const void*)"RIFF", 4) && !de_memcmp(&buf[8], (const void*)"CDR", 3) ) { // Looks like CorelDRAW dbuf_create_file_from_slice(c->infile, pos, data_len, "cdr", NULL, 0); } else if(buf[0]=='B' && buf[1]=='M') { // TODO: Detect true length of data dbuf_create_file_from_slice(c->infile, pos, data_len, "bmp", NULL, 0); } else { if(d->extract_ole) { extract_unknown_ole_obj(c, d, pos, data_len, srd_typename); } else { de_warn(c, "Unknown/unsupported type of OLE object (\"%s\") at %d", ucstring_getpsz(srd_typename->str), (int)pos1); } } pos += data_len; *bytes_consumed = pos - pos1; de_destroy_stringreaderdata(c, srd_typename); de_destroy_stringreaderdata(c, srd_filename); de_destroy_stringreaderdata(c, srd_params); return 1; }