Esempio n. 1
0
std::unique_ptr<IOBuf> ZlibCodec::doUncompress(const IOBuf* data,
                                               uint64_t uncompressedLength) {
  z_stream stream;
  stream.zalloc = nullptr;
  stream.zfree = nullptr;
  stream.opaque = nullptr;

  // "The windowBits parameter is the base two logarithm of the maximum window
  // size (...) The default value is 15 (...) add 16 to decode only the gzip
  // format (the zlib format will return a Z_DATA_ERROR)."
  int windowBits = 15 + (type() == CodecType::GZIP ? 16 : 0);
  int rc = inflateInit2(&stream, windowBits);
  if (rc != Z_OK) {
    throw std::runtime_error(to<std::string>(
        "ZlibCodec: inflateInit error: ", rc, ": ", stream.msg));
  }

  stream.next_in = stream.next_out = nullptr;
  stream.avail_in = stream.avail_out = 0;
  stream.total_in = stream.total_out = 0;

  bool success = false;

  SCOPE_EXIT {
    int rc = inflateEnd(&stream);
    // If we're here because of an exception, it's okay if some data
    // got dropped.
    CHECK(rc == Z_OK || (!success && rc == Z_DATA_ERROR))
      << rc << ": " << stream.msg;
  };

  // Max 64MiB in one go
  constexpr uint32_t maxSingleStepLength = uint32_t(64) << 20;    // 64MiB
  constexpr uint32_t defaultBufferLength = uint32_t(4) << 20;     // 4MiB

  auto out = addOutputBuffer(
      &stream,
      ((uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
        uncompressedLength <= maxSingleStepLength) ?
       uncompressedLength :
       defaultBufferLength));

  bool streamEnd = false;
  for (auto& range : *data) {
    if (range.empty()) {
      continue;
    }

    stream.next_in = const_cast<uint8_t*>(range.data());
    stream.avail_in = range.size();

    while (stream.avail_in != 0) {
      if (streamEnd) {
        throw std::runtime_error(to<std::string>(
            "ZlibCodec: junk after end of data"));
      }

      streamEnd = doInflate(&stream, out.get(), defaultBufferLength);
    }
  }

  while (!streamEnd) {
    streamEnd = doInflate(&stream, out.get(), defaultBufferLength);
  }

  out->prev()->trimEnd(stream.avail_out);

  if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
      uncompressedLength != stream.total_out) {
    throw std::runtime_error(to<std::string>(
        "ZlibCodec: invalid uncompressed length"));
  }

  success = true;  // we survived

  return out;
}
Esempio n. 2
0
std::unique_ptr<IOBuf> LZMA2Codec::doUncompress(const IOBuf* data,
                                               uint64_t uncompressedLength) {
  lzma_ret rc;
  lzma_stream stream = LZMA_STREAM_INIT;

  rc = lzma_auto_decoder(&stream, std::numeric_limits<uint64_t>::max(), 0);
  if (rc != LZMA_OK) {
    throw std::runtime_error(folly::to<std::string>(
      "LZMA2Codec: lzma_auto_decoder error: ", rc));
  }

  SCOPE_EXIT { lzma_end(&stream); };

  // Max 64MiB in one go
  constexpr uint32_t maxSingleStepLength = uint32_t(64) << 20;    // 64MiB
  constexpr uint32_t defaultBufferLength = uint32_t(4) << 20;     // 4MiB

  folly::io::Cursor cursor(data);
  uint64_t actualUncompressedLength;
  if (encodeSize()) {
    actualUncompressedLength = decodeVarintFromCursor(cursor);
    if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH &&
        uncompressedLength != actualUncompressedLength) {
      throw std::runtime_error("LZMA2Codec: invalid uncompressed length");
    }
  } else {
    actualUncompressedLength = uncompressedLength;
    DCHECK_NE(actualUncompressedLength, UNKNOWN_UNCOMPRESSED_LENGTH);
  }

  auto out = addOutputBuffer(
      &stream,
      (actualUncompressedLength <= maxSingleStepLength ?
       actualUncompressedLength :
       defaultBufferLength));

  bool streamEnd = false;
  auto buf = cursor.peekBytes();
  while (!buf.empty()) {
    stream.next_in = const_cast<uint8_t*>(buf.data());
    stream.avail_in = buf.size();

    while (stream.avail_in != 0) {
      if (streamEnd) {
        throw std::runtime_error(to<std::string>(
            "LZMA2Codec: junk after end of data"));
      }

      streamEnd = doInflate(&stream, out.get(), defaultBufferLength);
    }

    cursor.skip(buf.size());
    buf = cursor.peekBytes();
  }

  while (!streamEnd) {
    streamEnd = doInflate(&stream, out.get(), defaultBufferLength);
  }

  out->prev()->trimEnd(stream.avail_out);

  if (actualUncompressedLength != stream.total_out) {
    throw std::runtime_error(to<std::string>(
        "LZMA2Codec: invalid uncompressed length"));
  }

  return out;
}
Esempio n. 3
0
int displayEmbeddedProdAndBsp(void)
{
	int							result;
	int							returnVal = 0;
	char						*p;
	char						*p1, *p2;
	char						productName[64];
	char						bspName[64];
	int							prodStringFound = 0;
	int							bspStringFound = 0;

/*
 * First, perform the inflate from the compressed buffer to the
 * application buffer
 */

	if ((result = doInflate(cmpBuffer, appBuffer)) != ERR_OK)
		return(returnVal);

/* 
 * In the application buffer, look for both search patterns so
 * as to locate the Product and BSP names. Use memchr to find the
 * first character ('T'), then compare rest of string. If not found,
 * resume search for next occurrence of 'T'.
 */

	p = memchr(appBuffer, TEE, appBufferSize);
	if (p == NULL) {
		returnVal = 0;
		goto fail;
	}
	while (!prodStringFound && (p != NULL))
	{
		if (memcmp(p, PROD_SEARCH_STRING, strlen(PROD_SEARCH_STRING)) == 0)
		{
			prodStringFound = 1;
			returnVal = 1;
			p1 = strchr(p, COLON) + 1;
			if (p1 == NULL) {
				returnVal = 0;
				goto fail;
			}
			for (p2 = productName; (*p1 != SPACE) && (*p1 != NUL); p1++, p2++)
				*p2 = *p1;
			*p2 = NUL;
		}
		else
		{
			p = memchr(p + 1, TEE, appBufferSize - (p - appBuffer));
		}
	}
	if (returnVal)
	{
		p = memchr(appBuffer, TEE, appBufferSize);

		while (p && !bspStringFound)
		{
			if (memcmp(p, BSP_SEARCH_STRING, strlen(BSP_SEARCH_STRING)) == 0)
			{
				bspStringFound = 1;
				p1 = strchr(p, COLON) + 1;
				if (p1 == NULL) {
					returnVal = 0;
					goto fail;
				}
				for (p2 = bspName; (*p1 != SPACE) && (*p1 != NUL); p1++, p2++)
					*p2 = *p1;
				*p2 = NUL;
			}
			else
			{
				p = memchr(p + 1, TEE, appBufferSize - (p - appBuffer));
			}
		}
		if (!bspStringFound)
			returnVal = 0;
		else
			printf("%s.%s\n", productName, bspName);
	}

fail:
	return(returnVal);
}