Exemplo n.º 1
1
  void GzipCompressor::Uncompress(std::string& uncompressed,
                                  const void* compressed,
                                  size_t compressedSize)
  {
    uint64_t uncompressedSize;
    const uint8_t* source = reinterpret_cast<const uint8_t*>(compressed);

    if (HasPrefixWithUncompressedSize())
    {
      uncompressedSize = ReadUncompressedSizePrefix(compressed, compressedSize);
      source += sizeof(uint64_t);
      compressedSize -= sizeof(uint64_t);
    }
    else
    {
      uncompressedSize = GuessUncompressedSize(compressed, compressedSize);
    }

    try
    {
      uncompressed.resize(static_cast<size_t>(uncompressedSize));
    }
    catch (...)
    {
      throw OrthancException(ErrorCode_NotEnoughMemory);
    }

    z_stream stream;
    memset(&stream, 0, sizeof(stream));

    char dummy = '\0';  // zlib does not like NULL output buffers (even if the uncompressed data is empty)
    stream.next_in = const_cast<Bytef*>(source);
    stream.next_out = reinterpret_cast<Bytef*>(uncompressedSize == 0 ? &dummy : &uncompressed[0]);

    stream.avail_in = static_cast<uInt>(compressedSize);
    stream.avail_out = static_cast<uInt>(uncompressedSize);

    // Ensure no overflow (if the buffer is too large for the current archicture)
    if (static_cast<size_t>(stream.avail_in) != compressedSize ||
        static_cast<size_t>(stream.avail_out) != uncompressedSize)
    {
      throw OrthancException(ErrorCode_NotEnoughMemory);
    }

    // Initialize the compression engine
    int error = inflateInit2(&stream, 
                             MAX_WBITS + 16);  // this is a gzip input

    if (error != Z_OK)
    {
      // Cannot initialize zlib
      uncompressed.clear();
      throw OrthancException(ErrorCode_InternalError);
    }

    // Uncompress the input buffer
    error = inflate(&stream, Z_FINISH);

    if (error != Z_STREAM_END)
    {
      inflateEnd(&stream);
      uncompressed.clear();

      switch (error)
      {
        case Z_MEM_ERROR:
          throw OrthancException(ErrorCode_NotEnoughMemory);
          
        case Z_BUF_ERROR:
        case Z_NEED_DICT:
          throw OrthancException(ErrorCode_BadFileFormat);
          
        default:
          throw OrthancException(ErrorCode_InternalError);
      }
    }

    size_t size = stream.total_out;

    if (inflateEnd(&stream) != Z_OK)
    {
      uncompressed.clear();
      throw OrthancException(ErrorCode_InternalError);
    }

    if (size != uncompressedSize)
    {
      uncompressed.clear();

      // The uncompressed size was not that properly guess, presumably
      // because of a file size over 4GB. Should fallback to
      // stream-based decompression.
      LOG(ERROR) << "The uncompressed size of a gzip-encoded buffer was not properly guessed";
      throw OrthancException(ErrorCode_NotImplemented);
    }
  }
