예제 #1
0
// don't inline, to be friendly to js engine osr
void __attribute__ ((noinline)) doit(char *buffer, int size, int i) {
  static char *buffer2 = NULL;
  static char *buffer3 = NULL;

  unsigned long maxCompressedSize = lzma_stream_buffer_bound(size);

  if (!buffer2) buffer2 = (char*)malloc(maxCompressedSize);
  if (!buffer3) buffer3 = (char*)malloc(size);

  size_t compressedSize = 0;
  int ret = lzma_easy_buffer_encode(LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64, NULL, (const uint8_t*)buffer, size, (uint8_t*)buffer2, &compressedSize, maxCompressedSize);
  assert(ret == LZMA_OK);
  if (i == 0) printf("sizes: %d,%d\n", size, compressedSize);

  lzma_stream strm = LZMA_STREAM_INIT;
  ret = lzma_stream_decoder(&strm, UINT64_MAX, 0);
  assert(ret == LZMA_OK);
  strm.next_in = (const uint8_t*)buffer2;
  strm.avail_in = compressedSize;
  strm.next_out = (uint8_t*)buffer3;
  strm.avail_out = size;
  ret = lzma_code (&strm, LZMA_FINISH);
  assert(ret == LZMA_OK || ret == LZMA_STREAM_END);
  size_t decompressedSize = size - strm.avail_out;
  assert(decompressedSize == size);
  if (i == 0) assert(strcmp(buffer, buffer3) == 0);
}
예제 #2
0
static int php_xz_init_decoder(struct php_xz_stream_data_t *self)
{
  lzma_stream *strm = &self->strm;
  lzma_ret ret = lzma_stream_decoder(strm, UINT64_MAX, LZMA_CONCATENATED);
  if (ret == LZMA_OK) {
    self->in_buf_sz = XZ_INBUF_SIZE;
    self->out_buf_sz = XZ_OUTBUF_SIZE;
    self->in_buf = emalloc(self->in_buf_sz);
    self->out_buf = emalloc(self->out_buf_sz);
    self->out_buf_idx = self->out_buf;
    strm->next_in = self->in_buf;
    strm->avail_in = 0;
    strm->next_out = self->out_buf;
    strm->avail_out = self->out_buf_sz;
    return 1;
  }
  /*const char *msg;
  switch(ret) {
    case LZMA_MEM_ERROR:
      msg = "Memory allocation";
      break;
    case LZMA_OPTIONS_ERROR:
      msg = "Unsupported decompress flags";
      break;
    default:
      msg = "Unknown";
      break;
  }*/
  return 0;
}
예제 #3
0
static MojoInput *make_xz_input(MojoInput *origio)
{
    MojoInput *io = NULL;
    XZinfo *info = (XZinfo *) xmalloc(sizeof (XZinfo));
    lzma_stream *strm = &info->stream;

    // UINT64_MAX is the memory usage limit (so basically, no artificial
    //  limit here). Internally, this holds its entire dictionary in
    //  RAM (8 megabytes by default), plus a few other structures, so we
    //  shouldn't eat tons of memory in the normal case. Note that the
    //  dictionary can max out at _four gigabytes_, but obviously no one does
    //  that.
    initializeXZStream(strm);
	if (lzma_stream_decoder(strm, UINT64_MAX, LZMA_CONCATENATED) != LZMA_OK)
    {
        free(info);
        return NULL;
    } // if

    info->origio = origio;

    io = (MojoInput *) xmalloc(sizeof (MojoInput));
    io->ready = MojoInput_xz_ready;
    io->read = MojoInput_xz_read;
    io->seek = MojoInput_xz_seek;
    io->tell = MojoInput_xz_tell;
    io->length = MojoInput_xz_length;
    io->duplicate = MojoInput_xz_duplicate;
    io->close = MojoInput_xz_close;
    io->opaque = info;
    return io;
} // make_xz_input
예제 #4
0
/*
 * Setup state for decoding a strip.
 */
