static void decd_siz(ub4 *csize, ub4 *usize, ub2 *fnlen, ub2 *eflen, ub2 *flags, ub2 *method, ub1 *file_header) { *csize = UNPACK_UB4(file_header, LOC_CSIZE); #ifdef DEBUG printf("Compressed size is %u\n", *csize); #endif *usize = UNPACK_UB4(file_header, LOC_USIZE); #ifdef DEBUG printf("Uncompressed size is %u\n", *usize); #endif *fnlen = UNPACK_UB2(file_header, LOC_FNLEN); #ifdef DEBUG printf("Filename length is %hu\n", *fnlen); #endif *eflen = UNPACK_UB2(file_header, LOC_EFLEN); #ifdef DEBUG printf("Extra field length is %hu\n", *eflen); #endif *flags = UNPACK_UB2(file_header, LOC_EXTRA); #ifdef DEBUG printf("Flags are %#hx\n", *flags); #endif *method = UNPACK_UB2(file_header, LOC_COMP); #ifdef DEBUG printf("Compression method is %#hx\n", *method); #endif }
bool JarFile::check_crc(guint32 oldcrc, guint32 crc, guint16 flags) { //fixme: does not work yet if(flags & 0x0008) { guint8 *bytes = (guint8 *)g_malloc(sizeof(guint8) * 16); if (!read(bytes, 16)) { g_free(bytes); return false; } guint32 signature = UNPACK_UB4(bytes, 0); g_free(bytes); if(signature != 0x08074b50) { fprintf(stderr, "missing data descriptor!\n"); } crc = UNPACK_UB4(bytes, 4); } if (oldcrc != crc) { #ifdef DEBUG std::fprintf(stderr, "Error! CRCs do not match! Got %x, expected %x\n", oldcrc, crc); #endif } return true; }
/* Function name: check_sig args: scratch Pointer to array of bytes containing signature. pbf Pointer to push back handle for jar file. purpose: Verify that checksum is correct. returns: 0, 1, or 2. 0 means we are ready to read embedded file information. 1 means we have read beyound the embedded file list and can exit knowing we have read all the relevent information. 2 means we still haven't reached embdedded file list and need to do some more reading. */ static int check_sig(ub1 *scratch, pb_file *pbfp) { ub4 signature; int retflag = 0; signature = UNPACK_UB4(scratch, 0); #ifdef DEBUG printf("signature is %x\n", signature); #endif if(signature == 0x08074b50){ #ifdef DEBUG printf("skipping data descriptor\n"); #endif pb_read(pbfp, scratch, 12); retflag = 2; } else if(signature == 0x02014b50){ #ifdef DEBUG printf("Central header reached.. we're all done!\n"); #endif retflag = 1; }else if(signature != 0x04034b50){ printf("Ick! %#x\n", signature); retflag = 1; } return retflag; }
bool JarFile::read_signature() { guint8 *bytes = (guint8 *)g_malloc(sizeof(guint8) * 4); if (!read(bytes, 4)) { g_free(bytes); return false; } guint32 signature = UNPACK_UB4(bytes, 0); g_free(bytes); #ifdef DEBUG std::printf("signature is %x\n", signature); #endif if (signature == 0x08074b50) { //skip data descriptor bytes = (guint8 *)g_malloc(sizeof(guint8) * 12); if (!read(bytes, 12)) { g_free(bytes); return false; } else { g_free(bytes); } } else if (signature == 0x02014b50 || signature == 0x04034b50) { return true; } else { return false; } return false; }
static NEOERR *unpack_row (WDB *wdb, void *rdata, int dlen, WDBRow *row) { unsigned char *data = rdata; int version, n; int count, x, ondisk_index, type, d_int, inmem_index; char *s; n = 0; UNPACK_UB4(data, dlen, n, version); switch (version) { case PACK_VERSION_1: UNPACK_UB4(data, dlen, n, count); for (x = 0; x<count; x++) { UNPACK_UB4 (data, dlen, n, ondisk_index); UNPACK_BYTE (data, dlen, n, type); inmem_index = (int) skipSearch (wdb->ondisk, ondisk_index, NULL); switch (type) { case WDB_TYPE_INT: UNPACK_UB4 (data, dlen, n, d_int); if (inmem_index != 0) row->data[inmem_index-1] = (void *) d_int; break; case WDB_TYPE_STR: UNPACK_STRING (data, dlen, n, s); if (inmem_index != 0) row->data[inmem_index-1] = s; break; default: return nerr_raise (NERR_ASSERT, "Unknown type %d for col %d", type, ondisk_index); } } break; default: return nerr_raise (NERR_ASSERT, "Unknown version %d", version); } return STATUS_OK; pack_err: return nerr_raise(NERR_PARSE, "Unable to unpack row %s", row->key_value); }
static void check_crc(pb_file *pbf, const char *stream, ub4 usize) { ub4 crc; ub4 lcrc; ub1 scratch[16]; crc = crc32(crc, NULL, 0); crc = crc32(crc, (const unsigned char *)stream, usize); if(pb_read(pbf, scratch, 16) != 16) { perror("read"); exit(1); } if(UNPACK_UB4(scratch, 0) != 0x08074b50) { fprintf(stderr, "Error! Missing data descriptor!\n"); exit(1); } lcrc = UNPACK_UB4(scratch, 4); if(crc != lcrc){ fprintf(stderr, "Error! CRCs do not match! Got %x, expected %x\n", crc, lcrc); exit(1); } }
guint32 JarFile::get_crc(guint8 *bytes, guint16 flags) { guint32 crc = 0; //no data descriptor if (!(flags & 0x0008)) { crc = UNPACK_UB4(bytes, LOC_CRC); #ifdef DEBUG std::printf("CRC from file is %x\n", crc); #endif } return crc; }
GByteArray *JarFile::get_next_file_contents() { guint8 *bytes; GByteArray *gba = g_byte_array_new(); read_signature(); //get compressed size bytes = (guint8 *)g_malloc(sizeof(guint8) * 30); if (!read(bytes+4, 26)) { g_free(bytes); return NULL; } guint32 compressed_size = UNPACK_UB4(bytes, LOC_CSIZE); guint16 filename_length = UNPACK_UB2(bytes, LOC_FNLEN); guint16 eflen = UNPACK_UB2(bytes, LOC_EFLEN); guint16 flags = UNPACK_UB2(bytes, LOC_EXTRA); guint16 method = UNPACK_UB2(bytes, LOC_COMP); if (filename_length == 0) { g_byte_array_free(gba, TRUE); if (_last_filename != NULL) g_free(_last_filename); _last_filename = NULL; g_free(bytes); return NULL; } #ifdef DEBUG std::printf("Compressed size is %u\n", compressed_size); std::printf("Filename length is %hu\n", filename_length); std::printf("Extra field length is %hu\n", eflen); std::printf("Flags are %#hx\n", flags); std::printf("Compression method is %#hx\n", method); #endif guint32 crc = get_crc(bytes, flags); gchar *filename = (gchar *)read_filename(filename_length); g_free(bytes); if (filename == NULL) return NULL; if (_last_filename != NULL) g_free(_last_filename); _last_filename = filename; //check if this is a directory and skip char *c_ptr; if ((c_ptr = std::strrchr(filename, '/')) != NULL) { if (*(++c_ptr) == '\0') { return NULL; } } if (!check_compression_method(method, flags)) { std::fprintf(stderr, "error in jar file\n"); return NULL; } if (method == 8 || flags & 0x0008) { unsigned int file_length = 0;//uncompressed file length lseek(fd, eflen, SEEK_CUR); guint8 *file_data = get_compressed_file(compressed_size, file_length, crc, flags); if (file_data == NULL) { g_byte_array_free(gba, FALSE); return NULL; } g_byte_array_append(gba, file_data, file_length); } else if (method == 0) { guint8 *file_data = get_uncompressed_file(compressed_size, crc, eflen, flags); if (file_data == NULL) { g_byte_array_free(gba, TRUE); return NULL; } g_byte_array_append(gba, file_data, compressed_size); } else { lseek(fd, compressed_size+eflen, SEEK_CUR); g_byte_array_free(gba, FALSE); return NULL; } return gba; }