Exemplo n.º 2
0
static int wrap_inflateinit2(void *a, int b) {
    return inflateInit2(a, b);
}
Exemplo n.º 3
0
//! opens a file by index
IReadFile* CZipReader::openFile(s32 index)
{
	//0 - The file is stored (no compression)
	//1 - The file is Shrunk
	//2 - The file is Reduced with compression factor 1
	//3 - The file is Reduced with compression factor 2
	//4 - The file is Reduced with compression factor 3
	//5 - The file is Reduced with compression factor 4
	//6 - The file is Imploded
	//7 - Reserved for Tokenizing compression algorithm
	//8 - The file is Deflated
	//9 - Reserved for enhanced Deflating
	//10 - PKWARE Date Compression Library Imploding

	switch(FileList[index].header.CompressionMethod)
	{
	case 0: // no compression
		{
			File->seek(FileList[index].fileDataPosition);
			return createLimitReadFile(FileList[index].simpleFileName.c_str(), File, FileList[index].header.DataDescriptor.UncompressedSize);
		}
	case 8:
		{
  			#ifdef _IRR_COMPILE_WITH_ZLIB_
			
			u32 uncompressedSize = FileList[index].header.DataDescriptor.UncompressedSize;			
			u32 compressedSize = FileList[index].header.DataDescriptor.CompressedSize;

			void* pBuf = new c8[ uncompressedSize ];
			if (!pBuf)
			{
				os::Printer::log("Not enough memory for decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR);
				return 0;
			}

			c8 *pcData = new c8[ compressedSize ];
			if (!pcData)
			{
				os::Printer::log("Not enough memory for decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR);
				return 0;
			}

			//memset(pcData, 0, compressedSize );
			File->seek(FileList[index].fileDataPosition);
			File->read(pcData, compressedSize );
			
			// Setup the inflate stream.
			z_stream stream;
			s32 err;

			stream.next_in = (Bytef*)pcData;
			stream.avail_in = (uInt)compressedSize;
			stream.next_out = (Bytef*)pBuf;
			stream.avail_out = uncompressedSize;
			stream.zalloc = (alloc_func)0;
			stream.zfree = (free_func)0;

			// Perform inflation. wbits < 0 indicates no zlib header inside the data.
			err = inflateInit2(&stream, -MAX_WBITS);
			if (err == Z_OK)
			{
				err = inflate(&stream, Z_FINISH);
				inflateEnd(&stream);
				if (err == Z_STREAM_END)
					err = Z_OK;
				err = Z_OK;
				inflateEnd(&stream);
			}


			delete[] pcData;
			
			if (err != Z_OK)
			{
				os::Printer::log("Error decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR);
				delete [] (c8*)pBuf;
				return 0;
			}
			else
				return io::createMemoryReadFile (	pBuf,
													uncompressedSize,
													FileList[index].zipFileName.c_str(),
													true
												);
			
			#else
			return 0; // zlib not compiled, we cannot decompress the data.
			#endif
		}
	default:
		os::Printer::log("file has unsupported compression method.", FileList[index].simpleFileName.c_str(), ELL_ERROR);
		return 0;
	};
}
Exemplo n.º 4
0
/*!
    Opens the QtIOCompressor in \a mode. Only ReadOnly and WriteOnly is supported.
    This functon will return false if you try to open in other modes.

    If the underlying device is not opened, this function will open it in a suitable mode. If this happens
    the device will also be closed when close() is called.

    If the underlying device is already opened, its openmode must be compatable with \a mode.

    Returns true on success, false on error.

    \sa close()
*/
bool QtIOCompressor::open(OpenMode mode)
{
    Q_D(QtIOCompressor);
    if (isOpen()) {
        qWarning("QtIOCompressor::open: device already open");
        return false;
    }

    // Check for correct mode: ReadOnly xor WriteOnly
    const bool read = (bool)(mode & ReadOnly);
    const bool write = (bool)(mode & WriteOnly);
    const bool both = (read && write);
    const bool neither = !(read || write);
    if (both || neither) {
        qWarning("QtIOCompressor::open: QtIOCompressor can only be opened in the ReadOnly or WriteOnly modes");
        return false;
    }

    // If the underlying device is open, check that is it opened in a compatible mode.
    if (d->device->isOpen()) {
        d->manageDevice = false;
        const OpenMode deviceMode = d->device->openMode();
        if (read && !(deviceMode & ReadOnly)) {
            qWarning("QtIOCompressor::open: underlying device must be open in one of the ReadOnly or WriteOnly modes");
            return false;
        } else if (write && !(deviceMode & WriteOnly)) {
            qWarning("QtIOCompressor::open: underlying device must be open in one of the ReadOnly or WriteOnly modes");
            return false;
        }

    // If the underlying device is closed, open it.
    } else {
        d->manageDevice = true;
        if (d->device->open(mode) == false) {
            setErrorString(QT_TRANSLATE_NOOP("QtIOCompressor", "Error opening underlying device: ") + d->device->errorString());
            return false;
        }
    }

    // Initialize zlib for deflating or inflating.

    // The second argument to inflate/deflateInit2 is the windowBits parameter,
    // which also controls what kind of compression stream headers to use.
    // The default value for this is 15. Passing a value greater than 15
    // enables gzip headers and then subtracts 16 form the windowBits value.
    // (So passing 31 gives gzip headers and 15 windowBits). Passing a negative
    // value selects no headers hand then negates the windowBits argument.
    int windowBits;
    switch (d->streamFormat) {
    case QtIOCompressor::GzipFormat:
        windowBits = 31;
        break;
    case QtIOCompressor::RawZipFormat:
        windowBits = -15;
        break;
    default:
        windowBits = 15;
    }

    int status;
    if (read) {
        d->state = QtIOCompressorPrivate::NotReadFirstByte;
        d->zlibStream.avail_in = 0;
        d->zlibStream.next_in = 0;
        if (d->streamFormat == QtIOCompressor::ZlibFormat) {
            status = inflateInit(&d->zlibStream);
        } else {
            if (checkGzipSupport(zlibVersion()) == false) {
                setErrorString(QT_TRANSLATE_NOOP("QtIOCompressor::open", "The gzip format not supported in this version of zlib."));
                return false;
            }

            status = inflateInit2(&d->zlibStream, windowBits);
        }
    } else {
        d->state = QtIOCompressorPrivate::NoBytesWritten;
        if (d->streamFormat == QtIOCompressor::ZlibFormat)
            status = deflateInit(&d->zlibStream, d->compressionLevel);
        else
            status = deflateInit2(&d->zlibStream, d->compressionLevel, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
    }

    // Handle error.
    if (status != Z_OK) {
        d->setZlibError(QT_TRANSLATE_NOOP("QtIOCompressor::open", "Internal zlib error: "), status);
        return false;
    }
    return QIODevice::open(mode);
}
Exemplo n.º 5
0
/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
   If this is the first time in, allocate required memory.  state->how will be
   left unchanged if there is no more input data available, will be set to COPY
   if there is no gzip header and direct copying will be performed, or it will
   be set to GZIP for decompression.  If direct copying, then leftover input
   data from the input buffer will be copied to the output buffer.  In that
   case, all further file reads will be directly to either the output buffer or
   a user buffer.  If decompressing, the inflate state will be initialized.
   gz_look() will return 0 on success or -1 on failure. */
local int gz_look(
    gz_statep state)
{
    z_streamp strm = &(state->strm);

    /* allocate read buffers and inflate memory */
    if (state->size == 0) {
        /* allocate buffers */
        state->in = malloc(state->want);
        state->out = malloc(state->want << 1);
        if (state->in == NULL || state->out == NULL) {
            if (state->out != NULL)
                free(state->out);
            if (state->in != NULL)
                free(state->in);
            gz_error(state, Z_MEM_ERROR, "out of memory");
            return -1;
        }
        state->size = state->want;

        /* allocate inflate memory */
        state->strm.zalloc = Z_NULL;
        state->strm.zfree = Z_NULL;
        state->strm.opaque = Z_NULL;
        state->strm.avail_in = 0;
        state->strm.next_in = Z_NULL;
        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
            free(state->out);
            free(state->in);
            state->size = 0;
            gz_error(state, Z_MEM_ERROR, "out of memory");
            return -1;
        }
    }

    /* get at least the magic bytes in the input buffer */
    if (strm->avail_in < 2) {
        if (gz_avail(state) == -1)
            return -1;
        if (strm->avail_in == 0)
            return 0;
    }

    /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
       a logical dilemma here when considering the case of a partially written
       gzip file, to wit, if a single 31 byte is written, then we cannot tell
       whether this is a single-byte file, or just a partially written gzip
       file -- for here we assume that if a gzip file is being written, then
       the header will be written in a single operation, so that reading a
       single byte is sufficient indication that it is not a gzip file) */
    if (strm->avail_in > 1 &&
            strm->next_in[0] == 31 && strm->next_in[1] == 139) {
        inflateReset(strm);
        state->how = GZIP;
        state->direct = 0;
        return 0;
    }

    /* no gzip header -- if we were decoding gzip before, then this is trailing
       garbage.  Ignore the trailing garbage and finish. */
    if (state->direct == 0) {
        strm->avail_in = 0;
        state->eof = 1;
        state->x.have = 0;
        return 0;
    }

    /* doing raw i/o, copy any leftover input to output -- this assumes that
       the output buffer is larger than the input buffer, which also assures
       space for gzungetc() */
    state->x.next = state->out;
    if (strm->avail_in) {
        memcpy(state->x.next, strm->next_in, strm->avail_in);
        state->x.have = strm->avail_in;
        strm->avail_in = 0;
    }
    state->how = COPY;
    state->direct = 1;
    return 0;
}
Exemplo n.º 6
0
Arquivo: gz.c Projeto: Cy-4AH/showtime
buf_t *
gz_inflate(buf_t *bin, char *errbuf, size_t errlen)
{
  z_stream z = {0};
  unsigned char *out;
  size_t outlen;
  int r;

  if(!gz_check(bin)) {
    snprintf(errbuf, errlen, "Invalid header");
    buf_release(bin);
    return NULL;
  }

  const uint8_t *in = buf_c8(bin);
  size_t inlen = bin->b_size;

  if(in[3] != 0) {
    snprintf(errbuf, errlen, "Header extensions is not supported");
    buf_release(bin);
    return NULL;
  }

  in += 10;
  inlen -= 10;

  z.next_in = (void *)in;
  z.avail_in = inlen;

  if(inflateInit2(&z, -MAX_WBITS) != Z_OK) {
    snprintf(errbuf, errlen, "Inflate init failed");
    buf_release(bin);
    return NULL;
  }

  outlen = inlen * 2;
  out = mymalloc(outlen + 1);
  if(out == NULL) {
    snprintf(errbuf, errlen, "Out of memory");
    inflateEnd(&z);
    buf_release(bin);
    return NULL;
  }

  while(1) {
    
    if(outlen - z.total_out == 0) {
      outlen *= 2;
      out = realloc(out, outlen+1);
    }

    z.next_out  = out    + z.total_out;
    z.avail_out = outlen - z.total_out;

    r = inflate(&z, 0);
    if(r == Z_STREAM_END)
      break;

    if(r != Z_OK) {
      snprintf(errbuf, errlen, "inflate: %s", z.msg);
      inflateEnd(&z);
      free(out);
      buf_release(bin);
      return NULL;
    }
  }

  out[z.total_out] = 0;
  inflateEnd(&z);
  buf_release(bin);
  return buf_create_and_adopt(z.total_out, out, &free);
}
Mappable *
MappableExtractFile::Create(const char *name, Zip *zip, Zip::Stream *stream)
{
  const char *cachePath = getenv("MOZ_LINKER_CACHE");
  if (!cachePath || !*cachePath) {
    log("Warning: MOZ_LINKER_EXTRACT is set, but not MOZ_LINKER_CACHE; "
        "not extracting");
    return NULL;
  }
  mozilla::ScopedDeleteArray<char> path;
  path = new char[strlen(cachePath) + strlen(name) + 2];
  sprintf(path, "%s/%s", cachePath, name);
  struct stat cacheStat;
  if (stat(path, &cacheStat) == 0) {
    struct stat zipStat;
    stat(zip->GetName(), &zipStat);
    if (cacheStat.st_mtime > zipStat.st_mtime) {
      debug("Reusing %s", static_cast<char *>(path));
      return MappableFile::Create(path);
    }
  }
  debug("Extracting to %s", static_cast<char *>(path));
  AutoCloseFD fd;
  fd = open(path, O_TRUNC | O_RDWR | O_CREAT | O_NOATIME,
                  S_IRUSR | S_IWUSR);
  if (fd == -1) {
    log("Couldn't open %s to decompress library", path.get());
    return NULL;
  }
  AutoUnlinkFile file;
  file = path.forget();
  if (stream->GetType() == Zip::Stream::DEFLATE) {
    if (ftruncate(fd, stream->GetUncompressedSize()) == -1) {
      log("Couldn't ftruncate %s to decompress library", file.get());
      return NULL;
    }
    /* Map the temporary file for use as inflate buffer */
    MappedPtr buffer(::mmap(NULL, stream->GetUncompressedSize(), PROT_WRITE,
                            MAP_SHARED, fd, 0), stream->GetUncompressedSize());
    if (buffer == MAP_FAILED) {
      log("Couldn't map %s to decompress library", file.get());
      return NULL;
    }

    z_stream zStream = stream->GetZStream(buffer);

    /* Decompress */
    if (inflateInit2(&zStream, -MAX_WBITS) != Z_OK) {
      log("inflateInit failed: %s", zStream.msg);
      return NULL;
    }
    if (inflate(&zStream, Z_FINISH) != Z_STREAM_END) {
      log("inflate failed: %s", zStream.msg);
      return NULL;
    }
    if (inflateEnd(&zStream) != Z_OK) {
      log("inflateEnd failed: %s", zStream.msg);
      return NULL;
    }
    if (zStream.total_out != stream->GetUncompressedSize()) {
      log("File not fully uncompressed! %ld / %d", zStream.total_out,
          static_cast<unsigned int>(stream->GetUncompressedSize()));
      return NULL;
    }
  } else if (stream->GetType() == Zip::Stream::STORE) {
    SeekableZStream zStream;
    if (!zStream.Init(stream->GetBuffer())) {
      log("Couldn't initialize SeekableZStream for %s", name);
      return NULL;
    }
    if (ftruncate(fd, zStream.GetUncompressedSize()) == -1) {
      log("Couldn't ftruncate %s to decompress library", file.get());
      return NULL;
    }
    MappedPtr buffer(::mmap(NULL, zStream.GetUncompressedSize(), PROT_WRITE,
                            MAP_SHARED, fd, 0), zStream.GetUncompressedSize());
    if (buffer == MAP_FAILED) {
      log("Couldn't map %s to decompress library", file.get());
      return NULL;
    }

    if (!zStream.Decompress(buffer, 0, zStream.GetUncompressedSize())) {
      log("%s: failed to decompress", name);
      return NULL;
    }
  } else {
    return NULL;
  }

  return new MappableExtractFile(fd.forget(), file.forget());
}
Exemplo n.º 8
0
static CURLcode
inflate_stream(struct connectdata *conn,
               struct Curl_transfer_keeper *k)
{
  int allow_restart = 1;
  z_stream *z = &k->z;          /* zlib state structure */
  uInt nread = z->avail_in;
  Bytef *orig_in = z->next_in;
  int status;                   /* zlib status */
  CURLcode result = CURLE_OK;   /* Curl_client_write status */
  char *decomp;                 /* Put the decompressed data here. */

  /* Dynamically allocate a buffer for decompression because it's uncommonly
     large to hold on the stack */
  decomp = (char*)malloc(DSIZ);
  if (decomp == NULL) {
    return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
  }

  /* because the buffer size is fixed, iteratively decompress and transfer to
     the client via client_write. */
  for (;;) {
    /* (re)set buffer for decompressed output for every iteration */
    z->next_out = (Bytef *)decomp;
    z->avail_out = DSIZ;

    status = inflate(z, Z_SYNC_FLUSH);
    if (status == Z_OK || status == Z_STREAM_END) {
      allow_restart = 0;
      if(DSIZ - z->avail_out) {
        result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
                                   DSIZ - z->avail_out);
        /* if !CURLE_OK, clean up, return */
        if (result) {
          free(decomp);
          return exit_zlib(z, &k->zlib_init, result);
        }
      }

      /* Done? clean up, return */
      if (status == Z_STREAM_END) {
        free(decomp);
        if (inflateEnd(z) == Z_OK)
          return exit_zlib(z, &k->zlib_init, result);
        else
          return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
      }

      /* Done with these bytes, exit */
      if (status == Z_OK && z->avail_in == 0) {
        free(decomp);
        return result;
      }
    }
    else if (allow_restart && status == Z_DATA_ERROR) {
      /* some servers seem to not generate zlib headers, so this is an attempt
         to fix and continue anyway */

      inflateReset(z);
      if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
        return process_zlib_error(conn, z);
      }
      z->next_in = orig_in;
      z->avail_in = nread;
      allow_restart = 0;
      continue;
    }
    else {                      /* Error; exit loop, handle below */
      free(decomp);
      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
    }
  }
  /* Will never get here */
}
Exemplo n.º 9
0
/*
 * FUNCTION: Uncompresses data in a buffer
 * ARGUMENTS:
 *     OutputBuffer = Pointer to buffer to place uncompressed data
 *     InputBuffer  = Pointer to buffer with data to be uncompressed
 *     InputLength  = Length of input buffer before, and amount consumed after
 *                    Negative to indicate that this is not the start of a new block
 *     OutputLength = Length of output buffer before, amount filled after
 *                    Negative to indicate that this is not the end of the block
 */