static int
LZMAPreDecode(TIFF* tif, uint16 s)
{
    static const char module[] = "LZMAPreDecode";
    LZMAState* sp = DecoderState(tif);
    lzma_ret ret;

    (void) s;
    assert(sp != NULL);

    if( (sp->state & LSTATE_INIT_DECODE) == 0 )
            tif->tif_setupdecode(tif);

    sp->stream.next_in = tif->tif_rawdata;
    sp->stream.avail_in = (size_t) tif->tif_rawcc;
    if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) {
        TIFFErrorExt(tif->tif_clientdata, module,
                 "Liblzma cannot deal with buffers this size");
        return 0;
    }

    /*
     * Disable memory limit when decoding. UINT64_MAX is a flag to disable
     * the limit, we are passing (uint64_t)-1 which should be the same.
     */
    ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0);
    if (ret != LZMA_OK) {
        TIFFErrorExt(tif->tif_clientdata, module,
                 "Error initializing the stream decoder, %s",
                 LZMAStrerror(ret));
        return 0;
    }
    return 1;
}
예제 #5
0
파일: zstream.c 프로젝트: jelaas/bar
static int xz_open(struct zstream *z, int fd, char *mode)
{
    lzma_ret ret;

    z->xz.eof = 0;
    z->xz.fd = fd;
    if(*mode == 'w') {
        ret = lzma_easy_encoder(&z->xz.stream, 5, LZMA_CHECK_CRC64);
        if (ret == LZMA_OK)
            return 0;
        return -1;
    }
    if(*mode == 'r') {
        z->xz.stream.next_in = NULL;
        z->xz.stream.avail_in = 0;
        z->xz.stream.next_out = z->xz.outbuf;
        z->xz.stream.avail_out = z->xz.bufsize;

        ret = lzma_stream_decoder(&z->xz.stream, UINT64_MAX, LZMA_CONCATENATED);
        if (ret == LZMA_OK)
            return 0;
        return -1;
    }

    return -1;
}
예제 #6
0
int decompress_blob_xz(const void *src, uint64_t src_size,
                       void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {

#ifdef HAVE_XZ
        _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
        lzma_ret ret;
        size_t space;

        assert(src);
        assert(src_size > 0);
        assert(dst);
        assert(dst_alloc_size);
        assert(dst_size);
        assert(*dst_alloc_size == 0 || *dst);

        ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
        if (ret != LZMA_OK)
                return -ENOMEM;

        space = MIN(src_size * 2, dst_max ?: (size_t) -1);
        if (!greedy_realloc(dst, dst_alloc_size, space, 1))
                return -ENOMEM;

        s.next_in = src;
        s.avail_in = src_size;

        s.next_out = *dst;
        s.avail_out = space;

        for (;;) {
                size_t used;

                ret = lzma_code(&s, LZMA_FINISH);

                if (ret == LZMA_STREAM_END)
                        break;
                else if (ret != LZMA_OK)
                        return -ENOMEM;

                if (dst_max > 0 && (space - s.avail_out) >= dst_max)
                        break;
                else if (dst_max > 0 && space == dst_max)
                        return -ENOBUFS;

                used = space - s.avail_out;
                space = MIN(2 * space, dst_max ?: (size_t) -1);
                if (!greedy_realloc(dst, dst_alloc_size, space, 1))
                        return -ENOMEM;

                s.avail_out = space - used;
                s.next_out = *dst + used;
        }

        *dst_size = space - s.avail_out;
        return 0;
#else
        return -EPROTONOSUPPORT;
#endif
}
예제 #7
0
파일: lzma.c 프로젝트: yogo1212/nahcf
struct lzma_filter *lzma_decoder(void)
{
	lzma_stream strm = LZMA_STREAM_INIT;
	if (lzma_stream_decoder(&strm, UINT64_MAX, 0) != LZMA_OK)
		return NULL;

	return _lzma_filter_new(&strm);
}
예제 #8
0
파일: test-lzma.c 프로젝트: 020gzh/linux
int main(void)
{
	lzma_stream strm = LZMA_STREAM_INIT;
	int ret;

	ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
	return ret ? -1 : 0;
}
예제 #9
0
int decompress_startswith_xz(const void *src, uint64_t src_size,
                             void **buffer, size_t *buffer_size,
                             const void *prefix, size_t prefix_len,
                             uint8_t extra) {

#ifdef HAVE_XZ
        _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
        lzma_ret ret;

        /* Checks whether the decompressed blob starts with the
         * mentioned prefix. The byte extra needs to follow the
         * prefix */

        assert(src);
        assert(src_size > 0);
        assert(buffer);
        assert(buffer_size);
        assert(prefix);
        assert(*buffer_size == 0 || *buffer);

        ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
        if (ret != LZMA_OK)
                return -EBADMSG;

        if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1), 1)))
                return -ENOMEM;

        s.next_in = src;
        s.avail_in = src_size;

        s.next_out = *buffer;
        s.avail_out = *buffer_size;

        for (;;) {
                ret = lzma_code(&s, LZMA_FINISH);

                if (ret != LZMA_STREAM_END && ret != LZMA_OK)
                        return -EBADMSG;

                if (*buffer_size - s.avail_out >= prefix_len + 1)
                        return memcmp(*buffer, prefix, prefix_len) == 0 &&
                                ((const uint8_t*) *buffer)[prefix_len] == extra;

                if (ret == LZMA_STREAM_END)
                        return 0;

                s.avail_out += *buffer_size;

                if (!(greedy_realloc(buffer, buffer_size, *buffer_size * 2, 1)))
                        return -ENOMEM;

                s.next_out = *buffer + *buffer_size - s.avail_out;
        }

#else
        return -EPROTONOSUPPORT;
#endif
}
예제 #10
0
static void io_do_decompress(io_private_t *io_ptr)
{
	lzma_stream l = LZMA_STREAM_INIT;
	io_ptr->lzma_handle = l;

	if (lzma_stream_decoder(&io_ptr->lzma_handle, UINT64_MAX, 0/*LZMA_CONCATENATED*/) != LZMA_OK)
		return;

	io_ptr->lzma_init = true;
	return;
}
예제 #11
0
int import_uncompress_detect(ImportCompress *c, const void *data, size_t size) {
        static const uint8_t xz_signature[] = {
                0xfd, '7', 'z', 'X', 'Z', 0x00
        };
        static const uint8_t gzip_signature[] = {
                0x1f, 0x8b
        };
        static const uint8_t bzip2_signature[] = {
                'B', 'Z', 'h'
        };

        int r;

        assert(c);

        if (c->type != IMPORT_COMPRESS_UNKNOWN)
                return 1;

        if (size < MAX3(sizeof(xz_signature),
                        sizeof(gzip_signature),
                        sizeof(bzip2_signature)))
                return 0;

        assert(data);

        if (memcmp(data, xz_signature, sizeof(xz_signature)) == 0) {
                lzma_ret xzr;

                xzr = lzma_stream_decoder(&c->xz, UINT64_MAX, LZMA_TELL_UNSUPPORTED_CHECK);
                if (xzr != LZMA_OK)
                        return -EIO;

                c->type = IMPORT_COMPRESS_XZ;

        } else if (memcmp(data, gzip_signature, sizeof(gzip_signature)) == 0) {
                r = inflateInit2(&c->gzip, 15+16);
                if (r != Z_OK)
                        return -EIO;

                c->type = IMPORT_COMPRESS_GZIP;

        } else if (memcmp(data, bzip2_signature, sizeof(bzip2_signature)) == 0) {
                r = BZ2_bzDecompressInit(&c->bzip2, 0, 0);
                if (r != BZ_OK)
                        return -EIO;

                c->type = IMPORT_COMPRESS_BZIP2;
        } else
                c->type = IMPORT_COMPRESS_UNCOMPRESSED;

        c->encoding = false;

        return 1;
}
예제 #12
0
void lzma_base::do_init( const lzma_params &p, bool compress, lzma::alloc_func alloc, lzma::free_func free, void *derived )
{
	lzma_stream *s = static_cast<lzma_stream *>( stream_ );

	memset( s, 0, sizeof( *s ) );

	lzma_error::check(
		compress ?
		lzma_easy_encoder( s, p.level, LZMA_CHECK_CRC32 ) :
		lzma_stream_decoder( s, 100 * 1024 * 1024, 0 )
	);
}
예제 #13
0
파일: compress.c 프로젝트: CharizTeam/dpkg
static void
filter_unxz_init(struct io_lzma *io, lzma_stream *s)
{
	uint64_t memlimit = UINT64_MAX;
	lzma_ret ret;

	io->status |= DPKG_STREAM_DECOMPRESS;

	ret = lzma_stream_decoder(s, memlimit, 0);
	if (ret != LZMA_OK)
		filter_lzma_error(io, ret);
}
예제 #14
0
    int LzmaConnectorReader::resetConnectorReader (void)
    {
        lzma_end (&_lzmaDecompStream);

        resetDecompStream();

        if (LZMA_OK != lzma_stream_decoder (&_lzmaDecompStream, lzma_easy_decoder_memusage (getCompressionLevel()), DECODER_FLAGS)) {
            return -1;
        }

        return 0;
    }
