/*ARGSUSED*/ int gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) { size_t dstlen = d_len; ASSERT(d_len >= s_len); if (z_uncompress(d_start, &dstlen, s_start, s_len) != Z_OK) return (-1); return (0); }
*/ REBSER *Decompress(const REBYTE *data, REBCNT len, REBCNT limit, REBFLG use_crc) /* ** Decompress a binary (only). ** ** Rebol's compress/decompress functions store an extra length ** at the tail of the data, to double-check the zlib result ** ***********************************************************************/ { // NOTE: The use_crc flag is not present in Zlib 1.2.8 // There is no fifth parameter to uncompress matching the fifth to compress uLongf size; REBSER *output; REBINT err; // Get the size from the end and make the output buffer that size. if (len <= 4) Trap_DEAD_END(RE_PAST_END); // !!! better msg needed size = Bytes_To_REBCNT(data + len - sizeof(REBCNT)); // NOTE: You can hit this if you 'make prep' without doing a full rebuild // (If you 'make clean' and build again and this goes away, it was that) if (limit && size > limit) Trap_Num(RE_SIZE_LIMIT, size); output = Make_Binary(size); //DISABLE_GC; err = z_uncompress(BIN_HEAD(output), &size, data, len); if (err) { REBVAL arg; if (PG_Boot_Phase < 2) return 0; if (err == Z_MEM_ERROR) Trap_DEAD_END(RE_NO_MEMORY); SET_INTEGER(&arg, err); Trap1_DEAD_END(RE_BAD_PRESS, &arg); //!!!provide error string descriptions } SET_STR_END(output, size); SERIES_TAIL(output) = size; //ENABLE_GC; return output; }
static int splat_zlib_test1_check(struct file *file, void *src, void *dst, void *chk, int level) { size_t dst_len = BUFFER_SIZE; size_t chk_len = BUFFER_SIZE; int rc; memset(dst, 0, BUFFER_SIZE); memset(chk, 0, BUFFER_SIZE); rc = z_compress_level(dst, &dst_len, src, BUFFER_SIZE, level); if (rc != Z_OK) { splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, "Failed level %d z_compress_level(), %d\n", level, rc); return -EINVAL; } rc = z_uncompress(chk, &chk_len, dst, dst_len); if (rc != Z_OK) { splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, "Failed level %d z_uncompress(), %d\n", level, rc); return -EINVAL; } rc = memcmp(src, chk, BUFFER_SIZE); if (rc) { splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, "Failed level %d memcmp()), %d\n", level, rc); return -EINVAL; } splat_vprint(file, SPLAT_ZLIB_TEST1_NAME, "Passed level %d, compressed %d bytes to %d bytes\n", level, BUFFER_SIZE, (int)dst_len); return 0; }
/* * Decode the specified CTF buffer and optional symbol table and create a new * CTF container representing the symbolic debugging information. This code * can be used directly by the debugger, or it can be used as the engine for * ctf_fdopen() or ctf_open(), below. */ ctf_file_t * ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, const ctf_sect_t *strsect, int *errp) { const ctf_preamble_t *pp; ctf_header_t hp; ctf_file_t *fp; void *buf, *base; size_t size, hdrsz; int err; if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL))) return (ctf_set_open_errno(errp, EINVAL)); if (symsect != NULL && symsect->cts_entsize != sizeof (struct nlist) && symsect->cts_entsize != sizeof (struct nlist_64)) return (ctf_set_open_errno(errp, ECTF_SYMTAB)); if (symsect != NULL && symsect->cts_data == NULL) return (ctf_set_open_errno(errp, ECTF_SYMBAD)); if (strsect != NULL && strsect->cts_data == NULL) return (ctf_set_open_errno(errp, ECTF_STRBAD)); if (ctfsect->cts_size < sizeof (ctf_preamble_t)) return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); pp = (const ctf_preamble_t *)ctfsect->cts_data; ctf_dprintf("ctf_bufopen: magic=0x%x version=%u\n", pp->ctp_magic, pp->ctp_version); /* * Validate each part of the CTF header (either V1 or V2). * First, we validate the preamble (common to all versions). At that * point, we know specific header version, and can validate the * version-specific parts including section offsets and alignments. */ if (pp->ctp_magic != CTF_MAGIC) return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); if (pp->ctp_version == CTF_VERSION_2) { if (ctfsect->cts_size < sizeof (ctf_header_t)) return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); bcopy(ctfsect->cts_data, &hp, sizeof (hp)); hdrsz = sizeof (ctf_header_t); } else if (pp->ctp_version == CTF_VERSION_1) { const ctf_header_v1_t *h1p = (const ctf_header_v1_t *)ctfsect->cts_data; if (ctfsect->cts_size < sizeof (ctf_header_v1_t)) return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); bzero(&hp, sizeof (hp)); hp.cth_preamble = h1p->cth_preamble; hp.cth_objtoff = h1p->cth_objtoff; hp.cth_funcoff = h1p->cth_funcoff; hp.cth_typeoff = h1p->cth_typeoff; hp.cth_stroff = h1p->cth_stroff; hp.cth_strlen = h1p->cth_strlen; hdrsz = sizeof (ctf_header_v1_t); } else return (ctf_set_open_errno(errp, ECTF_CTFVERS)); size = hp.cth_stroff + hp.cth_strlen; ctf_dprintf("ctf_bufopen: uncompressed size=%lu\n", (ulong_t)size); if (hp.cth_lbloff > size || hp.cth_objtoff > size || hp.cth_funcoff > size || hp.cth_typeoff > size || hp.cth_stroff > size) return (ctf_set_open_errno(errp, ECTF_CORRUPT)); if (hp.cth_lbloff > hp.cth_objtoff || hp.cth_objtoff > hp.cth_funcoff || hp.cth_funcoff > hp.cth_typeoff || hp.cth_typeoff > hp.cth_stroff) return (ctf_set_open_errno(errp, ECTF_CORRUPT)); if ((hp.cth_lbloff & 3) || (hp.cth_objtoff & 1) || (hp.cth_funcoff & 1) || (hp.cth_typeoff & 3)) return (ctf_set_open_errno(errp, ECTF_CORRUPT)); /* * Once everything is determined to be valid, attempt to decompress * the CTF data buffer if it is compressed. Otherwise we just put * the data section's buffer pointer into ctf_buf, below. */ if (hp.cth_flags & CTF_F_COMPRESS) { size_t srclen, dstlen; const void *src; int rc = Z_OK; if (ctf_zopen(errp) == NULL) return (NULL); /* errp is set for us */ if ((base = ctf_data_alloc(size + hdrsz)) == MAP_FAILED) return (ctf_set_open_errno(errp, ECTF_ZALLOC)); bcopy(ctfsect->cts_data, base, hdrsz); ((ctf_preamble_t *)base)->ctp_flags &= ~CTF_F_COMPRESS; buf = (uchar_t *)base + hdrsz; src = (uchar_t *)ctfsect->cts_data + hdrsz; srclen = ctfsect->cts_size - hdrsz; dstlen = size; if ((rc = z_uncompress(buf, &dstlen, src, srclen)) != Z_OK) { ctf_dprintf("zlib inflate err: %s\n", z_strerror(rc)); ctf_data_free(base, size + hdrsz); return (ctf_set_open_errno(errp, ECTF_DECOMPRESS)); } if (dstlen != size) { ctf_dprintf("zlib inflate short -- got %lu of %lu " "bytes\n", (ulong_t)dstlen, (ulong_t)size); ctf_data_free(base, size + hdrsz); return (ctf_set_open_errno(errp, ECTF_CORRUPT)); } ctf_data_protect(base, size + hdrsz); } else { base = (void *)ctfsect->cts_data; buf = (uchar_t *)base + hdrsz; } /* * Once we have uncompressed and validated the CTF data buffer, we can * proceed with allocating a ctf_file_t and initializing it. */ if ((fp = ctf_alloc(sizeof (ctf_file_t))) == NULL) return (ctf_set_open_errno(errp, EAGAIN)); bzero(fp, sizeof (ctf_file_t)); fp->ctf_version = hp.cth_version; fp->ctf_fileops = &ctf_fileops[hp.cth_version]; bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t)); if (symsect != NULL) { bcopy(symsect, &fp->ctf_symtab, sizeof (ctf_sect_t)); bcopy(strsect, &fp->ctf_strtab, sizeof (ctf_sect_t)); } if (fp->ctf_data.cts_name != NULL) fp->ctf_data.cts_name = ctf_strdup(fp->ctf_data.cts_name); if (fp->ctf_symtab.cts_name != NULL) fp->ctf_symtab.cts_name = ctf_strdup(fp->ctf_symtab.cts_name); if (fp->ctf_strtab.cts_name != NULL) fp->ctf_strtab.cts_name = ctf_strdup(fp->ctf_strtab.cts_name); if (fp->ctf_data.cts_name == NULL) fp->ctf_data.cts_name = _CTF_NULLSTR; if (fp->ctf_symtab.cts_name == NULL) fp->ctf_symtab.cts_name = _CTF_NULLSTR; if (fp->ctf_strtab.cts_name == NULL) fp->ctf_strtab.cts_name = _CTF_NULLSTR; fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *)buf + hp.cth_stroff; fp->ctf_str[CTF_STRTAB_0].cts_len = hp.cth_strlen; if (strsect != NULL) { fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data; fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size; } fp->ctf_base = base; fp->ctf_buf = buf; fp->ctf_size = size + hdrsz; /* * If we have a parent container name and label, store the relocated * string pointers in the CTF container for easy access later. */ if (hp.cth_parlabel != 0) fp->ctf_parlabel = ctf_strptr(fp, hp.cth_parlabel); if (hp.cth_parname != 0) fp->ctf_parname = ctf_strptr(fp, hp.cth_parname); ctf_dprintf("ctf_bufopen: parent name %s (label %s)\n", fp->ctf_parname ? fp->ctf_parname : "<NULL>", fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>"); /* * If we have a symbol table section, allocate and initialize * the symtab translation table, pointed to by ctf_sxlate. */ if (symsect != NULL) { fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize; fp->ctf_sxlate = ctf_alloc(fp->ctf_nsyms * sizeof (uint_t)); if (fp->ctf_sxlate == NULL) { (void) ctf_set_open_errno(errp, EAGAIN); goto bad; } if ((err = init_symtab(fp, &hp, symsect, strsect)) != 0) { (void) ctf_set_open_errno(errp, err); goto bad; } } if ((err = init_types(fp, &hp)) != 0) { (void) ctf_set_open_errno(errp, err); goto bad; } /* * Initialize the ctf_lookup_by_name top-level dictionary. We keep an * array of type name prefixes and the corresponding ctf_hash to use. * NOTE: This code must be kept in sync with the code in ctf_update(). */ fp->ctf_lookups[0].ctl_prefix = "struct"; fp->ctf_lookups[0].ctl_len = strlen(fp->ctf_lookups[0].ctl_prefix); fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs; fp->ctf_lookups[1].ctl_prefix = "union"; fp->ctf_lookups[1].ctl_len = strlen(fp->ctf_lookups[1].ctl_prefix); fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions; fp->ctf_lookups[2].ctl_prefix = "enum"; fp->ctf_lookups[2].ctl_len = strlen(fp->ctf_lookups[2].ctl_prefix); fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums; fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR; fp->ctf_lookups[3].ctl_len = strlen(fp->ctf_lookups[3].ctl_prefix); fp->ctf_lookups[3].ctl_hash = &fp->ctf_names; fp->ctf_lookups[4].ctl_prefix = NULL; fp->ctf_lookups[4].ctl_len = 0; fp->ctf_lookups[4].ctl_hash = NULL; if (symsect != NULL) { if (symsect->cts_entsize == sizeof (struct nlist_64)) (void) ctf_setmodel(fp, CTF_MODEL_LP64); else if (symsect->cts_entsize == sizeof (struct nlist)) (void) ctf_setmodel(fp, CTF_MODEL_ILP32); else if (symsect->cts_entsize == sizeof (Elf64_Sym)) (void) ctf_setmodel(fp, CTF_MODEL_LP64); else (void) ctf_setmodel(fp, CTF_MODEL_ILP32); } else (void) ctf_setmodel(fp, CTF_MODEL_NATIVE); fp->ctf_refcnt = 1; return (fp); bad: ctf_close(fp); return (NULL); }
bool npk_entity_read( NPK_ENTITY entity, void* buf ) { NPK_ENTITYBODY* eb = entity; NPK_PACKAGEBODY* pb = NULL; void** lplpTarget = &buf; void* lpDecompressBuffer = NULL; //NPK_SIZE uncompLen = 0; unsigned long uncompLen = 0; NPK_RESULT res; if( !entity ) { npk_error( NPK_ERROR_EntityIsNull ); return false; } if( eb->info_.flag_ & ( NPK_ENTITY_COMPRESS_ZLIB | NPK_ENTITY_COMPRESS_BZIP2 ) ) { lpDecompressBuffer = malloc( sizeof(char) * eb->info_.size_ ); lplpTarget = &lpDecompressBuffer; } pb = eb->owner_; #ifdef NPK_PLATFORM_WINDOWS if( g_useCriticalSection ) EnterCriticalSection( &pb->cs_ ); #endif npk_seek( pb->handle_, (long)eb->info_.offset_+pb->offsetJump_, SEEK_SET ); res = npk_read( pb->handle_, (*lplpTarget), eb->info_.size_, g_callbackfp, NPK_PROCESSTYPE_ENTITY, g_callbackSize, eb->name_ ); #ifdef NPK_PLATFORM_WINDOWS if( g_useCriticalSection ) LeaveCriticalSection( &pb->cs_ ); #endif if( res != NPK_SUCCESS ) goto npk_entity_read_return_null_with_free; // Decode before uncompress, after v21 if( ( eb->info_.flag_ & NPK_ENTITY_ENCRYPT_TEA ) && ( eb->info_.flag_ & NPK_ENTITY_REVERSE ) ) tea_decode_buffer((char*)(*lplpTarget), eb->info_.size_, pb->teakey_, (pb->info_.version_ >= NPK_VERSION_ENCRYPTREMAINS)); if( eb->info_.flag_ & NPK_ENTITY_ENCRYPT_XXTEA ) xxtea_decode_buffer((char*)(*lplpTarget), eb->info_.size_, pb->teakey_, (pb->info_.version_ >= NPK_VERSION_ENCRYPTREMAINS)); if( eb->info_.flag_ & NPK_ENTITY_COMPRESS_ZLIB ) { uncompLen = eb->info_.originalSize_; if( uncompLen >= NPK_MIN_SIZE_ZIPABLE ) { #ifdef Z_PREFIX if( Z_OK != z_uncompress((Bytef*)(buf), (z_uLong*)&uncompLen, (const Bytef*)lpDecompressBuffer, (z_uLong)eb->info_.size_ ) ) #else if( Z_OK != uncompress((Bytef*)(buf), (uLong*)&uncompLen, (const Bytef*)lpDecompressBuffer, (uLong)eb->info_.size_ ) ) #endif { npk_error( NPK_ERROR_FailToDecompress ); goto npk_entity_read_return_null_with_free; } if( eb->info_.originalSize_ != uncompLen ) { npk_error( NPK_ERROR_FailToDecompress ); goto npk_entity_read_return_null_with_free; } } else memcpy( buf, lpDecompressBuffer, eb->info_.size_ ); NPK_SAFE_FREE( lpDecompressBuffer ); lplpTarget = &buf; } // Decode after uncompress, before v21 if( ( eb->info_.flag_ & NPK_ENTITY_ENCRYPT_TEA ) && !( eb->info_.flag_ & NPK_ENTITY_REVERSE ) ) tea_decode_buffer((char*)(*lplpTarget), eb->info_.originalSize_, pb->teakey_, false); return true; npk_entity_read_return_null_with_free: NPK_SAFE_FREE( lpDecompressBuffer ); return false; }