void de_fmtutil_free_SAUCE(deark *c, struct de_SAUCE_info *si) { if(!si) return; ucstring_destroy(si->title); ucstring_destroy(si->artist); ucstring_destroy(si->organization); if(si->comments) { i64 k; for(k=0; k<si->num_comments; k++) { ucstring_destroy(si->comments[k].s); } de_free(c, si->comments); } de_free(c, si); }
static void destroy_attachment_data(deark *c, lctx *d) { if(!d->attachmentctx) return; ucstring_destroy(d->attachmentctx->filename); de_free(c, d->attachmentctx); d->attachmentctx = NULL; }
static void do_vorbis_comment_block(deark *c, lctx *d, dbuf *f, i64 pos1) { i64 pos = pos1; i64 n; i64 ncomments; i64 k; de_ucstring *s = NULL; n = dbuf_getu32le_p(f, &pos); if(pos+n > f->len) goto done; s = ucstring_create(c); dbuf_read_to_ucstring_n(f, pos, n, DE_DBG_MAX_STRLEN, s, 0, DE_ENCODING_UTF8); de_dbg(c, "vendor: \"%s\"", ucstring_getpsz_d(s)); pos += n; ncomments = dbuf_getu32le_p(f, &pos); de_dbg(c, "number of comments: %d", (int)ncomments); for(k=0; k<ncomments; k++) { if(pos+4 > f->len) goto done; n = dbuf_getu32le_p(f, &pos); if(pos+n > f->len) goto done; ucstring_empty(s); dbuf_read_to_ucstring_n(f, pos, n, DE_DBG_MAX_STRLEN, s, 0, DE_ENCODING_UTF8); de_dbg(c, "comment[%d]: \"%s\"", (int)k, ucstring_getpsz_d(s)); pos += n; } done: ucstring_destroy(s); }
static void do_extract_file(deark *c, lctx *d, de_int64 dir_pos, de_byte filetype_c64s, de_byte filetype) { de_int64 load_addr; de_int64 end_addr; de_int64 offset; dbuf *f = NULL; de_int64 payload_size; // = file_size-2 de_ucstring *fname = NULL; de_int64 fname_len; de_int64 i; de_int64 fnpos; de_finfo *fi = NULL; load_addr = de_getui16le(dir_pos+2); end_addr = de_getui16le(dir_pos+4); offset = de_getui32le(dir_pos+8); de_dbg(c, "load_addr=%d end_addr=%d offset=%d\n", (int)load_addr, (int)end_addr, (int)offset); // File name at pos+16 fnpos = dir_pos+16; // Find the length of the (space-padded) filename. fname_len = 0; for(i=15; i>=0; i--) { if(de_getbyte(fnpos+i)!=' ') { fname_len = i+1; break; } } de_dbg2(c, "filename length: %d\n", (int)fname_len); fname = ucstring_create(c); dbuf_read_to_ucstring(c->infile, fnpos, fname_len, fname, 0, DE_ENCODING_PETSCII); de_dbg(c, "filename: \"%s\"\n", ucstring_get_printable_sz(fname)); ucstring_append_sz(fname, ".prg", DE_ENCODING_ASCII); fi = de_finfo_create(c); de_finfo_set_name_from_ucstring(c, fi, fname); fi->original_filename_flag = 1; payload_size = end_addr - load_addr; if(payload_size < 0) { // TODO: Try to support files that don't have end_addr set properly. de_err(c, "This type of T64 file is not supported.\n"); goto done; } f = dbuf_create_output_file(c, NULL, fi, 0); dbuf_copy(c->infile, dir_pos+2, 2, f); dbuf_copy(c->infile, offset, payload_size, f); done: dbuf_close(f); de_finfo_destroy(c, fi); ucstring_destroy(fname); }
static void do_woz_META(deark *c, struct de_iffctx *ictx, const struct de_iffchunkctx *chunkctx) { i64 k; int reading_val; de_ucstring *s = NULL; de_ucstring *name = NULL; de_ucstring *val = NULL; // Read the entire metadata string. s = ucstring_create(c); dbuf_read_to_ucstring_n(ictx->f, chunkctx->dpos, chunkctx->dlen, 65536, s, 0, DE_ENCODING_UTF8); // Parse out the individual metadata items name = ucstring_create(c); val = ucstring_create(c); reading_val = 0; for(k=0; k<s->len; k++) { i32 ch = s->str[k]; if(ch==0x0a) { // End of item do_woz_print_metadata_item(c, name, val); ucstring_empty(name); ucstring_empty(val); reading_val = 0; } else if(ch==0x09 && !reading_val) { // Name/value separator reading_val = 1; } else { // A non-special character if(reading_val) { ucstring_append_char(val, ch); } else { ucstring_append_char(name, ch); } } } do_woz_print_metadata_item(c, name, val); ucstring_destroy(s); ucstring_destroy(name); ucstring_destroy(val); }
void de_destroy_stringreaderdata(deark *c, struct de_stringreaderdata *srd) { if(!srd) return; de_free(c, srd->sz); de_free(c, srd->sz_utf8); ucstring_destroy(srd->str); de_free(c, srd); }
static void decode_string(deark *c, lctx *d, const struct ele_id_info *ele_id, i64 pos, i64 len, int encoding) { de_ucstring *s = NULL; s = ucstring_create(c); dbuf_read_to_ucstring_n(c->infile, pos, len, DE_DBG_MAX_STRLEN, s, DE_CONVFLAG_STOP_AT_NUL, encoding); de_dbg(c, "value: \"%s\"", ucstring_getpsz_d(s)); ucstring_destroy(s); }
// If has_max!=0, uses no more than max_chars Unicode characters from s to create the // printable string. static void ucstring_to_printable_sz_internal(de_ucstring *s, char *szbuf, size_t szbuf_len, int has_max, de_int64 max_chars) { de_ucstring *s2 = NULL; s2 = ucstring_clone(s); if(has_max) { // TODO: Maybe this should add an ellipsis, or something. ucstring_truncate(s2, max_chars); } ucstring_make_printable(s2); ucstring_to_sz(s2, szbuf, szbuf_len, DE_ENCODING_UTF8); ucstring_destroy(s2); }
static void do_read_linked_profile(deark *c, lctx *d) { de_ucstring *fname = NULL; de_dbg(c, "linked profile filename at %d\n", (int)d->profile_offset); fname = ucstring_create(c); dbuf_read_to_ucstring_n(c->infile, d->profile_offset, d->profile_size, 300, fname, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_WINDOWS1252); de_dbg_indent(c, 1); de_dbg(c, "profile filename: \"%s\"\n", ucstring_get_printable_sz(fname)); de_dbg_indent(c, -1); ucstring_destroy(fname); }
// Print an element ID number, in the format used by the Matroska spec. static void print_encoded_id(deark *c, lctx *d, i64 pos, i64 len) { de_ucstring *s = NULL; i64 i; if(len>8) return; s = ucstring_create(c); for(i=0; i<len; i++) { ucstring_printf(s, DE_ENCODING_UTF8, "[%02x]", (unsigned int)de_getbyte(pos+i)); } de_dbg(c, "encoded id: %s", ucstring_getpsz_d(s)); ucstring_destroy(s); }
static void handle_text(deark *c, lctx *d, const struct ds_info *dsi, de_int64 pos, de_int64 len) { int encoding; de_ucstring *s = NULL; s = ucstring_create(c); encoding = get_ds_encoding(c, d, dsi->recnum); if(encoding==DE_ENCODING_UNKNOWN) encoding = DE_ENCODING_ASCII; dbuf_read_to_ucstring(c->infile, pos, len, s, 0, encoding); de_dbg(c, "%s: \"%s\"\n", dsi->dsname, ucstring_get_printable_sz_n(s, 300)); ucstring_destroy(s); }
static char *get_hdrtype_descr(deark *c, char *buf, size_t buflen, u8 hdr_type) { if(hdr_type==0) { de_strlcpy(buf, "", buflen); } else { de_ucstring *s = NULL; s = ucstring_create(c); if(hdr_type&0x01) ucstring_append_flags_item(s, "continuation page"); if(hdr_type&0x02) ucstring_append_flags_item(s, "first page"); if(hdr_type&0x04) ucstring_append_flags_item(s, "last page"); de_snprintf(buf, buflen, " (%s)", ucstring_getpsz(s)); ucstring_destroy(s); } return buf; }
static void do_woz_INFO(deark *c, struct de_iffctx *ictx, const struct de_iffchunkctx *chunkctx) { u8 b; i64 n; i64 pos = chunkctx->dpos; lctx *d = ictx->userdata; de_ucstring *s = NULL; if(chunkctx->dlen<37) return; b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "INFO chunk version: %d", (int)b); b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "disk type: %d (%s)", (int)b, get_woz_disk_type_name(b)); b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "write protected: %d", (int)b); b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "synchronized: %d", (int)b); b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "cleaned: %d", (int)b); s = ucstring_create(c); dbuf_read_to_ucstring(ictx->f, pos, 32, s, 0, DE_ENCODING_UTF8); ucstring_strip_trailing_spaces(s); de_dbg(c, "creator: \"%s\"", ucstring_getpsz(s)); pos += 32; if(d->wozver<'2') goto done; b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "disk sides: %d", (int)b); b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "boot sector format: %d", (int)b); b = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "optimal bit timing: %d", (int)b); n = dbuf_getu16le_p(ictx->f, &pos); de_dbg(c, "compatible hardware: %d", (int)n); n = dbuf_getu16le_p(ictx->f, &pos); de_dbg(c, "required RAM: %dK", (int)n); n = dbuf_getu16le_p(ictx->f, &pos); de_dbg(c, "largest track: %d blocks", (int)n); done: ucstring_destroy(s); }
static void extract_unknown_ole_obj(deark *c, lctx *d, i64 pos, i64 len, struct de_stringreaderdata *srd_typename) { de_finfo *fi = NULL; de_ucstring *s = NULL; fi = de_finfo_create(c); s = ucstring_create(c); ucstring_append_sz(s, "oleobj", DE_ENCODING_LATIN1); if(ucstring_isnonempty(srd_typename->str)) { ucstring_append_sz(s, ".", DE_ENCODING_LATIN1); ucstring_append_ucstring(s, srd_typename->str); } de_finfo_set_name_from_ucstring(c, fi, s, 0); dbuf_create_file_from_slice(c->infile, pos, len, "bin", fi, 0); ucstring_destroy(s); de_finfo_destroy(c, fi); }
// Caption/abstract static void handle_2_120(deark *c, lctx *d, const struct ds_info *dsi, de_int64 pos, de_int64 len) { de_ucstring *s = NULL; dbuf *outf = NULL; int encoding; const char *fntoken; if(c->extract_level<2) { handle_text(c, d, dsi, pos, len); goto done; } // FIXME: There is currently no way to extract IPTC captions to files, // except when reading a raw IPTC file. If IPTC is embedded in some other // file (as it usually is), then the -a option will extract the entire // IPTC data, and we will never get here. fntoken = "caption.txt"; encoding = get_ds_encoding(c, d, dsi->recnum); if(encoding==DE_ENCODING_UNKNOWN) { // If the encoding is unknown, copy the raw bytes. dbuf_create_file_from_slice(c->infile, pos, len, fntoken, NULL, DE_CREATEFLAG_IS_AUX); goto done; } // If the encoding is known, convert to UTF-8. s = ucstring_create(c); dbuf_read_to_ucstring(c->infile, pos, len, s, 0, encoding); outf = dbuf_create_output_file(c, fntoken, NULL, DE_CREATEFLAG_IS_AUX); ucstring_write_as_utf8(c, s, outf, 1); done: if(outf) dbuf_close(outf); if(s) ucstring_destroy(s); }
static void do_para_fprop(deark *c, lctx *d, struct para_info *pinfo, i64 bfprop, u8 is_dup) { i64 fprop_dlen = 0; // bfprop is a pointer into the 123 bytes of data starting // at pos+4. The maximum sensible value is at most 122. if(bfprop<=122) { // It appears that the length prefix does not include itself, // contrary to what one source says. fprop_dlen = (i64)de_getbyte(pinfo->bfprop_offset); if(!is_dup) de_dbg(c, "fprop dlen: %d", (int)fprop_dlen); } if(fprop_dlen>=2) { pinfo->justification = de_getbyte(pinfo->bfprop_offset + 1 + 1) & 0x03; if(!is_dup && pinfo->justification!=0) { de_dbg(c, "justification: %d", (int)pinfo->justification); } } if(fprop_dlen>=17) { pinfo->papflags = de_getbyte(pinfo->bfprop_offset + 1 + 16); if(!is_dup) { de_ucstring *flagstr = ucstring_create(c); if(pinfo->papflags&0x06) { ucstring_append_flags_item(flagstr, (pinfo->papflags&0x01)?"footer":"header"); ucstring_append_flags_item(flagstr, (pinfo->papflags&0x08)?"print on first page": "do not print on first page"); } if(pinfo->papflags&0x10) ucstring_append_flags_item(flagstr, "picture"); de_dbg(c, "paragraph flags: 0x%02x (%s)", (unsigned int)pinfo->papflags, ucstring_getpsz(flagstr)); ucstring_destroy(flagstr); } } }
static int do_gzip_read_member(deark *c, lctx *d, i64 pos1, i64 *member_size) { u8 b0, b1; i64 pos; i64 n; i64 foundpos; i64 string_len; i64 cmpr_data_len; i64 mod_time_unix; u32 crc_calculated; de_ucstring *member_name = NULL; int saved_indent_level; int ret; struct member_data *md = NULL; int retval = 0; md = de_malloc(c, sizeof(struct member_data)); de_dbg_indent_save(c, &saved_indent_level); de_dbg(c, "gzip member at %d", (int)pos1); de_dbg_indent(c, 1); pos = pos1; b0 = de_getbyte(pos+0); b1 = de_getbyte(pos+1); if(b0!=0x1f || b1!=0x8b) { de_err(c, "Invalid gzip signature at %d. This is not a valid gzip file.", (int)pos1); goto done; } md->cmpr_code = de_getbyte(pos+2); if(md->cmpr_code!=0x08) { de_err(c, "Unsupported compression type (%d)", (int)md->cmpr_code); goto done; } md->flags = de_getbyte(pos+3); de_dbg(c, "flags: 0x%02x", (unsigned int)md->flags); pos += 4; mod_time_unix = de_getu32le(pos); de_unix_time_to_timestamp(mod_time_unix, &md->mod_time_ts, 0x1); if(md->mod_time_ts.is_valid) { char timestamp_buf[64]; de_timestamp_to_string(&md->mod_time_ts, timestamp_buf, sizeof(timestamp_buf), 0); de_dbg(c, "mod time: %" I64_FMT " (%s)", mod_time_unix, timestamp_buf); } pos += 4; b0 = de_getbyte(pos++); de_dbg(c, "extra flags: 0x%02x", (unsigned int)b0); b0 = de_getbyte(pos++); de_dbg(c, "OS or filesystem: %d (%s)", (int)b0, get_os_name(b0)); if(md->flags & GZIPFLAG_FEXTRA) { n = de_getu16le(pos); // XLEN // TODO: It might be interesting to dissect these extra fields, but it's // hard to find even a single file that uses them. de_dbg(c, "[extra fields at %d, dpos=%d, dlen=%d]", (int)pos, (int)(pos+2), (int)n); pos += 2; pos += n; } if(md->flags & GZIPFLAG_FNAME) { ret = dbuf_search_byte(c->infile, 0x00, pos, c->infile->len - pos, &foundpos); if(!ret) { de_err(c, "Invalid NAME field"); goto done; } string_len = foundpos - pos; member_name = ucstring_create(c); #define DE_GZIP_MAX_FNLEN 300 dbuf_read_to_ucstring_n(c->infile, pos, string_len, DE_GZIP_MAX_FNLEN, member_name, 0, DE_ENCODING_LATIN1); de_dbg(c, "file name at %d, len=%d: \"%s\"", (int)pos, (int)string_len, ucstring_getpsz_d(member_name)); pos = foundpos + 1; } if(md->flags & GZIPFLAG_FCOMMENT) { ret = dbuf_search_byte(c->infile, 0x00, pos, c->infile->len - pos, &foundpos); if(!ret) { de_err(c, "Invalid COMMENT field"); goto done; } pos = foundpos + 1; } if(md->flags & GZIPFLAG_FHCRC) { md->crc16_reported = (u32)de_getu16le(pos); de_dbg(c, "crc16 (reported): 0x%04x", (unsigned int)md->crc16_reported); pos += 2; } de_dbg(c, "compressed blocks at %d", (int)pos); if(!d->output_file) { // Although any member can have a name and mod time, this metadata // is ignored for members after the first one. de_finfo *fi = NULL; fi = de_finfo_create(c); if(member_name && c->filenames_from_file) { de_finfo_set_name_from_ucstring(c, fi, member_name, 0); fi->original_filename_flag = 1; } if(md->mod_time_ts.is_valid) { fi->mod_time = md->mod_time_ts; } d->output_file = dbuf_create_output_file(c, member_name?NULL:"bin", fi, 0); de_finfo_destroy(c, fi); } d->output_file->writecallback_fn = our_writecallback; d->output_file->userdata = (void*)md; md->crco = d->crco; de_crcobj_reset(md->crco); ret = de_decompress_deflate(c->infile, pos, c->infile->len - pos, d->output_file, 0, &cmpr_data_len, 0); crc_calculated = de_crcobj_getval(md->crco); d->output_file->writecallback_fn = NULL; d->output_file->userdata = NULL; if(!ret) goto done; pos += cmpr_data_len; de_dbg(c, "crc32 (calculated): 0x%08x", (unsigned int)crc_calculated); md->crc32_reported = (u32)de_getu32le(pos); de_dbg(c, "crc32 (reported) : 0x%08x", (unsigned int)md->crc32_reported); pos += 4; if(crc_calculated != md->crc32_reported) { de_warn(c, "CRC check failed: Expected 0x%08x, got 0x%08x", (unsigned int)md->crc32_reported, (unsigned int)crc_calculated); } md->isize = de_getu32le(pos); de_dbg(c, "uncompressed size (mod 2^32): %u", (unsigned int)md->isize); pos += 4; retval = 1; done: if(retval) *member_size = pos - pos1; else *member_size = 0; ucstring_destroy(member_name); de_free(c, md); de_dbg_indent_restore(c, saved_indent_level); return retval; }
static void do_read_extension_area(deark *c, lctx *d, i64 pos) { i64 ext_area_size; i64 k; int has_date; de_ucstring *s = NULL; i64 val[6]; de_dbg(c, "extension area at %d", (int)pos); if(pos > c->infile->len - 2) { de_warn(c, "Bad extension area offset: %u", (unsigned int)pos); return; } de_dbg_indent(c, 1); s = ucstring_create(c); ext_area_size = de_getu16le(pos); de_dbg(c, "extension area size: %d", (int)ext_area_size); if(ext_area_size<495) goto done; d->has_extension_area = 1; ucstring_empty(s); dbuf_read_to_ucstring(c->infile, pos+2, 41, s, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); ucstring_strip_trailing_spaces(s); de_dbg(c, "author: \"%s\"", ucstring_getpsz_d(s)); for(k=0; k<4; k++) { ucstring_empty(s); dbuf_read_to_ucstring(c->infile, pos+43+81*k, 81, s, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); ucstring_strip_trailing_spaces(s); de_dbg(c, "comment line %d: \"%s\"", (int)k, ucstring_getpsz_d(s)); } // date/time: pos=367, size=12 has_date = 0; for(k=0; k<6; k++) { val[k] = de_getu16le(pos+367+2*k); if(val[k]!=0) has_date = 1; } if(has_date) { char timestamp_buf[64]; de_make_timestamp(&d->mod_time, val[2], val[0], val[1], val[3], val[4], val[5]); d->mod_time.tzcode = DE_TZCODE_LOCAL; de_timestamp_to_string(&d->mod_time, timestamp_buf, sizeof(timestamp_buf), 0); de_dbg(c, "timestamp: %s", timestamp_buf); } // Job name: pos=379, size=41 (not implemented) // Job time: pos=420, size=6 (not implemented) ucstring_empty(s); dbuf_read_to_ucstring(c->infile, pos+426, 41, s, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); ucstring_strip_trailing_spaces(s); de_dbg(c, "software id: \"%s\"", ucstring_getpsz_d(s)); val[0] = de_getu16le(pos+467); val[1] = (i64)de_getbyte(pos+469); if(val[0]!=0 || val[1]!=32) { de_dbg(c, "software version: %u,%u,%u", (unsigned int)(val[0]/100), (unsigned int)(val[0]%100), (unsigned int)val[1]); } val[0] = de_getu32le(pos+470); if(val[0]!=0) { de_dbg(c, "background color: 0x%08x", (unsigned int)val[0]); } // TODO: Retain the aspect ratio. (Need sample files. Nobody seems to use this field.) d->aspect_ratio_num = de_getu16le(pos+474); d->aspect_ratio_den = de_getu16le(pos+476); if(d->aspect_ratio_den!=0) { de_dbg(c, "aspect ratio: %d/%d", (int)d->aspect_ratio_num, (int)d->aspect_ratio_den); } // Gamma: pos=478, size=4 (not implemented) // Color correction table offset: pos=482, size=4 (not implemented) d->thumbnail_offset = de_getu32le(pos+486); de_dbg(c, "thumbnail image offset: %d", (int)d->thumbnail_offset); val[0] = de_getu32le(pos+490); de_dbg(c, "scan line table offset: %"I64_FMT, val[0]); d->attributes_type = de_getbyte(pos+494); de_dbg(c, "attributes type: %d", (int)d->attributes_type); if(d->attributes_type==0 && d->num_attribute_bits!=0) { de_warn(c, "Incompatible \"number of attribute bits\" (%d) and \"attributes type\" " "(%d) fields. Transparency may not be handled correctly.", (int)d->num_attribute_bits, (int)d->attributes_type); } done: de_dbg_indent(c, -1); ucstring_destroy(s); }
static int do_gzip_read_member(deark *c, lctx *d, de_int64 pos1, de_int64 *member_size) { de_byte b0, b1; de_int64 cmpr_code; de_int64 pos; de_int64 n; de_int64 foundpos; de_int64 string_len; de_int64 cmpr_data_len; de_int64 isize; de_int64 mod_time_unix; struct de_timestamp mod_time_ts; de_uint32 crc32_field; de_ucstring *member_name = NULL; de_finfo *fi = NULL; int saved_indent_level; int ret; int retval = 0; mod_time_ts.is_valid = 0; de_dbg_indent_save(c, &saved_indent_level); de_dbg(c, "gzip member at %d\n", (int)pos1); de_dbg_indent(c, 1); pos = pos1; b0 = de_getbyte(pos+0); b1 = de_getbyte(pos+1); if(b0!=0x1f || b1!=0x8b) { de_err(c, "Invalid gzip signature at %d. This is not a valid gzip file.\n", (int)pos1); goto done; } cmpr_code=de_getbyte(pos+2); if(cmpr_code!=0x08) { de_err(c, "Unsupported compression type (%d)\n", (int)cmpr_code); goto done; } d->flags = de_getbyte(pos+3); de_dbg(c, "flags: 0x%02x\n", (unsigned int)d->flags); pos += 4; mod_time_unix = de_getui32le(pos); de_unix_time_to_timestamp(mod_time_unix, &mod_time_ts); if(mod_time_ts.is_valid) { char timestamp_buf[64]; de_timestamp_to_string(&mod_time_ts, timestamp_buf, sizeof(timestamp_buf), 1); de_dbg(c, "mod time: %" INT64_FMT " (%s)\n", mod_time_unix, timestamp_buf); } pos += 4; b0 = de_getbyte(pos++); de_dbg(c, "extra flags: 0x%02x\n", (unsigned int)b0); b0 = de_getbyte(pos++); de_dbg(c, "OS or filesystem: %d (%s)\n", (int)b0, get_os_name(b0)); if(d->flags & GZIPFLAG_FEXTRA) { n = de_getui16le(pos); // XLEN // TODO: It might be interesting to dissect these extra fields, but it's // hard to find even a single file that uses them. de_dbg(c, "[extra fields at %d, dpos=%d, dlen=%d]\n", (int)pos, (int)(pos+2), (int)n); pos += 2; pos += n; } if(d->flags & GZIPFLAG_FNAME) { ret = dbuf_search_byte(c->infile, 0x00, pos, c->infile->len - pos, &foundpos); if(!ret) { de_err(c, "Invalid NAME field\n"); goto done; } string_len = foundpos - pos; member_name = ucstring_create(c); dbuf_read_to_ucstring_n(c->infile, pos, string_len, 300, member_name, 0, DE_ENCODING_LATIN1); de_dbg(c, "file name at %d, len=%d: \"%s\"\n", (int)pos, (int)string_len, ucstring_get_printable_sz(member_name)); pos = foundpos + 1; } if(d->flags & GZIPFLAG_FCOMMENT) { ret = dbuf_search_byte(c->infile, 0x00, pos, c->infile->len - pos, &foundpos); if(!ret) { de_err(c, "Invalid COMMENT field\n"); goto done; } pos = foundpos + 1; } if(d->flags & GZIPFLAG_FHCRC) { pos += 2; } de_dbg(c, "compressed blocks at %d\n", (int)pos); if(!d->output_file) { fi = de_finfo_create(c); if(member_name && c->filenames_from_file) { de_finfo_set_name_from_ucstring(c, fi, member_name); fi->original_filename_flag = 1; } if(mod_time_ts.is_valid) { fi->mod_time = mod_time_ts; } d->output_file = dbuf_create_output_file(c, member_name?NULL:"bin", fi, 0); } ret = de_uncompress_deflate(c->infile, pos, c->infile->len - pos, d->output_file, &cmpr_data_len); if(!ret) goto done; pos += cmpr_data_len; crc32_field = (de_uint32)de_getui32le(pos); de_dbg(c, "crc32: 0x%08x\n", (unsigned int)crc32_field); pos += 4; // TODO: Validate CRCs isize = de_getui32le(pos); de_dbg(c, "uncompressed size (mod 2^32): %u\n", (unsigned int)isize); pos += 4; retval = 1; done: if(retval) *member_size = pos - pos1; else *member_size = 0; ucstring_destroy(member_name); de_finfo_destroy(c, fi); de_dbg_indent_restore(c, saved_indent_level); return retval; }
static void do_card_index(deark *c, lctx *d, de_int64 cardnum, de_int64 pos) { de_int64 datapos; de_int64 bitmap_len; de_int64 w, h; de_int64 src_rowspan; de_int64 text_len; de_int64 text_pos; struct deark_bitmap *img = NULL; de_finfo *fi_bitmap = NULL; de_finfo *fi_text = NULL; const char *cardtype; de_ucstring *name = NULL; int saved_indent_level; de_dbg_indent_save(c, &saved_indent_level); datapos = de_getui32le(pos+6); de_dbg(c, "card #%d at %d, dpos=%d\n", (int)cardnum, (int)pos, (int)datapos); de_dbg_indent(c, 1); if(datapos>=c->infile->len) goto done; bitmap_len = de_getui16le(datapos); de_dbg(c, "bitmap length: %d\n", (int)bitmap_len); if(bitmap_len==0) { text_len = de_getui16le(datapos+2); text_pos = datapos+4; } else { text_len = de_getui16le(datapos + bitmap_len + 10); text_pos = datapos + bitmap_len + 10; } de_dbg(c, "text length: %d\n", (int)text_len); if(bitmap_len==0 && text_len==0) { cardtype = "empty"; } else if(bitmap_len==0) { cardtype = "text-only"; } else if(text_len==0) { cardtype = "graphics-only"; } else { cardtype = "graphics+text"; } de_dbg(c, "card type: %s\n", cardtype); if(bitmap_len==0 && text_len==0) { goto done; } name = ucstring_create(c); dbuf_read_to_ucstring(c->infile, pos+11, 40, name, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); de_dbg(c, "name: \"%s\"\n", ucstring_get_printable_sz(name)); // Text if(text_len!=0 && c->extract_level>=2) { fi_text = de_finfo_create(c); if(c->filenames_from_file) de_finfo_set_name_from_ucstring(c, fi_text, name); do_text_data(c, d, fi_text, text_pos, text_len); } // Bitmap if(bitmap_len==0) goto done; fi_bitmap = de_finfo_create(c); if(c->filenames_from_file) de_finfo_set_name_from_ucstring(c, fi_bitmap, name); w = de_getui16le(datapos+2); h = de_getui16le(datapos+4); de_dbg(c, "bitmap dimensions: %dx%d\n", (int)w, (int)h); img = de_bitmap_create(c, w, h, 1); src_rowspan = ((w+15)/16)*2; de_convert_and_write_image_bilevel(c->infile, datapos+10, w, h, src_rowspan, 0, fi_bitmap, 0); done: ucstring_destroy(name); de_bitmap_destroy(img); de_finfo_destroy(c, fi_bitmap); de_finfo_destroy(c, fi_text); de_dbg_indent_restore(c, saved_indent_level); }