예제 #15
0
static int xc_try_xz_decode(
    struct xc_dom_image *dom, void **blob, size_t *size)
{
    lzma_stream stream = LZMA_STREAM_INIT;

    if ( lzma_stream_decoder(&stream, LZMA_BLOCK_SIZE, 0) != LZMA_OK )
    {
        DOMPRINTF("XZ: Failed to init decoder");
        return -1;
    }

    return _xc_try_lzma_decode(dom, blob, size, &stream, "XZ");
}
예제 #16
0
static void i_stream_lzma_init(struct lzma_istream *zstream)
{
	lzma_ret ret;

	ret = lzma_stream_decoder(&zstream->strm, LZMA_MEMORY_LIMIT,
				  LZMA_CONCATENATED);
	switch (ret) {
	case LZMA_OK:
		break;
	case LZMA_MEM_ERROR:
		i_fatal_status(FATAL_OUTOFMEM, "lzma: Out of memory");
	default:
		i_fatal("lzma_stream_decoder() failed with ret=%d", ret);
	}
}
예제 #17
0
    LzmaConnectorReader::LzmaConnectorReader (const CompressionSettings & compressionSettings, unsigned int ulInBufSize, unsigned int ulOutBufSize) :
        ConnectorReader{compressionSettings}
    {
         if ((ulOutBufSize == 0) || (ulInBufSize == 0) ||
             (nullptr == (_pOutputBuffer = new unsigned char[ulOutBufSize])) ||
             (nullptr == (_pInputBuffer = new unsigned char[ulInBufSize]))) {
            // throw a c++ exception here
        }
        _ulInBufSize = ulInBufSize;
        _ulOutBufSize = ulOutBufSize;

        resetDecompStream();

        if (LZMA_OK != lzma_stream_decoder (&_lzmaDecompStream, lzma_easy_decoder_memusage (getCompressionLevel()), DECODER_FLAGS)) {
            // throw a c++ exception here
        }
    }