ULONG
MSZipCodecUncompress(PVOID OutputBuffer,
                     PVOID InputBuffer,
                     PLONG InputLength,
                     PLONG OutputLength)
{
    USHORT Magic;
    INT Status;

    DPRINT("MSZipCodecUncompress(OutputBuffer = %x, InputBuffer = %x, "
           "InputLength = %d, OutputLength = %d)\n", OutputBuffer,
           InputBuffer, *InputLength, *OutputLength);
    if (*InputLength > 0)
    {
        Magic = *(PUSHORT)InputBuffer;

        if (Magic != MSZIP_MAGIC)
        {
            DPRINT("Bad MSZIP block header magic (0x%X)\n", Magic);
            return CS_BADSTREAM;
        }

        ZStream.next_in = (PUCHAR)InputBuffer + 2;
        ZStream.avail_in = *InputLength - 2;
        ZStream.next_out = (PUCHAR)OutputBuffer;
        ZStream.avail_out = abs(*OutputLength);

        /* WindowBits is passed < 0 to tell that there is no zlib header.
         * Note that in this case inflate *requires* an extra "dummy" byte
         * after the compressed stream in order to complete decompression and
         * return Z_STREAM_END.
         */
        Status = inflateInit2(&ZStream, -MAX_WBITS);
        if (Status != Z_OK)
        {
            DPRINT("inflateInit2() returned (%d)\n", Status);
            return CS_BADSTREAM;
        }
        ZStream.total_in = 2;
    }
    else
    {
        ZStream.avail_in = -*InputLength;
        ZStream.next_in = (PUCHAR)InputBuffer;
        ZStream.next_out = (PUCHAR)OutputBuffer;
        ZStream.avail_out = abs(*OutputLength);
        ZStream.total_in = 0;
    }

    ZStream.total_out = 0;
    Status = inflate(&ZStream, Z_SYNC_FLUSH);
    if (Status != Z_OK && Status != Z_STREAM_END)
    {
        DPRINT("inflate() returned (%d) (%s)\n", Status, ZStream.msg);
        if (Status == Z_MEM_ERROR)
            return CS_NOMEMORY;
        return CS_BADSTREAM;
    }

    if (*OutputLength > 0)
    {
        Status = inflateEnd(&ZStream);
        if (Status != Z_OK)
        {
            DPRINT("inflateEnd() returned (%d)\n", Status);
            return CS_BADSTREAM;
        }
    }

    *OutputLength = ZStream.total_out;
    *InputLength = ZStream.total_in;

    return CS_SUCCESS;
}
Exemplo n.º 10
0
Buffer decompressBuffer( const Buffer &aBuffer, bool resizeResult, bool useGZip )
{
	int err;
	z_stream strm;

	strm.zalloc = Z_NULL;
	strm.zfree = Z_NULL;
	strm.opaque = Z_NULL;
	strm.avail_in = 0;
	strm.next_in = Z_NULL;
	err = useGZip ? inflateInit2( &strm, 16 + MAX_WBITS ) : inflateInit( &strm );
	if( err != Z_OK ) {
		//cleanup stream
		(void)inflateEnd(&strm);
		//throw
	}
	
	size_t inOffset = 0;
	size_t chunkSize = 16384;
	size_t inBufferSize = aBuffer.getDataSize();
	uint8_t * inPtr = (uint8_t *)aBuffer.getData();
	
	size_t outBufferSize = chunkSize;
	size_t outOffset = 0;
	Buffer outBuffer = Buffer( outBufferSize );
	uint8_t * outPtr = (uint8_t *)outBuffer.getData();
	
	do {
		strm.avail_in = chunkSize;
		if( inOffset + chunkSize > inBufferSize ) {
			strm.avail_in = inBufferSize - inOffset;
		}
		
		if( strm.avail_in == 0 ) break;
		
		strm.next_in = &inPtr[inOffset];
		inOffset += strm.avail_in;
		
		do {
			//expand the output buffer if neccessary
			if( outOffset + chunkSize > outBufferSize ) {
				// increase the size of the buffer by 50%
				while( outBufferSize < outOffset + chunkSize )
					outBufferSize = (size_t)(outBufferSize * 1.5f + 1);
				outBuffer.resize( outBufferSize );
				outPtr = (uint8_t *)outBuffer.getData();
			}
			strm.avail_out = chunkSize;
			strm.next_out = &outPtr[outOffset];
			err = inflate( &strm, Z_NO_FLUSH );
			switch( err ) {
				case Z_NEED_DICT:
				case Z_DATA_ERROR:
				case Z_MEM_ERROR:
					(void)inflateEnd(&strm);
					//throw
			}
			
			outOffset += (chunkSize - strm.avail_out);			
		} while( strm.avail_out == 0 );
		
		
	} while( err != Z_STREAM_END );
	
	(void)inflateEnd(&strm);
	
	outBuffer.setDataSize( outOffset );
	if( resizeResult ) {
		outBuffer.resize( outOffset );
	}
	
	return outBuffer;
}
Exemplo n.º 11
0
CURLcode
Curl_unencode_gzip_write(struct connectdata *conn,
                         struct Curl_transfer_keeper *k,
                         ssize_t nread)
{
  z_stream *z = &k->z;          /* zlib state structure */

  /* Initialize zlib? */
  if (k->zlib_init == ZLIB_UNINIT) {
    z->zalloc = (alloc_func)Z_NULL;
    z->zfree = (free_func)Z_NULL;
    z->opaque = 0;
    z->next_in = NULL;
    z->avail_in = 0;

    if (strcmp(zlibVersion(), "1.2.0.4") >= 0) {
        /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
        if (inflateInit2(z, MAX_WBITS+32) != Z_OK) {
          return process_zlib_error(conn, z);
        }
        k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */

    } else {
        /* we must parse the gzip header ourselves */
        if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
          return process_zlib_error(conn, z);
        }
        k->zlib_init = ZLIB_INIT;   /* Initial call state */
    }
  }

  if (k->zlib_init == ZLIB_INIT_GZIP) {
     /* Let zlib handle the gzip decompression entirely */
     z->next_in = (Bytef *)k->str;
     z->avail_in = (uInt)nread;
     /* Now uncompress the data */
     return inflate_stream(conn, k);
  }

#ifndef OLD_ZLIB_SUPPORT
  /* Support for old zlib versions is compiled away and we are running with
     an old version, so return an error. */
  return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);

#else
  /* This next mess is to get around the potential case where there isn't
   * enough data passed in to skip over the gzip header.  If that happens, we
   * malloc a block and copy what we have then wait for the next call.  If
   * there still isn't enough (this is definitely a worst-case scenario), we
   * make the block bigger, copy the next part in and keep waiting.
   *
   * This is only required with zlib versions < 1.2.0.4 as newer versions
   * can handle the gzip header themselves.
   */

  switch (k->zlib_init) {
  /* Skip over gzip header? */
  case ZLIB_INIT:
  {
    /* Initial call state */
    ssize_t hlen;

    switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
    case GZIP_OK:
      z->next_in = (Bytef *)k->str + hlen;
      z->avail_in = (uInt)(nread - hlen);
      k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
      break;

    case GZIP_UNDERFLOW:
      /* We need more data so we can find the end of the gzip header.  It's
       * possible that the memory block we malloc here will never be freed if
       * the transfer abruptly aborts after this point.  Since it's unlikely
       * that circumstances will be right for this code path to be followed in
       * the first place, and it's even more unlikely for a transfer to fail
       * immediately afterwards, it should seldom be a problem.
       */
      z->avail_in = (uInt)nread;
      z->next_in = malloc(z->avail_in);
      if (z->next_in == NULL) {
        return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
      }
      memcpy(z->next_in, k->str, z->avail_in);
      k->zlib_init = ZLIB_GZIP_HEADER;   /* Need more gzip header data state */
      /* We don't have any data to inflate yet */
      return CURLE_OK;

    case GZIP_BAD:
    default:
      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
    }

  }
  break;

  case ZLIB_GZIP_HEADER:
  {
    /* Need more gzip header data state */
    ssize_t hlen;
    unsigned char *oldblock = z->next_in;

    z->avail_in += nread;
    z->next_in = realloc(z->next_in, z->avail_in);
    if (z->next_in == NULL) {
      free(oldblock);
      return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
    }
    /* Append the new block of data to the previous one */
    memcpy(z->next_in + z->avail_in - nread, k->str, nread);

    switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) {
    case GZIP_OK:
      /* This is the zlib stream data */
      free(z->next_in);
      /* Don't point into the malloced block since we just freed it */
      z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in;
      z->avail_in = (uInt)(z->avail_in - hlen);
      k->zlib_init = ZLIB_GZIP_INFLATING;   /* Inflating stream state */
      break;

    case GZIP_UNDERFLOW:
      /* We still don't have any data to inflate! */
      return CURLE_OK;

    case GZIP_BAD:
    default:
      free(z->next_in);
      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
    }

  }
  break;

  case ZLIB_GZIP_INFLATING:
  default:
    /* Inflating stream state */
    z->next_in = (Bytef *)k->str;
    z->avail_in = (uInt)nread;
    break;
  }

  if (z->avail_in == 0) {
    /* We don't have any data to inflate; wait until next time */
    return CURLE_OK;
  }

  /* We've parsed the header, now uncompress the data */
  return inflate_stream(conn, k);
