Beispiel #1
0
/*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);
}
Beispiel #2
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;
}
Beispiel #3
0
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;
}
Beispiel #4
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);
}
Beispiel #5
0
Datei: npk.c Projekt: keedi/npk
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;
}