예제 #18
0
static int load_xz(struct kmod_file *file)
{
	lzma_stream strm = LZMA_STREAM_INIT;
	lzma_ret lzret;
	int ret;

	lzret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
	if (lzret == LZMA_MEM_ERROR) {
		ERR(file->ctx, "xz: %s\n", strerror(ENOMEM));
		return -ENOMEM;
	} else if (lzret != LZMA_OK) {
		ERR(file->ctx, "xz: Internal error (bug)\n");
		return -EINVAL;
	}
	ret = xz_uncompress(&strm, file);
	lzma_end(&strm);
	return ret;
}
예제 #19
0
static readstat_error_t init_lzma_stream(rdata_ctx_t *ctx) {
    readstat_error_t retval = READSTAT_OK;
    ctx->lzma_strm = calloc(1, sizeof(lzma_stream));
    ctx->strm_buffer = malloc(STREAM_BUFFER_SIZE);
    if (lzma_stream_decoder(ctx->lzma_strm, UINT64_MAX, 0) != LZMA_OK) {
        retval = READSTAT_ERROR_MALLOC;
        goto cleanup;
    }
    int bytes_read = read(ctx->fd, ctx->strm_buffer, STREAM_BUFFER_SIZE);
    if (bytes_read <= 0) {
        retval = READSTAT_ERROR_READ;
        goto cleanup;
    }

    ctx->lzma_strm->next_in = ctx->strm_buffer;
    ctx->lzma_strm->avail_in = bytes_read;
cleanup:
    return retval;
}
예제 #20
0
파일: compress.c 프로젝트: kilobyte/termrec
static void read_xz(int f, int fd, const char *arg)
{
    uint8_t inbuf[BUFFER_SIZE], outbuf[BUFFER_SIZE];
    lzma_stream xz = LZMA_STREAM_INIT;

    if (lzma_stream_decoder(&xz, UINT64_MAX, LZMA_CONCATENATED) != LZMA_OK)
        goto xz_read_end;

    xz.avail_in  = 0;

    while (xz.avail_in
           || (xz.avail_in = read(f, (uint8_t*)(xz.next_in = inbuf), BUFFER_SIZE)) > 0)
    {
        xz.next_out  = outbuf;
        xz.avail_out = sizeof(outbuf);
        if (lzma_code(&xz, LZMA_RUN) != LZMA_OK)
            goto xz_read_lzma_end;

        if (write(fd, outbuf, xz.next_out - outbuf) != xz.next_out - outbuf)
            goto xz_read_lzma_end;
    }

    // Flush the stream
    lzma_ret ret;
    do
    {
        xz.next_out  = outbuf;
        xz.avail_out = sizeof(outbuf);
        ret = lzma_code(&xz, LZMA_FINISH);

        if (write(fd, outbuf, xz.next_out - outbuf) != xz.next_out - outbuf)
            goto xz_read_lzma_end;
    }
    while (ret == LZMA_OK);

xz_read_lzma_end:
    lzma_end(&xz);

xz_read_end:
    close(f);
    close(fd);
}
예제 #21
0
파일: tiff.c 프로젝트: r-type/vice-libretro
static int tiff_uncompress_lzma(uint8_t *dst, uint64_t *len, const uint8_t *src,
                                int size)
{
    lzma_stream stream = LZMA_STREAM_INIT;
    lzma_ret ret;

    stream.next_in   = (uint8_t *)src;
    stream.avail_in  = size;
    stream.next_out  = dst;
    stream.avail_out = *len;
    ret              = lzma_stream_decoder(&stream, UINT64_MAX, 0);
    if (ret != LZMA_OK) {
        av_log(NULL, AV_LOG_ERROR, "LZMA init error: %d\n", ret);
        return ret;
    }
    ret = lzma_code(&stream, LZMA_RUN);
    lzma_end(&stream);
    *len = stream.total_out;
    return ret == LZMA_STREAM_END ? LZMA_OK : ret;
}
예제 #22
0
static boolean MojoInput_xz_seek(MojoInput *io, uint64 offset)
{
    // This is all really expensive.
    XZinfo *info = (XZinfo *) io->opaque;

    /*
     * If seeking backwards, we need to redecode the file
     *  from the start and throw away the compressed bits until we hit
     *  the offset we need. If seeking forward, we still need to
     *  decode, but we don't rewind first.
     */
    if (offset < info->uncompressed_position)
    {
        lzma_stream *strm = &info->stream;
        if (!info->origio->seek(info->origio, 0))
            return false;
        lzma_end(strm);
        initializeXZStream(strm);
	    if (lzma_stream_decoder(strm, UINT64_MAX, LZMA_CONCATENATED) != LZMA_OK)
            return false;
        info->uncompressed_position = 0;
    } // if

    while (info->uncompressed_position != offset)
    {
        uint8 buf[512];
        uint32 maxread;
        int64 br;

        maxread = (uint32) (offset - info->uncompressed_position);
        if (maxread > sizeof (buf))
            maxread = sizeof (buf);

        br = io->read(io, buf, maxread);
        if (br != maxread)
            return false;
    } /* while */

    return true;
} // MojoInput_xz_seek
예제 #23
0
GSDumpLzma::GSDumpLzma(char* filename) : GSDumpFile(filename) {

	memset(&m_strm, 0, sizeof(lzma_stream));

	lzma_ret ret = lzma_stream_decoder(&m_strm, UINT32_MAX, 0);

	if (ret != LZMA_OK) {
		fprintf(stderr, "Error initializing the decoder! (error code %u)\n", ret);
		throw "BAD"; // Just exit the program
	}

	m_buff_size = 1024*1024;
	m_area      = (uint8_t*)_aligned_malloc(m_buff_size, 32);
	m_inbuf     = (uint8_t*)_aligned_malloc(BUFSIZ, 32);
	m_avail     = 0;
	m_start     = 0;

	m_strm.avail_in  = 0;
	m_strm.next_in   = m_inbuf;

	m_strm.avail_out = m_buff_size;
	m_strm.next_out  = m_area;
}
예제 #24
0
static int
LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
{
    static const char module[] = "LZMADecode";
    LZMAState* sp = DecoderState(tif);

    (void) s;
    assert(sp != NULL);
    assert(sp->state == LSTATE_INIT_DECODE);

        sp->stream.next_in = tif->tif_rawcp;
        sp->stream.avail_in = (size_t) tif->tif_rawcc;

    sp->stream.next_out = op;
    sp->stream.avail_out = (size_t) occ;
    if ((tmsize_t)sp->stream.avail_out != occ) {
        TIFFErrorExt(tif->tif_clientdata, module,
                 "Liblzma cannot deal with buffers this size");
        return 0;
    }

    do {
        /*
         * Save the current stream state to properly recover from the
         * decoding errors later.
         */
        const uint8_t *next_in = sp->stream.next_in;
        size_t avail_in = sp->stream.avail_in;

        lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
        if (ret == LZMA_STREAM_END)
            break;
        if (ret == LZMA_MEMLIMIT_ERROR) {
            lzma_ret r = lzma_stream_decoder(&sp->stream,
                             lzma_memusage(&sp->stream), 0);
            if (r != LZMA_OK) {
                TIFFErrorExt(tif->tif_clientdata, module,
                         "Error initializing the stream decoder, %s",
                         LZMAStrerror(r));
                break;
            }
            sp->stream.next_in = next_in;
            sp->stream.avail_in = avail_in;
            continue;
        }
        if (ret != LZMA_OK) {
            TIFFErrorExt(tif->tif_clientdata, module,
                "Decoding error at scanline %lu, %s",
                (unsigned long) tif->tif_row, LZMAStrerror(ret));
            break;
        }
    } while (sp->stream.avail_out > 0);
    if (sp->stream.avail_out != 0) {
        TIFFErrorExt(tif->tif_clientdata, module,
            "Not enough data at scanline %lu (short %lu bytes)",
            (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out);
        return 0;
    }

        tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */
        tif->tif_rawcc = sp->stream.avail_in;

    return 1;
}
예제 #25
0
static off_t
unxz(int i, int o, char *pre, size_t prelen, off_t *bytes_in)
{
	lzma_stream strm = LZMA_STREAM_INIT;
	static const int flags = LZMA_TELL_UNSUPPORTED_CHECK|LZMA_CONCATENATED;
	lzma_ret ret;
	lzma_action action = LZMA_RUN;
	off_t bytes_out, bp;
	uint8_t ibuf[BUFSIZ];
	uint8_t obuf[BUFSIZ];

	if (bytes_in == NULL)
		bytes_in = &bp;

	strm.next_in = ibuf;
	memcpy(ibuf, pre, prelen);
	strm.avail_in = read(i, ibuf + prelen, sizeof(ibuf) - prelen);
	if (strm.avail_in == (size_t)-1)
		maybe_err("read failed");
	strm.avail_in += prelen;
	*bytes_in = strm.avail_in;

	if ((ret = lzma_stream_decoder(&strm, UINT64_MAX, flags)) != LZMA_OK)
		maybe_errx("Can't initialize decoder (%d)", ret);

	strm.next_out = NULL;
	strm.avail_out = 0;
	if ((ret = lzma_code(&strm, LZMA_RUN)) != LZMA_OK)
		maybe_errx("Can't read headers (%d)", ret);

	bytes_out = 0;
	strm.next_out = obuf;
	strm.avail_out = sizeof(obuf);

	for (;;) {
		if (strm.avail_in == 0) {
			strm.next_in = ibuf;
			strm.avail_in = read(i, ibuf, sizeof(ibuf));
			switch (strm.avail_in) {
			case (size_t)-1:
				maybe_err("read failed");
				/*NOTREACHED*/
			case 0:
				action = LZMA_FINISH;
				break;
			default:
				*bytes_in += strm.avail_in;
				break;
			}
		}

		ret = lzma_code(&strm, action);

		// Write and check write error before checking decoder error.
		// This way as much data as possible gets written to output
		// even if decoder detected an error.
		if (strm.avail_out == 0 || ret != LZMA_OK) {
			const size_t write_size = sizeof(obuf) - strm.avail_out;

			if (write(o, obuf, write_size) != (ssize_t)write_size)
				maybe_err("write failed");

			strm.next_out = obuf;
			strm.avail_out = sizeof(obuf);
			bytes_out += write_size;
		}

		if (ret != LZMA_OK) {
			if (ret == LZMA_STREAM_END) {
				// Check that there's no trailing garbage.
				if (strm.avail_in != 0 || read(i, ibuf, 1))
					ret = LZMA_DATA_ERROR;
				else {
					lzma_end(&strm);
					return bytes_out;
				}
			}

			const char *msg;
			switch (ret) {
			case LZMA_MEM_ERROR:
				msg = strerror(ENOMEM);
				break;

			case LZMA_FORMAT_ERROR:
				msg = "File format not recognized";
				break;

			case LZMA_OPTIONS_ERROR:
				// FIXME: Better message?
				msg = "Unsupported compression options";
				break;

			case LZMA_DATA_ERROR:
				msg = "File is corrupt";
				break;

			case LZMA_BUF_ERROR:
				msg = "Unexpected end of input";
				break;

			case LZMA_MEMLIMIT_ERROR:
				msg = "Reached memory limit";
				break;

			default:
				maybe_errx("Unknown error (%d)", ret);
				break;
			}
			maybe_errx("%s", msg);

		}
	}
}
예제 #26
0
void PsUpdateDownloader::unpackUpdate() {
    QByteArray packed;
	if (!outputFile.open(QIODevice::ReadOnly)) {
		LOG(("Update Error: cant read updates file!"));
		return fatalFail();
	}
#ifdef Q_OS_WIN // use Lzma SDK for win
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
#else
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
#endif
	QByteArray compressed = outputFile.readAll();
	int32 compressedLen = compressed.size() - hSize;
	if (compressedLen <= 0) {
		LOG(("Update Error: bad compressed size: %1").arg(compressed.size()));
		return fatalFail();
	}
	outputFile.close();

	QString tempDirPath = cWorkingDir() + qsl("tupdates/temp"), readyDirPath = cWorkingDir() + qsl("tupdates/ready");
	deleteDir(tempDirPath);
	deleteDir(readyDirPath);

	QDir tempDir(tempDirPath), readyDir(readyDirPath);
	if (tempDir.exists() || readyDir.exists()) {
		LOG(("Update Error: cant clear tupdates/temp or tupdates/ready dir!"));
		return fatalFail();
	}

	uchar sha1Buffer[20];
	bool goodSha1 = !memcmp(compressed.constData() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen);
	if (!goodSha1) {
		LOG(("Update Error: bad SHA1 hash of update file!"));
		return fatalFail();
	}

	RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(UpdatesPublicKey), -1), 0, 0, 0);
	if (!pbKey) {
		LOG(("Update Error: cant read public rsa key!"));
		return fatalFail();
	}
    if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
		RSA_free(pbKey);
		LOG(("Update Error: bad RSA signature of update file!"));
		return fatalFail();
    }
	RSA_free(pbKey);

	QByteArray uncompressed;

	int32 uncompressedLen;
	memcpy(&uncompressedLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
	uncompressed.resize(uncompressedLen);

	size_t resultLen = uncompressed.size();
#ifdef Q_OS_WIN // use Lzma SDK for win
	SizeT srcLen = compressedLen;
	int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
	if (uncompressRes != SZ_OK) {
		LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes));
		return fatalFail();
	}