#endif
}
Exemplo n.º 12
0
int uncompress_gzip ( u_char *dest, int destLen, u_char *source, 
        int sourceLen, HttpSessionData *sd, int *total_bytes_read, int compr_fmt)
{
    z_stream stream;
    int err;
    int iRet = HI_SUCCESS;

   stream = sd->decomp_state->d_stream;

   stream.next_in = (Bytef*)source;
   stream.avail_in = (uInt)sourceLen;
   if ((uLong)stream.avail_in != (uLong)sourceLen) 
   {
       sd->decomp_state->d_stream = stream;
       return HI_FATAL_ERR;
   }

   stream.next_out = dest;
   stream.avail_out = (uInt)destLen;
   if ((uLong)stream.avail_out != (uLong)destLen)
   { 
       sd->decomp_state->d_stream = stream;
       return HI_FATAL_ERR;
   }


   if(!sd->decomp_state->inflate_init)
   {
       sd->decomp_state->inflate_init = 1;
       stream.zalloc = (alloc_func)0;
       stream.zfree = (free_func)0;
       if(compr_fmt & HTTP_RESP_COMPRESS_TYPE__DEFLATE)
           err = inflateInit2(&stream, DEFLATE_WBITS);
       else 
           err = inflateInit2(&stream, GZIP_WBITS);
       if (err != Z_OK) 
       {
           sd->decomp_state->d_stream = stream;
           return HI_FATAL_ERR;
       }
   }
   else
   {
       stream.total_in = 0;
       stream.total_out =0;
   }


   err = inflate(&stream, Z_STREAM_END);
   if ((err != Z_STREAM_END) && (err !=Z_OK)) {
       /* If some of the compressed data is decompressed we need to provide that for detection */
       if( stream.total_out > 0)
       {
           *total_bytes_read = stream.total_out;
           iRet = HI_NONFATAL_ERR;
       }
       else
           iRet = HI_FATAL_ERR;
       inflateEnd(&stream);
       sd->decomp_state->d_stream = stream;
       return iRet;
   }
   *total_bytes_read = stream.total_out;
   sd->decomp_state->d_stream = stream;
   return HI_SUCCESS;
}
Exemplo n.º 13
0
ZIP_EXTERN struct zip_file *
zip_fopen_index(struct zip *za, int fileno, int flags)
{
    int len, ret;
    int zfflags;
    struct zip_file *zf;

    if ((fileno < 0) || (fileno >= za->nentry)) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((flags & ZIP_FL_UNCHANGED) == 0
	&& ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) {
	_zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
	return NULL;
    }

    if (fileno >= za->cdir->nentry) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    zfflags = 0;
    switch (za->cdir->entry[fileno].comp_method) {
    case ZIP_CM_STORE:
	zfflags |= ZIP_ZF_CRC;
	break;

    case ZIP_CM_DEFLATE:
	if ((flags & ZIP_FL_COMPRESSED) == 0)
	    zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP;
	break;
    default:
	if ((flags & ZIP_FL_COMPRESSED) == 0) {
	    _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
	    return NULL;
	}
	break;
    }

    zf = _zip_file_new(za);

    zf->flags = zfflags;
    /* zf->name = za->cdir->entry[fileno].filename; */
    zf->method = za->cdir->entry[fileno].comp_method;
    zf->bytes_left = za->cdir->entry[fileno].uncomp_size;
    zf->cbytes_left = za->cdir->entry[fileno].comp_size;
    zf->crc_orig = za->cdir->entry[fileno].crc;

    if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) {
	zip_fclose(zf);
	return NULL;
    }
    
    if ((zf->flags & ZIP_ZF_DECOMP) == 0)
	zf->bytes_left = zf->cbytes_left;
    else {
	if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) {
	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    zip_fclose(zf);
	    return NULL;
	}

	len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
	if (len <= 0) {
	    _zip_error_copy(&za->error, &zf->error);
	    zip_fclose(zf);
	return NULL;
	}

	if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) {
	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    zip_fclose(zf);
	    return NULL;
	}
	zf->zstr->zalloc = Z_NULL;
	zf->zstr->zfree = Z_NULL;
	zf->zstr->opaque = NULL;
	zf->zstr->next_in = (Bytef *)zf->buffer;
	zf->zstr->avail_in = len;
	
	/* negative value to tell zlib that there is no header */
	if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) {
	    _zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
	    zip_fclose(zf);
	    return NULL;
	}
    }
    
    return zf;
}
Exemplo n.º 14
0
void ExtractWorker::process()
{
    QFile sourceFile(sourceName);
    QFile targetFile(destName);
    QString home = QDir::homePath();
    bool sourceopen = sourceFile.open(QIODevice::ReadOnly);
    int sourceFileDescriptor = sourceFile.handle();
    FILE* source = fdopen(sourceFileDescriptor, "rb");
    bool targetopen = targetFile.open(QIODevice::WriteOnly);
    int targetFileDescriptor = targetFile.handle();
    FILE* dest = fdopen(targetFileDescriptor, "wb");

    int ret;
    unsigned have;
    unsigned written = 0;
    z_stream strm;
    unsigned char in[CHUNKSIZE];
    unsigned char out[CHUNKSIZE];
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit2(&strm,  47);
    if (ret != Z_OK)
    {
        emit error();
        return;
    }

    do
    {
        strm.avail_in = fread(in, 1, CHUNKSIZE, source);

        if (ferror(source))
        {
            (void)inflateEnd(&strm);
            emit error();
            return;
        }
        if (strm.avail_in == 0)
            break;
        strm.next_in = in;

        do
        {
            strm.avail_out = CHUNKSIZE;
            strm.next_out = out;
            ret = inflate(&strm, Z_NO_FLUSH);
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            switch (ret) {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;     /* and fall through */
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                (void)inflateEnd(&strm);
                emit error();
                return;
         }
            have = CHUNKSIZE - strm.avail_out;
            written += have;

            emit progressUpdate(written);
            if (fwrite(out, 1, have, dest) != have || ferror(dest))
            {
                (void)inflateEnd(&strm);
                emit error();
                return;
            }
         }
        while (strm.avail_out == 0);
    }
    while (ret != Z_STREAM_END);

    (void)inflateEnd(&strm);
    if (ret == Z_STREAM_END)
        emit finished();
    else
        emit error();
}
Exemplo n.º 15
0
NS_IMETHODIMP
nsHTTPCompressConv::OnDataAvailable(nsIRequest* request,
                                    nsISupports *aContext,
                                    nsIInputStream *iStr,
                                    uint64_t aSourceOffset,
                                    uint32_t aCount)
{
  nsresult rv = NS_ERROR_INVALID_CONTENT_ENCODING;
  uint32_t streamLen = aCount;
  LOG(("nsHttpCompressConv %p OnDataAvailable %d", this, aCount));

  if (streamLen == 0) {
    NS_ERROR("count of zero passed to OnDataAvailable");
    return NS_ERROR_UNEXPECTED;
  }

  if (mStreamEnded) {
    // Hmm... this may just indicate that the data stream is done and that
    // what's left is either metadata or padding of some sort.... throwing
    // it out is probably the safe thing to do.
    uint32_t n;
    return iStr->ReadSegments(NS_DiscardSegment, nullptr, streamLen, &n);
  }

  switch (mMode) {
  case HTTP_COMPRESS_GZIP:
    streamLen = check_header(iStr, streamLen, &rv);

    if (rv != NS_OK) {
      return rv;
    }

    if (streamLen == 0) {
      return NS_OK;
    }

    MOZ_FALLTHROUGH;

  case HTTP_COMPRESS_DEFLATE:

    if (mInpBuffer != nullptr && streamLen > mInpBufferLen) {
      mInpBuffer = (unsigned char *) realloc(mInpBuffer, mInpBufferLen = streamLen);

      if (mOutBufferLen < streamLen * 2) {
        mOutBuffer = (unsigned char *) realloc(mOutBuffer, mOutBufferLen = streamLen * 3);
      }

      if (mInpBuffer == nullptr || mOutBuffer == nullptr) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
    }

    if (mInpBuffer == nullptr) {
      mInpBuffer = (unsigned char *) malloc(mInpBufferLen = streamLen);
    }

    if (mOutBuffer == nullptr) {
      mOutBuffer = (unsigned char *) malloc(mOutBufferLen = streamLen * 3);
    }

    if (mInpBuffer == nullptr || mOutBuffer == nullptr) {
      return NS_ERROR_OUT_OF_MEMORY;
    }

    uint32_t unused;
    iStr->Read((char *)mInpBuffer, streamLen, &unused);

    if (mMode == HTTP_COMPRESS_DEFLATE) {
      if (!mStreamInitialized) {
        memset(&d_stream, 0, sizeof (d_stream));

        if (inflateInit(&d_stream) != Z_OK) {
          return NS_ERROR_FAILURE;
        }

        mStreamInitialized = true;
      }
      d_stream.next_in = mInpBuffer;
      d_stream.avail_in = (uInt)streamLen;

      mDummyStreamInitialised = false;
      for (;;) {
        d_stream.next_out = mOutBuffer;
        d_stream.avail_out = (uInt)mOutBufferLen;

        int code = inflate(&d_stream, Z_NO_FLUSH);
        unsigned bytesWritten = (uInt)mOutBufferLen - d_stream.avail_out;

        if (code == Z_STREAM_END) {
          if (bytesWritten) {
            rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten);
            if (NS_FAILED (rv)) {
              return rv;
            }
          }

          inflateEnd(&d_stream);
          mStreamEnded = true;
          break;
        } else if (code == Z_OK) {
          if (bytesWritten) {
            rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten);
            if (NS_FAILED (rv)) {
              return rv;
            }
          }
        } else if (code == Z_BUF_ERROR) {
          if (bytesWritten) {
            rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten);
            if (NS_FAILED (rv)) {
              return rv;
            }
          }
          break;
        } else if (code == Z_DATA_ERROR) {
          // some servers (notably Apache with mod_deflate) don't generate zlib headers
          // insert a dummy header and try again
          static char dummy_head[2] =
            {
              0x8 + 0x7 * 0x10,
              (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
            };
          inflateReset(&d_stream);
          d_stream.next_in = (Bytef*) dummy_head;
          d_stream.avail_in = sizeof(dummy_head);

          code = inflate(&d_stream, Z_NO_FLUSH);
          if (code != Z_OK) {
            return NS_ERROR_FAILURE;
          }

          // stop an endless loop caused by non-deflate data being labelled as deflate
          if (mDummyStreamInitialised) {
            NS_WARNING("endless loop detected"
                       " - invalid deflate");
            return NS_ERROR_INVALID_CONTENT_ENCODING;
          }
          mDummyStreamInitialised = true;
          // reset stream pointers to our original data
          d_stream.next_in = mInpBuffer;
          d_stream.avail_in = (uInt)streamLen;
        } else {
          return NS_ERROR_INVALID_CONTENT_ENCODING;
        }
      } /* for */
    } else {
      if (!mStreamInitialized) {
        memset(&d_stream, 0, sizeof (d_stream));

        if (inflateInit2(&d_stream, -MAX_WBITS) != Z_OK) {
          return NS_ERROR_FAILURE;
        }

        mStreamInitialized = true;
      }

      d_stream.next_in  = mInpBuffer;
      d_stream.avail_in = (uInt)streamLen;

      for (;;) {
        d_stream.next_out  = mOutBuffer;
        d_stream.avail_out = (uInt)mOutBufferLen;

        int code = inflate (&d_stream, Z_NO_FLUSH);
        unsigned bytesWritten = (uInt)mOutBufferLen - d_stream.avail_out;

        if (code == Z_STREAM_END) {
          if (bytesWritten) {
            rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten);
            if (NS_FAILED (rv)) {
              return rv;
            }
          }

          inflateEnd(&d_stream);
          mStreamEnded = true;
          break;
        } else if (code == Z_OK) {
          if (bytesWritten) {
            rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten);
            if (NS_FAILED (rv)) {
              return rv; 
            }
          }
        } else if (code == Z_BUF_ERROR) {
          if (bytesWritten) {
            rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten);
            if (NS_FAILED (rv)) {
              return rv;
            }
          }
          break;
        } else {
          return NS_ERROR_INVALID_CONTENT_ENCODING;
        }
      } /* for */
    } /* gzip */
    break;

  case HTTP_COMPRESS_BROTLI:
  {
    if (!mBrotli) {
      mBrotli = new BrotliWrapper();
    }

    mBrotli->mRequest = request;
    mBrotli->mContext = aContext;
    mBrotli->mSourceOffset = aSourceOffset;

    uint32_t countRead;
    rv = iStr->ReadSegments(BrotliHandler, this, streamLen, &countRead);
    if (NS_SUCCEEDED(rv)) {
      rv = mBrotli->mStatus;
    }
    if (NS_FAILED(rv)) {
      return rv;
    }
  }
    break;

  default:
    rv = mListener->OnDataAvailable(request, aContext, iStr, aSourceOffset, aCount);
    if (NS_FAILED (rv)) {
      return rv;
    }
  } /* switch */

  return NS_OK;
} /* OnDataAvailable */
Exemplo n.º 16
0
/*
  Open for reading data the current file in the zipfile.
  If there is no error and the file is opened, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFile3 (
    unzFile file,
    int* method,
    int* level,
    int raw,
    const char* password)
{
    int err=UNZ_OK;
    uInt iSizeVar;
    unz_s* s;
    file_in_zip_read_info_s* pfile_in_zip_read_info;
    uLong offset_local_extrafield;  /* offset of the local extra field */
    uInt  size_local_extrafield;    /* size of the local extra field */
#    ifndef NOUNCRYPT
    char source[12];
#    else
    if (password != NULL)
        return UNZ_PARAMERROR;