#else
	lzma_stream stream = LZMA_STREAM_INIT;

	lzma_ret ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
	if (ret != LZMA_OK) {
		const char *msg;
		switch (ret) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
			case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		LOG(("Error initializing the decoder: %1 (error code %2)").arg(msg).arg(ret));
		return fatalFail();
	}

	stream.avail_in = compressedLen;
	stream.next_in = (uint8_t*)(compressed.constData() + hSize);
	stream.avail_out = resultLen;
	stream.next_out = (uint8_t*)uncompressed.data();

	lzma_ret res = lzma_code(&stream, LZMA_FINISH);
	if (stream.avail_in) {
		LOG(("Error in decompression, %1 bytes left in _in of %2 whole.").arg(stream.avail_in).arg(compressedLen));
		return fatalFail();
	} else if (stream.avail_out) {
		LOG(("Error in decompression, %1 bytes free left in _out of %2 whole.").arg(stream.avail_out).arg(resultLen));
		return fatalFail();
	}
	lzma_end(&stream);
	if (res != LZMA_OK && res != LZMA_STREAM_END) {
		const char *msg;
		switch (res) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
			case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
			case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
			case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		LOG(("Error in decompression: %1 (error code %2)").arg(msg).arg(res));
		return fatalFail();
	}
#endif

	tempDir.mkdir(tempDir.absolutePath());

	quint32 version;
	{
		QBuffer buffer(&uncompressed);
		buffer.open(QIODevice::ReadOnly);
		QDataStream stream(&buffer);
		stream.setVersion(QDataStream::Qt_5_1);

		stream >> version;
		if (stream.status() != QDataStream::Ok) {
			LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
			return fatalFail();
		}
		if (version <= AppVersion) {
			LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
			return fatalFail();
		}

		quint32 filesCount;
		stream >> filesCount;
		if (stream.status() != QDataStream::Ok) {
			LOG(("Update Error: cant read files count from downloaded stream, status: %1").arg(stream.status()));
			return fatalFail();
		}
		if (!filesCount) {
			LOG(("Update Error: update is empty!"));
			return fatalFail();
		}
		for (uint32 i = 0; i < filesCount; ++i) {
			QString relativeName;
			quint32 fileSize;
			QByteArray fileInnerData;
			bool executable = false;

			stream >> relativeName >> fileSize >> fileInnerData;
#if defined Q_OS_MAC || defined Q_OS_LINUX
			stream >> executable;
#endif
			if (stream.status() != QDataStream::Ok) {
				LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status()));
				return fatalFail();
			}
			if (fileSize != quint32(fileInnerData.size())) {
				LOG(("Update Error: bad file size %1 not matching data size %2").arg(fileSize).arg(fileInnerData.size()));
				return fatalFail();
			}

			QFile f(tempDirPath + '/' + relativeName);
			if (!QDir().mkpath(QFileInfo(f).absolutePath())) {
				LOG(("Update Error: cant mkpath for file '%1'").arg(tempDirPath + '/' + relativeName));
				return fatalFail();
			}
			if (!f.open(QIODevice::WriteOnly)) {
				LOG(("Update Error: cant open file '%1' for writing").arg(tempDirPath + '/' + relativeName));
				return fatalFail();
			}
			if (f.write(fileInnerData) != fileSize) {
				f.close();
				LOG(("Update Error: cant write file '%1'").arg(tempDirPath + '/' + relativeName));
				return fatalFail();
			}
			f.close();
			if (executable) {
				QFileDevice::Permissions p = f.permissions();
				p |= QFileDevice::ExeOwner | QFileDevice::ExeUser | QFileDevice::ExeGroup | QFileDevice::ExeOther;
				f.setPermissions(p);
			}
		}

		// create tdata/version file
		tempDir.mkdir(QDir(tempDirPath + qsl("/tdata")).absolutePath());
		std::wstring versionString = ((version % 1000) ? QString("%1.%2.%3").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000)).arg(int(version % 1000)) : QString("%1.%2").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000))).toStdWString();

		VerInt versionNum = VerInt(version), versionLen = VerInt(versionString.size() * sizeof(VerChar));
		VerChar versionStr[32];
		memcpy(versionStr, versionString.c_str(), versionLen);

		QFile fVersion(tempDirPath + qsl("/tdata/version"));
		if (!fVersion.open(QIODevice::WriteOnly)) {
			LOG(("Update Error: cant write version file '%1'").arg(tempDirPath + qsl("/version")));
			return fatalFail();
		}
		fVersion.write((const char*)&versionNum, sizeof(VerInt));
		fVersion.write((const char*)&versionLen, sizeof(VerInt));
		fVersion.write((const char*)&versionStr[0], versionLen);
		fVersion.close();
	}

	if (!tempDir.rename(tempDir.absolutePath(), readyDir.absolutePath())) {
		LOG(("Update Error: cant rename temp dir '%1' to ready dir '%2'").arg(tempDir.absolutePath()).arg(readyDir.absolutePath()));
		return fatalFail();
	}
	deleteDir(tempDirPath);
	outputFile.remove();

    emit App::app()->updateReady();
}
예제 #27
0
int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {

#ifdef HAVE_XZ
        _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
        lzma_ret ret;

        uint8_t buf[BUFSIZ], out[BUFSIZ];
        lzma_action action = LZMA_RUN;

        assert(fdf >= 0);
        assert(fdt >= 0);

        ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
        if (ret != LZMA_OK) {
                log_error("Failed to initialize XZ decoder: code %u", ret);
                return -ENOMEM;
        }

        for (;;) {
                if (s.avail_in == 0 && action == LZMA_RUN) {
                        ssize_t n;

                        n = read(fdf, buf, sizeof(buf));
                        if (n < 0)
                                return -errno;
                        if (n == 0)
                                action = LZMA_FINISH;
                        else {
                                s.next_in = buf;
                                s.avail_in = n;
                        }
                }

                if (s.avail_out == 0) {
                        s.next_out = out;
                        s.avail_out = sizeof(out);
                }

                ret = lzma_code(&s, action);
                if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
                        log_error("Decompression failed: code %u", ret);
                        return -EBADMSG;
                }

                if (s.avail_out == 0 || ret == LZMA_STREAM_END) {
                        ssize_t n, k;

                        n = sizeof(out) - s.avail_out;

                        if (max_bytes != -1) {
                                if (max_bytes < n)
                                        return -EFBIG;

                                max_bytes -= n;
                        }

                        k = loop_write(fdt, out, n, false);
                        if (k < 0)
                                return k;

                        if (ret == LZMA_STREAM_END) {
                                log_debug("XZ decompression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)",
                                          s.total_in, s.total_out,
                                          (double) s.total_out / s.total_in * 100);

                                return 0;
                        }
                }
        }