#    endif

    if (file==NULL)
        return UNZ_PARAMERROR;
    s=(unz_s*)file;
    if (!s->current_file_ok)
        return UNZ_PARAMERROR;

    if (s->pfile_in_zip_read != NULL)
        unzCloseCurrentFile(file);

    if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
                &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
        return UNZ_BADZIPFILE;

    pfile_in_zip_read_info = (file_in_zip_read_info_s*)
                                        ALLOC(sizeof(file_in_zip_read_info_s));
    if (pfile_in_zip_read_info==NULL)
        return UNZ_INTERNALERROR;

    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
    pfile_in_zip_read_info->pos_local_extrafield=0;
    pfile_in_zip_read_info->raw=raw;

    if (pfile_in_zip_read_info->read_buffer==NULL)
    {
        TRYFREE(pfile_in_zip_read_info);
        return UNZ_INTERNALERROR;
    }

    pfile_in_zip_read_info->stream_initialised=0;

    if (method!=NULL)
        *method = (int)s->cur_file_info.compression_method;

    if (level!=NULL)
    {
        *level = 6;
        switch (s->cur_file_info.flag & 0x06)
        {
          case 6 : *level = 1; break;
          case 4 : *level = 2; break;
          case 2 : *level = 9; break;
        }
    }

#ifndef NO_ZLIB
    if ((s->cur_file_info.compression_method!=0) &&
        (s->cur_file_info.compression_method!=Z_DEFLATED))
        err=UNZ_BADZIPFILE;
#else
    if ((s->cur_file_info.compression_method!=0))
        err=UNZ_BADZIPFILE;
#endif

    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
    pfile_in_zip_read_info->crc32=0;
    pfile_in_zip_read_info->compression_method =
            s->cur_file_info.compression_method;
    pfile_in_zip_read_info->filestream=s->filestream;
    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;

    pfile_in_zip_read_info->stream.total_out = 0;

#ifndef NO_ZLIB
    if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
        (!raw))
    {
      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
      pfile_in_zip_read_info->stream.zfree = (free_func)0;
      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
      pfile_in_zip_read_info->stream.avail_in = 0;

      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
      if (err == Z_OK)
        pfile_in_zip_read_info->stream_initialised=1;
      else
      {
        TRYFREE(pfile_in_zip_read_info);
        return err;
      }
        /* windowBits is passed < 0 to tell that there is no zlib header.
         * Note that in this case inflate *requires* an extra "dummy" byte
         * after the compressed stream in order to complete decompression and
         * return Z_STREAM_END.
         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
         * size of both compressed and uncompressed data
         */
    }
#endif
    pfile_in_zip_read_info->rest_read_compressed =
            s->cur_file_info.compressed_size ;
    pfile_in_zip_read_info->rest_read_uncompressed =
            s->cur_file_info.uncompressed_size ;


    pfile_in_zip_read_info->pos_in_zipfile =
            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
              iSizeVar;

    pfile_in_zip_read_info->stream.avail_in = (uInt)0;

    s->pfile_in_zip_read = pfile_in_zip_read_info;

#    ifndef NOUNCRYPT
    if (password != NULL)
    {
        int i;
        s->pcrc_32_tab = get_crc_table();
        init_keys(password,s->keys,s->pcrc_32_tab);
        if (ZSEEK(s->z_filefunc, s->filestream,
                  s->pfile_in_zip_read->pos_in_zipfile +
                     s->pfile_in_zip_read->byte_before_the_zipfile,
                  SEEK_SET)!=0)
            return UNZ_INTERNALERROR;
        if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
            return UNZ_INTERNALERROR;

        for (i = 0; i<12; i++)
            zdecode(s->keys,s->pcrc_32_tab,source[i]);

        s->pfile_in_zip_read->pos_in_zipfile+=12;
        s->encrypted=1;
    }
#    endif


    return UNZ_OK;
}
Exemplo n.º 17
0
/*
  Open for reading data the current file in the zipfile.
  If there is no error and the file is opened, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFile (unzFile file)
{
	int err=UNZ_OK;
	int Store;
	uInt iSizeVar;
	unz_s* s;
	file_in_zip_read_info_s* pfile_in_zip_read_info;
	uLong offset_local_extrafield;  /* offset of the local extra field */
	uInt  size_local_extrafield;    /* size of the local extra field */

	if (file==NULL)
		return UNZ_PARAMERROR;
	s=(unz_s*)file;
	if (!s->current_file_ok)
		return UNZ_PARAMERROR;

    if (s->pfile_in_zip_read != NULL)
        unzCloseCurrentFile(file);

	if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
				&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
		return UNZ_BADZIPFILE;

	pfile_in_zip_read_info = (file_in_zip_read_info_s*)
									    ALLOC(sizeof(file_in_zip_read_info_s));
	if (pfile_in_zip_read_info==NULL)
		return UNZ_INTERNALERROR;

	pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
	pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
	pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
	pfile_in_zip_read_info->pos_local_extrafield=0;

	if (pfile_in_zip_read_info->read_buffer==NULL)
	{
		TRYFREE(pfile_in_zip_read_info);
		return UNZ_INTERNALERROR;
	}

	pfile_in_zip_read_info->stream_initialised=0;
	
	if ((s->cur_file_info.compression_method!=0) &&
        (s->cur_file_info.compression_method!=Z_DEFLATED))
		err=UNZ_BADZIPFILE;
	Store = s->cur_file_info.compression_method==0;

	pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
	pfile_in_zip_read_info->crc32=0;
	pfile_in_zip_read_info->compression_method =
            s->cur_file_info.compression_method;
	pfile_in_zip_read_info->file=s->file;
	pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;

    pfile_in_zip_read_info->stream.total_out = 0;

	if (!Store)
	{
	  pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
	  pfile_in_zip_read_info->stream.zfree = (free_func)0;
	  pfile_in_zip_read_info->stream.opaque = (voidpf)0; 
      
	  err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
	  if (err == Z_OK)
	    pfile_in_zip_read_info->stream_initialised=1;
        /* windowBits is passed < 0 to tell that there is no zlib header.
         * Note that in this case inflate *requires* an extra "dummy" byte
         * after the compressed stream in order to complete decompression and
         * return Z_STREAM_END. 
         * In unzip, i don't wait absolutely Z_STREAM_END because I known the 
         * size of both compressed and uncompressed data
         */
	}
	pfile_in_zip_read_info->rest_read_compressed = 
            s->cur_file_info.compressed_size ;
	pfile_in_zip_read_info->rest_read_uncompressed = 
            s->cur_file_info.uncompressed_size ;

	
	pfile_in_zip_read_info->pos_in_zipfile = 
            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 
			  iSizeVar;
	
	pfile_in_zip_read_info->stream.avail_in = (uInt)0;


	s->pfile_in_zip_read = pfile_in_zip_read_info;
    return UNZ_OK;
}
Exemplo n.º 18
0
  // return new out_buf else error text
  std::string new_from_zip(const uint8_t* const in_buf,
                           const size_t in_size,
                           const size_t in_offset,
                           uint8_t** out_buf,
                           size_t* out_size) {

    // pointer to the output buffer that will be created using new
    *out_buf = NULL;
    *out_size = 0;

    // validate the buffer range
    if (in_size < in_offset + 30) {
      // nothing to do
      return "zip region too small";
    }

    const uint8_t* const b = in_buf + in_offset;

    const uint32_t compr_size=u32(b+18);
    const uint32_t uncompr_size=u32(b+22);
    const uint16_t name_len=u16(b+26);
    const uint16_t extra_field_len=u16(b+28);

    // validate name length
    if (name_len == 0 || name_len > zip_name_len_max) {
      return "invalid zip metadata";
    }

    // calculate offset to compressed data
    uint32_t compressed_offset = in_offset + 30 + name_len + extra_field_len;

    // offset must be inside the buffer
    if (compressed_offset >= in_size) {
      return "zip read request outside data range";
    }

    // size of compressed data
    const uint32_t compressed_size = (compr_size == 0 ||
               compressed_offset + compr_size > in_size) 
                          ? in_size - compressed_offset : compr_size;

    // size of uncompressed data
    const uint32_t potential_uncompressed_size =
               (compr_size == 0 || compr_size > uncompressed_size_max)
                                  ? uncompressed_size_max : uncompr_size;
    
    // skip if uncompressed size is too small
    if (potential_uncompressed_size < uncompressed_size_min) {
      return "zip uncompress size too small";
    }

    // create the uncompressed buffer
    *out_buf = new (std::nothrow) uint8_t[potential_uncompressed_size]();
    if (*out_buf == NULL) {
      // comment that the buffer acquisition request failed
      hashdb::tprint(std::cout, "# bad memory allocation in zip uncompression");
      return "bad memory allocation in zip uncompression";
    }

    // set up zlib data
    z_stream zs;
    memset(&zs, 0, sizeof(zs));
    zs.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(
                                         in_buf + compressed_offset));
    zs.avail_in = compressed_size;
    zs.next_out = *out_buf;
    zs.avail_out = potential_uncompressed_size;

    // initialize zlib for this decompression
    int r = inflateInit2(&zs, -15);
    if (r == 0) {

      // inflate
      inflate(&zs, Z_SYNC_FLUSH);

      // set out_size
      *out_size = zs.total_out;

      // close zlib
      inflateEnd(&zs);
      return "";

    } else {

      // inflate failed
      delete[] *out_buf;
      *out_buf = NULL;
      return "zip zlib inflate failed";
    }
  }
Exemplo n.º 19
0
/*
 * Uncompress "deflate" data from the archive's file to an open file
 * descriptor.
 */