#else
        log_error("Cannot decompress file. Compiled without XZ support.");
        return -EPROTONOSUPPORT;
#endif
}
예제 #28
0
int main(int argc, char *argv[])
{
	QString workDir;
#ifdef Q_OS_MAC
    if (QDir(QString()).absolutePath() == "/") {
		QString first = argc ? QString::fromLocal8Bit(argv[0]) : QString();
		if (!first.isEmpty()) {
			QFileInfo info(first);
			if (info.exists()) {
				QDir result(info.absolutePath() + "/../../..");
				workDir = result.absolutePath() + '/';
			}
		}
	}
#endif

	QString remove;
	int version = 0;
	QFileInfoList files;
	for (int i = 0; i < argc; ++i) {
		if (string("-path") == argv[i] && i + 1 < argc) {
			QString path = workDir + QString(argv[i + 1]);
			QFileInfo info(path);
			files.push_back(info);
			if (remove.isEmpty()) remove = info.canonicalPath() + "/";
		} else if (string("-version") == argv[i] && i + 1 < argc) {
			version = QString(argv[i + 1]).toInt();
		} else if (string("-dev") == argv[i]) {
			DevChannel = true;
		} else if (string("-beta") == argv[i] && i + 1 < argc) {
			BetaVersion = QString(argv[i + 1]).toULongLong();
			if (BetaVersion > version * 1000ULL && BetaVersion < (version + 1) * 1000ULL) {
				DevChannel = false;
				BetaSignature = countBetaVersionSignature(BetaVersion);
				if (BetaSignature.isEmpty()) {
					return -1;
				}
			} else {
				cout << "Bad -beta param value passed, should be for the same version: " << version << ", beta: " << BetaVersion << "\n";
				return -1;
			}
		}
	}

	if (files.isEmpty() || remove.isEmpty() || version <= 1016 || version > 999999999) {
#ifdef Q_OS_WIN
		cout << "Usage: Packer.exe -path {file} -version {version} OR Packer.exe -path {dir} -version {version}\n";
#elif defined Q_OS_MAC
		cout << "Usage: Packer.app -path {file} -version {version} OR Packer.app -path {dir} -version {version}\n";
#else
		cout << "Usage: Packer -path {file} -version {version} OR Packer -path {dir} -version {version}\n";
#endif
		return -1;
	}

	bool hasDirs = true;
	while (hasDirs) {
		hasDirs = false;
		for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
			QFileInfo info(*i);
			QString fullPath = info.canonicalFilePath();
			if (info.isDir()) {
				hasDirs = true;
				files.erase(i);
				QDir d = QDir(info.absoluteFilePath());
				QString fullDir = d.canonicalPath();
				QStringList entries = d.entryList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
				files.append(d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot));
				break;
			} else if (!info.isReadable()) {
				cout << "Can't read: " << info.absoluteFilePath().toUtf8().constData() << "\n";
				return -1;
			} else if (info.isHidden()) {
				hasDirs = true;
				files.erase(i);
				break;
			}
		}
	}
	for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
		QFileInfo info(*i);
		if (!info.canonicalFilePath().startsWith(remove)) {
			cout << "Can't find '" << remove.toUtf8().constData() << "' in file '" << info.canonicalFilePath().toUtf8().constData() << "' :(\n";
			return -1;
		}
	}

	QByteArray result;
	{
		QBuffer buffer(&result);
		buffer.open(QIODevice::WriteOnly);
		QDataStream stream(&buffer);
		stream.setVersion(QDataStream::Qt_5_1);

		if (BetaVersion) {
			stream << quint32(0x7FFFFFFF);
			stream << quint64(BetaVersion);
		} else {
			stream << quint32(version);
		}

		stream << quint32(files.size());
		cout << "Found " << files.size() << " file" << (files.size() == 1 ? "" : "s") << "..\n";
		for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
			QFileInfo info(*i);
			QString fullName = info.canonicalFilePath();
			QString name = fullName.mid(remove.length());
			cout << name.toUtf8().constData() << " (" << info.size() << ")\n";

			QFile f(fullName);
			if (!f.open(QIODevice::ReadOnly)) {
				cout << "Can't open '" << fullName.toUtf8().constData() << "' for read..\n";
				return -1;
			}
			QByteArray inner = f.readAll();
			stream << name << quint32(inner.size()) << inner;
#if defined Q_OS_MAC || defined Q_OS_LINUX
			stream << (QFileInfo(fullName).isExecutable() ? true : false);
#endif
		}
		if (stream.status() != QDataStream::Ok) {
			cout << "Stream status is bad: " << stream.status() << "\n";
			return -1;
		}
	}

	int32 resultSize = result.size();
	cout << "Compression start, size: " << resultSize << "\n";

	QByteArray compressed, resultCheck;