static int inflateToFile(int outFd, int inFd, size_t uncompLen, size_t compLen)
{
    int result = -1;
    const size_t kBufSize = 32768;
    unsigned char* readBuf = (unsigned char*) malloc(kBufSize);
    unsigned char* writeBuf = (unsigned char*) malloc(kBufSize);
    z_stream zstream;
    int zerr;

    if (readBuf == NULL || writeBuf == NULL)
        goto bail;

    /*
     * Initialize the zlib stream struct.
     */
    memset(&zstream, 0, sizeof(zstream));
    zstream.zalloc = Z_NULL;
    zstream.zfree = Z_NULL;
    zstream.opaque = Z_NULL;
    zstream.next_in = NULL;
    zstream.avail_in = 0;
    zstream.next_out = (Bytef*) writeBuf;
    zstream.avail_out = kBufSize;
    zstream.data_type = Z_UNKNOWN;

    /*
     * Use the undocumented "negative window bits" feature to tell zlib
     * that there's no zlib header waiting for it.
     */
    zerr = inflateInit2(&zstream, -MAX_WBITS);
    if (zerr != Z_OK) {
        if (zerr == Z_VERSION_ERROR) {
            LOGE("Installed zlib is not compatible with linked version (%s)",
                ZLIB_VERSION);
        } else {
            LOGW("Call to inflateInit2 failed (zerr=%d)", zerr);
        }
        goto bail;
    }

    /*
     * Loop while we have more to do.
     */
    do {
        /* read as much as we can */
        if (zstream.avail_in == 0) {
            size_t getSize = (compLen > kBufSize) ? kBufSize : compLen;

            ssize_t actual = TEMP_FAILURE_RETRY(read(inFd, readBuf, getSize));
            if (actual != (ssize_t) getSize) {
                LOGW("Zip: inflate read failed (%d vs %zd)",
                    (int)actual, getSize);
                goto z_bail;
            }

            compLen -= getSize;

            zstream.next_in = readBuf;
            zstream.avail_in = getSize;
        }

        /* uncompress the data */
        zerr = inflate(&zstream, Z_NO_FLUSH);
        if (zerr != Z_OK && zerr != Z_STREAM_END) {
            LOGW("Zip: inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)",
                zerr, zstream.next_in, zstream.avail_in,
                zstream.next_out, zstream.avail_out);
            goto z_bail;
        }

        /* write when we're full or when we're done */
        if (zstream.avail_out == 0 ||
            (zerr == Z_STREAM_END && zstream.avail_out != kBufSize))
        {
            size_t writeSize = zstream.next_out - writeBuf;
            if (sysWriteFully(outFd, writeBuf, writeSize, "Zip inflate") != 0)
                goto z_bail;

            zstream.next_out = writeBuf;
            zstream.avail_out = kBufSize;
        }
    } while (zerr == Z_OK);

    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */

    /* paranoia */
    if (zstream.total_out != uncompLen) {
        LOGW("Zip: size mismatch on inflated file (%ld vs %zd)",
            zstream.total_out, uncompLen);
        goto z_bail;
    }

    result = 0;

z_bail:
    inflateEnd(&zstream);        /* free up any allocated structures */

bail:
    free(readBuf);
    free(writeBuf);
    return result;
}
Exemplo n.º 20
0
	char *Util::DecompressGZIP(const char *data, int dataSize, int expectedSize) 
	{
		int bufferSize = expectedSize;
		int ret;
		z_stream strm;
		char *out = (char*)malloc(bufferSize);

		strm.zalloc = Z_NULL;
		strm.zfree = Z_NULL;
		strm.opaque = Z_NULL;
		strm.next_in = (Bytef*)data;
		strm.avail_in = dataSize;
		strm.next_out = (Bytef*)out;
		strm.avail_out = bufferSize;

		ret = inflateInit2(&strm, 15 + 32);

		if (ret != Z_OK) 
		{
			free(out);
			return NULL;
		}

		do 
		{
			ret = inflate(&strm, Z_SYNC_FLUSH);

			switch (ret) 
			{
				case Z_NEED_DICT:
				case Z_STREAM_ERROR:
					ret = Z_DATA_ERROR;
				case Z_DATA_ERROR:
				case Z_MEM_ERROR:
					inflateEnd(&strm);
					free(out);
					return NULL;
			}

			if (ret != Z_STREAM_END) 
			{
				out = (char *) realloc(out, bufferSize * 2);

				if (!out) 
				{
					inflateEnd(&strm);
					free(out);
					return NULL;
				}

				strm.next_out = (Bytef *)(out + bufferSize);
				strm.avail_out = bufferSize;
				bufferSize *= 2;
			}
		}
		while (ret != Z_STREAM_END);

		if (strm.avail_in != 0) 
		{
			free(out);
			return NULL;
		}

		inflateEnd(&strm);

		return out;
	}
Exemplo n.º 21
0
char *dict_data_read_ (
   dictData *h, unsigned long start, unsigned long size,
   const char *preFilter, const char *postFilter )
{
   char          *buffer, *pt;
   unsigned long end;
   int           count;
   char          *inBuffer;
   char          outBuffer[OUT_BUFFER_SIZE];
   int           firstChunk, lastChunk;
   int           firstOffset, lastOffset;
   int           i, j;
   int           found, target, lastStamp;
   static int    stamp = 0;

   end  = start + size;

   buffer = xmalloc( size + 1 );
   
   PRINTF(DBG_UNZIP,
	  ("dict_data_read( %p, %lu, %lu, %s, %s )\n",
	   h, start, size, preFilter, postFilter ));

   assert( h != NULL);
   switch (h->type) {
   case DICT_GZIP:
      err_fatal( __func__,
		 "Cannot seek on pure gzip format files.\n"
		 "Use plain text (for performance)"
		 " or dzip format (for space savings).\n" );
      break;
   case DICT_TEXT:
      memcpy( buffer, h->start + start, size );
      buffer[size] = '\0';
      break;
   case DICT_DZIP:
      if (!h->initialized) {
	 ++h->initialized;
	 h->zStream.zalloc    = NULL;
	 h->zStream.zfree     = NULL;
	 h->zStream.opaque    = NULL;
	 h->zStream.next_in   = 0;
	 h->zStream.avail_in  = 0;
	 h->zStream.next_out  = NULL;
	 h->zStream.avail_out = 0;
	 if (inflateInit2( &h->zStream, -15 ) != Z_OK)
	    err_internal( __func__,
			  "Cannot initialize inflation engine: %s\n",
			  h->zStream.msg );
      }
      firstChunk  = start / h->chunkLength;
      firstOffset = start - firstChunk * h->chunkLength;
      lastChunk   = (end - 1) / h->chunkLength;
      if (lastChunk < firstChunk) {
	 lastChunk = firstChunk;
      }
      lastOffset  = end - lastChunk * h->chunkLength;
      PRINTF(DBG_UNZIP,
	     ("   start = %lu, end = %lu\n"
	      "firstChunk = %d, firstOffset = %d,"
	      " lastChunk = %d, lastOffset = %d\n",
	      start, end, firstChunk, firstOffset, lastChunk, lastOffset ));
      for (pt = buffer, i = firstChunk; i <= lastChunk; i++) {

				/* Access cache */
	 found  = 0;
	 target = 0;
	 lastStamp = INT_MAX;
	 for (j = 0; j < DICT_CACHE_SIZE; j++) {
#if USE_CACHE
	    if (h->cache[j].chunk == i) {
	       found  = 1;
	       target = j;
	       break;
	    }
#endif
	    if (h->cache[j].stamp < lastStamp) {
	       lastStamp = h->cache[j].stamp;
	       target = j;
	    }
	 }

	 h->cache[target].stamp = ++stamp;
	 if (found) {
	    count = h->cache[target].count;
	    inBuffer = h->cache[target].inBuffer;
	 } else {
	    h->cache[target].chunk = i;
	    if (!h->cache[target].inBuffer)
	       h->cache[target].inBuffer = xmalloc( IN_BUFFER_SIZE );
	    inBuffer = h->cache[target].inBuffer;

	    if (h->chunks[i] >= OUT_BUFFER_SIZE ) {
	       err_internal( __func__,
			     "h->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n",
			     i, h->chunks[i], OUT_BUFFER_SIZE );
	    }
	    memcpy( outBuffer, h->start + h->offsets[i], h->chunks[i] );
	    dict_data_filter( outBuffer, &count, OUT_BUFFER_SIZE, preFilter );
	 
	    h->zStream.next_in   = (Bytef *) outBuffer;
	    h->zStream.avail_in  = h->chunks[i];
	    h->zStream.next_out  = (Bytef *) inBuffer;
	    h->zStream.avail_out = IN_BUFFER_SIZE;
	    if (inflate( &h->zStream,  Z_PARTIAL_FLUSH ) != Z_OK)
	       err_fatal( __func__, "inflate: %s\n", h->zStream.msg );
	    if (h->zStream.avail_in)
	       err_internal( __func__,
			     "inflate did not flush (%d pending, %d avail)\n",
			     h->zStream.avail_in, h->zStream.avail_out );
	    
	    count = IN_BUFFER_SIZE - h->zStream.avail_out;
	    dict_data_filter( inBuffer, &count, IN_BUFFER_SIZE, postFilter );

	    h->cache[target].count = count;
	 }
	 
	 if (i == firstChunk) {
	    if (i == lastChunk) {
	       memcpy( pt, inBuffer + firstOffset, lastOffset-firstOffset);
	       pt += lastOffset - firstOffset;
	    } else {
	       if (count != h->chunkLength )
		  err_internal( __func__,
				"Length = %d instead of %d\n",
				count, h->chunkLength );
	       memcpy( pt, inBuffer + firstOffset,
		       h->chunkLength - firstOffset );
	       pt += h->chunkLength - firstOffset;
	    }
	 } else if (i == lastChunk) {
	    memcpy( pt, inBuffer, lastOffset );
	    pt += lastOffset;
	 } else {
	    assert( count == h->chunkLength );
	    memcpy( pt, inBuffer, h->chunkLength );
	    pt += h->chunkLength;
	 }
      }
      *pt = '\0';
      break;
   case DICT_UNKNOWN:
      err_fatal( __func__, "Cannot read unknown file type\n" );
      break;
   }
   
   return buffer;
}
Exemplo n.º 22
0
StaticCompressor::StaticCompressor(int compressionLevel,
                                       int compressionThreshold)
{
  buffer_     = NULL;
  bufferSize_ = 0;

  compressionStream_.zalloc = (alloc_func) 0;
  compressionStream_.zfree  = (free_func) 0;
  compressionStream_.opaque = (voidpf) 0;

  decompressionStream_.zalloc = (alloc_func) 0;
  decompressionStream_.zfree  = (free_func) 0;
  decompressionStream_.opaque = (void *) 0;

  decompressionStream_.next_in = (Bytef *) 0;
  decompressionStream_.avail_in = 0;

  #ifdef TEST
  *logofs << "StaticCompressor: Compression level is "
          << compressionLevel << ".\n" << logofs_flush;
  #endif

  int result = deflateInit2(&compressionStream_, compressionLevel, Z_DEFLATED,
                                15, 9, Z_DEFAULT_STRATEGY);

  if (result != Z_OK)
  {
    #ifdef PANIC
    *logofs << "StaticCompressor: PANIC! Cannot initialize the "
            << "compression stream. Error is '" << zError(result)
            << "'.\n" << logofs_flush;
    #endif

    cerr << "Error" << ": Cannot initialize the compression "
         << "stream. Error is '" << zError(result) << "'.\n";

    HandleAbort();
  }

  result = inflateInit2(&decompressionStream_, 15);

  if (result != Z_OK)
  {
    #ifdef PANIC
    *logofs << "StaticCompressor: PANIC! Cannot initialize the "
            << "decompression stream. Error is '" << zError(result)
            << "'.\n" << logofs_flush;
    #endif

    cerr << "Error" << ": Cannot initialize the decompression "
         << "stream. Error is '" << zError(result) << "'.\n";

    HandleAbort();
  }

  #ifdef TEST
  *logofs << "StaticCompressor: Compression threshold is "
          << compressionThreshold << ".\n" << logofs_flush;
  #endif

  threshold_ = compressionThreshold;
}
Exemplo n.º 23
0
		GunzipContentTransformer(): _streamBad(false)
		{
			memset(&_inflateStream, 0, sizeof(z_stream));
			inflateInit2(&_inflateStream, 31);
		}
Exemplo n.º 24
0
static unsigned char *
cbz_read_zip_entry(cbz_document *doc, cbz_entry *entry, int *sizep)
{
	fz_context *ctx = doc->ctx;
	fz_stream *file = doc->file;
	int sig, general, method, namelength, extralength;
	unsigned char *cdata;
	int code;

	fz_seek(file, entry->offset, 0);

	sig = getlong(doc->file);
	if (sig != ZIP_LOCAL_FILE_SIG)
		fz_throw(ctx, FZ_ERROR_GENERIC, "wrong zip local file signature (0x%x)", sig);

	(void) getshort(doc->file); /* version */
	general = getshort(doc->file); /* general */
	if (general & ZIP_ENCRYPTED_FLAG)
		fz_throw(doc->ctx, FZ_ERROR_GENERIC, "zipfile content is encrypted");

	method = getshort(doc->file);
	(void) getshort(doc->file); /* file time */
	(void) getshort(doc->file); /* file date */
	(void) getlong(doc->file); /* crc-32 */
	(void) getlong(doc->file); /* csize */
	(void) getlong(doc->file); /* usize */
	namelength = getshort(doc->file);
	extralength = getshort(doc->file);

	fz_seek(file, namelength + extralength, 1);

	cdata = fz_malloc(ctx, entry->csize);
	fz_try(ctx)
	{
		fz_read(file, cdata, entry->csize);
	}
	fz_catch(ctx)
	{
		fz_free(ctx, cdata);
		fz_rethrow(ctx);
	}

	if (method == 0)
	{
		*sizep = entry->usize;
		return cdata;
	}

	if (method == 8)
	{
		unsigned char *udata = fz_malloc(ctx, entry->usize);
		z_stream stream;

		memset(&stream, 0, sizeof stream);
		stream.zalloc = cbz_zip_alloc_items;
		stream.zfree = cbz_zip_free;
		stream.opaque = ctx;
		stream.next_in = cdata;
		stream.avail_in = entry->csize;
		stream.next_out = udata;
		stream.avail_out = entry->usize;

		fz_try(ctx)
		{
			code = inflateInit2(&stream, -15);
			if (code != Z_OK)
				fz_throw(ctx, FZ_ERROR_GENERIC, "zlib inflateInit2 error: %s", stream.msg);
			code = inflate(&stream, Z_FINISH);
			if (code != Z_STREAM_END) {
				inflateEnd(&stream);
				fz_throw(ctx, FZ_ERROR_GENERIC, "zlib inflate error: %s", stream.msg);
			}
			code = inflateEnd(&stream);
			if (code != Z_OK)
				fz_throw(ctx, FZ_ERROR_GENERIC, "zlib inflateEnd error: %s", stream.msg);
		}
		fz_always(ctx)
		{
			fz_free(ctx, cdata);
		}
		fz_catch(ctx)
		{
			fz_free(ctx, udata);
			fz_rethrow(ctx);
		}

		*sizep = entry->usize;
		return udata;
	}
Exemplo n.º 25
0
// If the contents of this buffer are between headers and compressed with gzip, this method can remove all that
// Returns false on error
BOOL CBuffer::Ungzip()
{
    // Make sure there are at least 10 bytes in this buffer
    if ( m_nLength < 10 ) return FALSE;

    // Make sure the first 3 bytes are not 1f8b08
    if ( m_pBuffer[0] != 0x1F || m_pBuffer[1] != 0x8B || m_pBuffer[2] != 8 ) return FALSE;

    // At a distance of 3 bytes into the buffer, read the byte there and call it nFlags
    BYTE nFlags = m_pBuffer[3];

    // Remove the first 10 bytes of the buffer
    Remove( 10 );

    // If there is a 1 in position 0000 0100 in the flags byte
    if ( nFlags & 0x04 )
    {
        // Make sure the buffer has 2 or more bytes
        if ( m_nLength < 2 ) return FALSE;

        // Look at the first 2 bytes in the buffer as a word, this says how long the data it beyond it
        WORD nLen = *(WORD*)m_pBuffer;

        // If the buffer has less data than it should, return false
        if ( (int)m_nLength < (int)nLen + 2 ) return FALSE;

        // Remove the length word and the length it describes from the front of the buffer
        Remove( 2 + nLen );
    }

    // If there is a 1 in position 0000 1000 in the flags byte
    if ( nFlags & 0x08 )
    {
        // Loop until after we remove a 0 byte from the buffer
        for ( ;; )
        {
            // If the buffer is empty, return false
            if ( m_nLength == 0 ) return FALSE;

            // Move the first byte of the buffer into an int
            int nChar = m_pBuffer[0]; // Copy one byte from the start of the buffer into an int named nChar
            Remove( 1 );              // Remove that first byte from the buffer

            // If we just removed a 0 byte, exit the loop
            if ( nChar == 0 ) break;
        }
    }

    // If there is a 1 in position 0001 0000 in the flags byte
    if ( nFlags & 0x10 )
    {
        // Loop until after we remove a 0 byte from the buffer
        for ( ;; )
        {
            // If the buffer is empty, return false
            if ( m_nLength == 0 ) return FALSE;

            // Move the first byte of the buffer into an int
            int nChar = m_pBuffer[0]; // Copy one byte from the start of the buffer into an int named nChar
            Remove( 1 );              // Remove that first byte from the buffer

            // If we just removed a 0 byte, exit the loop
            if ( nChar == 0 ) break;
        }
    }

    // If there is a 1 in position 0000 0010 in the flags byte
    if ( nFlags & 0x02 )
    {
        // Make sure the buffer has at least 2 bytes, and then remove them
        if ( m_nLength < 2 ) return FALSE;
        Remove( 2 );
    }

    // After removing all that header information from the front, remove the last 8 bytes from the end
    if ( m_nLength <= 8 ) return FALSE; // Make sure the buffer has more than 8 bytes
    m_nLength -= 8;                     // Remove the last 8 bytes in the buffer

    // Setup a z_stream structure to perform a raw inflate
    z_stream pStream;
    ZeroMemory( &pStream, sizeof(pStream) );
    if ( Z_OK != inflateInit2( // Initialize a stream inflation with more options than just inflateInit
                &pStream,              // Stream structure to initialize
                -MAX_WBITS ) ) {       // Window bits value of -15 to perform a raw inflate

        // The Zlib function inflateInit2 returned something other than Z_OK, report error
        return FALSE;
    }

    // Make a new buffer for the output
    CBuffer pOutput;
    pOutput.EnsureBuffer( m_nLength * 6 ); // Guess that inflating the data won't make it more than 6 times as big

    // Tell the z_stream structure where to work
    pStream.next_in   = m_pBuffer;         // Decompress the memory here
    pStream.avail_in  = m_nLength;         // There is this much of it
    pStream.next_out  = pOutput.m_pBuffer; // Write decompressed data here
    pStream.avail_out = pOutput.m_nBuffer; // Tell ZLib it has this much space, it make this smaller to show how much space is left

    // Call ZLib inflate to decompress all the data, and see if it returns Z_STREAM_END
    BOOL bSuccess = ( Z_STREAM_END == inflate( &pStream, Z_FINISH ) );

    // The inflate call returned Z_STREAM_END
    if ( bSuccess )
    {
        // Move the decompressed data from the output buffer into this one
        Clear();                   // Record there are no bytes stored here, doesn't change the allocated block size
        Add(pOutput.m_pBuffer,     // Add the memory at the start of the output buffer
            pOutput.m_nBuffer      // The amount of space the buffer had when we gave it to Zlib
            - pStream.avail_out ); // Minus the amount it said it left, this is the number of bytes it wrote

        // Close ZLib and report success
        inflateEnd( &pStream );
        return TRUE;

    } // The inflate call returned something else
    else
    {
        // Close ZLib and report error
        inflateEnd( &pStream );
        return FALSE;
    }
}
Exemplo n.º 26
0
static int
zf_open(const char *fname, struct open_file *f)
{
    char		*zfname;
    int			rawfd;
    struct z_file	*zf;
    char		*cp;
    int			error;
    struct stat		sb;

    /* Have to be in "just read it" mode */
    if ((f->f_flags & (F_READ | F_WRITE)) != F_READ)
        return(EPERM);

    /* If the name already ends in .gz or .bz2, ignore it */
    if ((cp = strrchr(fname, '.')) && (!strcmp(cp, ".gz")
                                       || !strcmp(cp, ".bz2") || !strcmp(cp, ".split")))
        return(ENOENT);

    /* Construct new name */
    zfname = malloc(strlen(fname) + 4);
    if (zfname == NULL)
        return(ENOMEM);
    sprintf(zfname, "%s.gz", fname);

    /* Try to open the compressed datafile */
    rawfd = open(zfname, O_RDONLY);
    free(zfname);
    if (rawfd == -1)
        return(ENOENT);

    if (fstat(rawfd, &sb) < 0) {
        printf("zf_open: stat failed\n");
        close(rawfd);
        return(ENOENT);
    }
    if (!S_ISREG(sb.st_mode)) {
        printf("zf_open: not a file\n");
        close(rawfd);
        return(EISDIR);			/* best guess */
    }

    /* Allocate a z_file structure, populate it */
    zf = malloc(sizeof(struct z_file));
    if (zf == NULL)
        return(ENOMEM);
    bzero(zf, sizeof(struct z_file));
    zf->zf_rawfd = rawfd;

    /* Verify that the file is gzipped (XXX why do this afterwards?) */
    if (check_header(zf)) {
        close(zf->zf_rawfd);
        inflateEnd(&(zf->zf_zstream));
        free(zf);
        return(EFTYPE);
    }

    /* Initialise the inflation engine */
    if ((error = inflateInit2(&(zf->zf_zstream), -15)) != Z_OK) {
        printf("zf_open: inflateInit returned %d : %s\n", error, zf->zf_zstream.msg);
        close(zf->zf_rawfd);
        free(zf);
        return(EIO);
    }

    /* Looks OK, we'll take it */
    f->f_fsdata = zf;
    return(0);
}
Exemplo n.º 27
0
int ungzip(std::ifstream &file, std::stringstream &ss) {
    std::string gzipedBytes;
    gzipedBytes.clear();
    ss.flush();

    while (!file.eof()) {
        gzipedBytes += (char) file.get();
    }
    file.close();

    if (gzipedBytes.size() == 0) {
        ss << gzipedBytes;
        return 0;
    }

    unsigned int full_length  = gzipedBytes.size();
    unsigned int half_length  = gzipedBytes.size()/2;
    unsigned int uncompLength = full_length;

    char* uncomp = (char*) calloc(sizeof(char), uncompLength);

    z_stream strm;
    strm.next_in   = (Bytef *) gzipedBytes.c_str();
    strm.avail_in  = full_length;
    strm.total_out = 0;
    strm.zalloc    = Z_NULL;
    strm.zfree     = Z_NULL;

    bool done = false;

    if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
        free(uncomp);
        return 1;
    }

    while (!done) {
        // If our output buffer is too small
        if (strm.total_out >= uncompLength) {
            // Increase size of output buffer
            char* uncomp2 = (char*) calloc(sizeof(char), uncompLength + half_length);
            memcpy(uncomp2, uncomp, uncompLength);
            uncompLength += half_length;
            free(uncomp);
            uncomp = uncomp2;
        }

        strm.next_out  = (Bytef *) (uncomp + strm.total_out);
        strm.avail_out = uncompLength - strm.total_out;

        // Inflate another chunk.
        int err = inflate (&strm, Z_SYNC_FLUSH);
        if (err == Z_STREAM_END) {
            done = true;
        } else if (err != Z_OK) {
            break;
        }
    }

    if (inflateEnd (&strm) != Z_OK) {
        free(uncomp);
        return 1;
    }

    for (size_t i = 0; i < strm.total_out; ++i) {
        ss << uncomp[i];
    }
    free(uncomp);

    return 0;
}
Exemplo n.º 28
0
bool ReaderWriterGZ::read(std::istream& fin, std::string& destination) const
{
    int ret;
    unsigned have;
    z_stream strm;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];

    /* allocate inflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit2(&strm,
                       15 + 32 // autodetected zlib or gzip header
                       );
    if (ret != Z_OK)
        return false;

    /* decompress until deflate stream ends or end of file */
    do {

        fin.read((char*)in, CHUNK);
        strm.avail_in = fin.gcount();

        if (fin.bad())
        {
            (void)inflateEnd(&strm);
            return false;
        }
        if (strm.avail_in == 0)
            break;
        strm.next_in = in;

        /* run inflate() on input until output buffer not full */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = inflate(&strm, Z_NO_FLUSH);

            switch (ret) {
            case Z_NEED_DICT:
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                (void)inflateEnd(&strm);
                return false;
            }
            have = CHUNK - strm.avail_out;

            destination.append((char*)out, have);

        } while (strm.avail_out == 0);

        /* done when inflate() says it's done */
    } while (ret != Z_STREAM_END);

    /* clean up and return */
    (void)inflateEnd(&strm);
    return ret == Z_STREAM_END ? true : false;
}
Exemplo n.º 29
0
static void
extractFile(const char * path, const struct cdir_entry *entry, void * data)
{
  uint32_t size = letoh32(entry->uncompressed_size);

  struct stat status;
  if (!stat(path, &status) &&
      status.st_size == size &&
      apk_mtime < status.st_mtime)
    return;

  int fd = open(path, O_CREAT | O_NOATIME | O_TRUNC | O_RDWR, S_IRWXU);
  if (fd == -1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open %s to decompress library", path);
    return;
  }

  if (ftruncate(fd, size) == -1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't ftruncate %s to decompress library", path);
    close(fd);
    return;
  }

  void * buf = mmap(NULL, size, PROT_READ | PROT_WRITE,
                    MAP_SHARED, fd, 0);
  if (buf == (void *)-1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
    close(fd);
    return;
  }

  z_stream strm = {
    next_in: (Bytef *)data,
    avail_in: letoh32(entry->compressed_size),
    total_in: 0,

    next_out: (Bytef *)buf,
    avail_out: size,
    total_out: 0
  };

  int ret;
  ret = inflateInit2(&strm, -MAX_WBITS);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateInit failed: %s", strm.msg);

  if (inflate(&strm, Z_FINISH) != Z_STREAM_END)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflate failed: %s", strm.msg);

  if (strm.total_out != size)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "extracted %d, expected %d!", strm.total_out, size);

  ret = inflateEnd(&strm);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateEnd failed: %s", strm.msg);

  close(fd);