#ifdef Q_OS_WIN // use Lzma SDK for win
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header

	compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size

	size_t compressedLen = compressed.size() - hSize;
	size_t outPropsSize = LZMA_PROPS_SIZE;
	uchar *_dest = (uchar*)(compressed.data() + hSize);
	size_t *_destLen = &compressedLen;
	const uchar *_src = (const uchar*)(result.constData());
	size_t _srcLen = result.size();
	uchar *_outProps = (uchar*)(compressed.data() + hSigLen + hShaLen);
	int res = LzmaCompress(_dest, _destLen, _src, _srcLen, _outProps, &outPropsSize, 9, 64 * 1024 * 1024, 4, 0, 2, 273, 2);
	if (res != SZ_OK) {
		cout << "Error in compression: " << res << "\n";
		return -1;
	}
	compressed.resize(int(hSize + compressedLen));
	memcpy(compressed.data() + hSigLen + hShaLen + hPropsLen, &resultSize, hOriginalSizeLen);

	cout << "Compressed to size: " << compressedLen << "\n";

	cout << "Checking uncompressed..\n";

	int32 resultCheckLen;
	memcpy(&resultCheckLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
	if (resultCheckLen <= 0 || resultCheckLen > 1024 * 1024 * 1024) {
		cout << "Bad result len: " << resultCheckLen << "\n";
		return -1;
	}
	resultCheck.resize(resultCheckLen);

	size_t resultLen = resultCheck.size();
	SizeT srcLen = compressedLen;
	int uncompressRes = LzmaUncompress((uchar*)resultCheck.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
	if (uncompressRes != SZ_OK) {
		cout << "Uncompress failed: " << uncompressRes << "\n";
		return -1;
	}
	if (resultLen != size_t(result.size())) {
		cout << "Uncompress bad size: " << resultLen << ", was: " << result.size() << "\n";
		return -1;
	}
#else // use liblzma for others
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header

	compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size

	size_t compressedLen = compressed.size() - hSize;

	lzma_stream stream = LZMA_STREAM_INIT;

	int preset = 9 | LZMA_PRESET_EXTREME;
	lzma_ret ret = lzma_easy_encoder(&stream, preset, LZMA_CHECK_CRC64);
	if (ret != LZMA_OK) {
		const char *msg;
		switch (ret) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
			case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error initializing the encoder: " << msg << " (error code " << ret << ")\n";
		return -1;
	}

	stream.avail_in = resultSize;
	stream.next_in = (uint8_t*)result.constData();
	stream.avail_out = compressedLen;
	stream.next_out = (uint8_t*)(compressed.data() + hSize);

	lzma_ret res = lzma_code(&stream, LZMA_FINISH);
	compressedLen -= stream.avail_out;
	lzma_end(&stream);
	if (res != LZMA_OK && res != LZMA_STREAM_END) {
		const char *msg;
		switch (res) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_DATA_ERROR: msg = "File size limits exceeded"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error in compression: " << msg << " (error code " << res << ")\n";
		return -1;
	}

	compressed.resize(int(hSize + compressedLen));
	memcpy(compressed.data() + hSigLen + hShaLen, &resultSize, hOriginalSizeLen);

	cout << "Compressed to size: " << compressedLen << "\n";

	cout << "Checking uncompressed..\n";

	int32 resultCheckLen;
	memcpy(&resultCheckLen, compressed.constData() + hSigLen + hShaLen, hOriginalSizeLen);
	if (resultCheckLen <= 0 || resultCheckLen > 1024 * 1024 * 1024) {
		cout << "Bad result len: " << resultCheckLen << "\n";
		return -1;
	}
	resultCheck.resize(resultCheckLen);

	size_t resultLen = resultCheck.size();

	stream = LZMA_STREAM_INIT;

	ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
	if (ret != LZMA_OK) {
		const char *msg;
		switch (ret) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
			case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error initializing the decoder: " << msg << " (error code " << ret << ")\n";
		return -1;
	}

	stream.avail_in = compressedLen;
	stream.next_in = (uint8_t*)(compressed.constData() + hSize);
	stream.avail_out = resultLen;
	stream.next_out = (uint8_t*)resultCheck.data();

	res = lzma_code(&stream, LZMA_FINISH);
	if (stream.avail_in) {
		cout << "Error in decompression, " << stream.avail_in << " bytes left in _in of " << compressedLen << " whole.\n";
		return -1;
	} else if (stream.avail_out) {
		cout << "Error in decompression, " << stream.avail_out << " bytes free left in _out of " << resultLen << " whole.\n";
		return -1;
	}
	lzma_end(&stream);
	if (res != LZMA_OK && res != LZMA_STREAM_END) {
		const char *msg;
		switch (res) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
			case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
			case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
			case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error in decompression: " << msg << " (error code " << res << ")\n";
		return -1;
	}
#endif
	if (memcmp(result.constData(), resultCheck.constData(), resultLen)) {
		cout << "Data differ :(\n";
		return -1;
	}
	/**/
	result = resultCheck = QByteArray();

	cout << "Counting SHA1 hash..\n";

	uchar sha1Buffer[20];
	memcpy(compressed.data() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, uint32(compressedLen + hPropsLen + hOriginalSizeLen), sha1Buffer), hShaLen); // count sha1

	uint32 siglen = 0;

	cout << "Signing..\n";
	RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>((DevChannel || BetaVersion) ? PrivateDevKey : PrivateKey), -1), 0, 0, 0);
	if (!prKey) {
		cout << "Could not read RSA private key!\n";
		return -1;
	}
	if (RSA_size(prKey) != hSigLen) {
		cout << "Bad private key, size: " << RSA_size(prKey) << "\n";
		RSA_free(prKey);
		return -1;
	}
	if (RSA_sign(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (uchar*)(compressed.data()), &siglen, prKey) != 1) { // count signature
		cout << "Signing failed!\n";
		RSA_free(prKey);
		return -1;
	}
	RSA_free(prKey);

	if (siglen != hSigLen) {
		cout << "Bad signature length: " << siglen << "\n";
		return -1;
	}

	cout << "Checking signature..\n";
	RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>((DevChannel || BetaVersion) ? PublicDevKey : PublicKey), -1), 0, 0, 0);
	if (!pbKey) {
		cout << "Could not read RSA public key!\n";
		return -1;
	}
	if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), siglen, pbKey) != 1) { // verify signature
		RSA_free(pbKey);
		cout << "Signature verification failed!\n";
		return -1;
	}
	cout << "Signature verified!\n";
	RSA_free(pbKey);