#ifdef ANDROID_ARM_LINKER
  /* We just extracted data that is going to be executed in the future.
   * We thus need to ensure Instruction and Data cache coherency. */
  cacheflush((unsigned) buf, (unsigned) buf + size, 0);
#endif
  munmap(buf, size);
}

static void
extractLib(const struct cdir_entry *entry, void * data, void * dest)
{
  z_stream strm = {
    next_in: (Bytef *)data,
    avail_in: letoh32(entry->compressed_size),
    total_in: 0,

    next_out: (Bytef *)dest,
    avail_out: letoh32(entry->uncompressed_size),
    total_out: 0
  };

  int ret;
  ret = inflateInit2(&strm, -MAX_WBITS);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateInit failed: %s", strm.msg);

  ret = inflate(&strm, Z_SYNC_FLUSH);
  if (ret != Z_STREAM_END)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflate failed: %s", strm.msg);

  ret = inflateEnd(&strm);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateEnd failed: %s", strm.msg);

  if (strm.total_out != letoh32(entry->uncompressed_size))
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "File not fully uncompressed! %d / %d", strm.total_out, letoh32(entry->uncompressed_size));
}
Exemplo n.º 30
0
static ErlDrvSSizeT zlib_ctl(ErlDrvData drv_data, unsigned int command, char *buf,
			     ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen)
{
    ZLibData* d = (ZLibData*)drv_data;
    int res;

    switch(command) {
    case DEFLATE_INIT:
	if (len != 4) goto badarg;
	if (d->state != ST_NONE) goto badarg;
	res = deflateInit(&d->s, i32(buf));
	if (res == Z_OK) {
	    d->state = ST_DEFLATE;
	    d->want_crc = 0;
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);

    case DEFLATE_INIT2: {
	int wbits;

	if (len != 20) goto badarg;
	if (d->state != ST_NONE) goto badarg;
	wbits = i32(buf+8);
	res = deflateInit2(&d->s, i32(buf), i32(buf+4), wbits, 
			   i32(buf+12), i32(buf+16));
	if (res == Z_OK) {
	    d->state = ST_DEFLATE;
	    d->want_crc = (wbits < 0);
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);
    }
	
    case DEFLATE_SETDICT:
	if (d->state != ST_DEFLATE) goto badarg;
	res = deflateSetDictionary(&d->s, (unsigned char*)buf, len);
	if (res == Z_OK) {
	    return zlib_value(d->s.adler, rbuf, rlen);
	} else {
	    return zlib_return(res, rbuf, rlen);
	}

    case DEFLATE_RESET:
	if (len != 0) goto badarg;
	if (d->state != ST_DEFLATE) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = deflateReset(&d->s);
	return zlib_return(res, rbuf, rlen);	
	
    case DEFLATE_END:
	if (len != 0) goto badarg;
	if (d->state != ST_DEFLATE) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = deflateEnd(&d->s);
	d->state = ST_NONE;
	return zlib_return(res, rbuf, rlen);

    case DEFLATE_PARAMS:
	if (len != 8) goto badarg;
	if (d->state != ST_DEFLATE) goto badarg;
	res = deflateParams(&d->s, i32(buf), i32(buf+4));
	return zlib_return(res, rbuf, rlen);

    case DEFLATE:
	if (d->state != ST_DEFLATE) goto badarg;
	if (len != 4) goto badarg;
	res = zlib_deflate(d, i32(buf));
	return zlib_return(res, rbuf, rlen);

    case INFLATE_INIT:
	if (len != 0) goto badarg;
	if (d->state != ST_NONE) goto badarg;
	res = inflateInit(&d->s);
	if (res == Z_OK) {
	    d->state = ST_INFLATE;
	    d->inflate_eos_seen = 0;
	    d->want_crc = 0;
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);	
	
    case INFLATE_INIT2: {
	int wbits;

	if (len != 4) goto badarg;	
	if (d->state != ST_NONE) goto badarg;
	wbits = i32(buf);
	res = inflateInit2(&d->s, wbits);
	if (res == Z_OK) {
	    d->state = ST_INFLATE;
	    d->inflate_eos_seen = 0;
	    d->want_crc = (wbits < 0);
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);
    }
	
    case INFLATE_SETDICT:
	if (d->state != ST_INFLATE) goto badarg;
	res = inflateSetDictionary(&d->s, (unsigned char*)buf, len);
	return zlib_return(res, rbuf, rlen);

    case INFLATE_SYNC:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 0) goto badarg;
	if (driver_sizeq(d->port) == 0) {
	    res = Z_BUF_ERROR;
	} else {
	    int vlen;
	    SysIOVec* iov = driver_peekq(d->port, &vlen);

	    d->s.next_in = iov[0].iov_base;
	    d->s.avail_in = iov[0].iov_len;
	    res = inflateSync(&d->s);
	}
	return zlib_return(res, rbuf, rlen);

    case INFLATE_RESET:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 0) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = inflateReset(&d->s);
	d->inflate_eos_seen = 0;
	return zlib_return(res, rbuf, rlen);

    case INFLATE_END:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 0) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = inflateEnd(&d->s);
	if (res == Z_OK && d->inflate_eos_seen == 0) {
	    res = Z_DATA_ERROR;
	}
	d->state = ST_NONE;
	return zlib_return(res, rbuf, rlen);

    case INFLATE:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 4) goto badarg;
	res = zlib_inflate(d, i32(buf));
	if (res == Z_NEED_DICT) {
	    return zlib_value2(3, d->s.adler, rbuf, rlen);
	} else {
	    return zlib_return(res, rbuf, rlen);
	}

    case GET_QSIZE:
	return zlib_value(driver_sizeq(d->port), rbuf, rlen);

    case GET_BUFSZ:
	return zlib_value(d->binsz_need, rbuf, rlen);

    case SET_BUFSZ: {
	int need;
	if (len != 4) goto badarg;
	need = i32(buf);
	if ((need < 16) || (need > 0x00ffffff))
	    goto badarg;
	if (d->binsz_need != need) {
	    d->binsz_need = need;
	    if (d->bin != NULL) {
		if (d->s.avail_out == d->binsz) {
		    driver_free_binary(d->bin);
		    d->bin = NULL;
		    d->binsz = 0;
		}
		else
		    zlib_output(d);
	    }
	}
	return zlib_return(Z_OK, rbuf, rlen);
    }

    case CRC32_0:
	return zlib_value(d->crc, rbuf, rlen);

    case CRC32_1: {
	uLong crc = crc32(0L, Z_NULL, 0);
	crc = crc32(crc, (unsigned char*) buf, len);
	return zlib_value(crc, rbuf, rlen);
    }
	
    case CRC32_2: {
	uLong crc;
	if (len < 4) goto badarg;
	crc = (unsigned int) i32(buf);
	crc = crc32(crc, (unsigned char*) buf+4, len-4);
	return zlib_value(crc, rbuf, rlen);
    }

    case ADLER32_1: {
	uLong adler = adler32(0L, Z_NULL, 0);
	adler = adler32(adler, (unsigned char*) buf, len);
	return zlib_value(adler, rbuf, rlen);
    }
	
    case ADLER32_2: {
       uLong adler;
       if (len < 4) goto badarg;
       adler = (unsigned int) i32(buf);
       adler = adler32(adler, (unsigned char*) buf+4, len-4);
       return zlib_value(adler, rbuf, rlen);
    }

    case CRC32_COMBINE: {
       uLong crc, crc1, crc2, len2;
       if (len != 12) goto badarg;
       crc1 = (unsigned int) i32(buf);
       crc2 = (unsigned int) i32(buf+4);
       len2 = (unsigned int) i32(buf+8);
       crc = crc32_combine(crc1, crc2, len2);
       return zlib_value(crc, rbuf, rlen);
    }

    case ADLER32_COMBINE: {
       uLong adler, adler1, adler2, len2;
       if (len != 12) goto badarg;
       adler1 = (unsigned int) i32(buf);
       adler2 = (unsigned int) i32(buf+4);
       len2   = (unsigned int) i32(buf+8);
       adler  = adler32_combine(adler1, adler2, len2);
       return zlib_value(adler, rbuf, rlen);
    }       
    }

 badarg:
    errno = EINVAL;
    return zlib_return(Z_ERRNO, rbuf, rlen);
}