#ifdef Q_OS_WIN
	QString outName(QString("tupdate%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_MAC
	QString outName(QString("tmacupd%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_LINUX32
    QString outName(QString("tlinux32upd%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_LINUX64
    QString outName(QString("tlinuxupd%1").arg(BetaVersion ? BetaVersion : version));
#else
#error Unknown platform!
#endif
	if (BetaVersion) {
		outName += "_" + BetaSignature;
	}
	QFile out(outName);
	if (!out.open(QIODevice::WriteOnly)) {
		cout << "Can't open '" << outName.toUtf8().constData() << "' for write..\n";
		return -1;
	}
	out.write(compressed);
	out.close();

	if (BetaVersion) {
		QString keyName(QString("tbeta_%1_key").arg(BetaVersion));
		QFile key(keyName);
		if (!key.open(QIODevice::WriteOnly)) {
			cout << "Can't open '" << keyName.toUtf8().constData() << "' for write..\n";
			return -1;
		}
		key.write(BetaSignature.toUtf8());
		key.close();
	}

	cout << "Update file '" << outName.toUtf8().constData() << "' written successfully!\n";

	return 0;
}
예제 #29
0
static int
decompress_fd_xz(int fdi, int fdo)
{
    uint8_t buf_in[BUFSIZ];
    uint8_t buf_out[BUFSIZ];

    lzma_stream strm = LZMA_STREAM_INIT;
    lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, 0);
    if (ret != LZMA_OK)
    {
        close(fdi);
        close(fdo);
        log_error("Failed to initialize XZ decoder: code %d", ret);
        return -ENOMEM;
    }

    lzma_action action = LZMA_RUN;

    strm.next_out = buf_out;
    strm.avail_out = sizeof(buf_out);

    for (;;)
    {
        if (strm.avail_in == 0 && action == LZMA_RUN)
        {
            strm.next_in = buf_in;
            strm.avail_in = safe_read(fdi, buf_in, sizeof(buf_in));

            if (strm.avail_in < 0)
            {
                perror_msg("Failed to read source core file");
                close(fdi);
                close(fdo);
                lzma_end(&strm);
                return -1;
            }

            if (strm.avail_in == 0)
                action = LZMA_FINISH;
        }

        ret = lzma_code(&strm, action);

        if (strm.avail_out == 0 || ret == LZMA_STREAM_END)
        {
            const ssize_t n = sizeof(buf_out) - strm.avail_out;
            if (n != safe_write(fdo, buf_out, n))
            {
                perror_msg("Failed to write decompressed data");
                close(fdi);
                close(fdo);
                lzma_end(&strm);
                return -1;
            }

            if (ret == LZMA_STREAM_END)
            {
                log_debug("Successfully decompressed coredump.");
                break;
            }

            strm.next_out = buf_out;
            strm.avail_out = sizeof(buf_out);
        }
    }

    return 0;
}
예제 #30
0
파일: main.c 프로젝트: bryanr/transpress
int xz_dec_init(lzma_stream *str)
{
	lzma_ret ret_xz;
    ret_xz = lzma_stream_decoder(str, UINT64_MAX, LZMA_CONCATENATED);
    return ret_xz;
}