Exemple #1
0
static SquashStatus
squash_brotli_decompress_buffer (SquashCodec* codec,
                                 size_t* decompressed_size,
                                 uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)],
                                 size_t compressed_size,
                                 const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)],
                                 SquashOptions* options) {
  BrotliResult res;
  size_t total_out = 0;
  size_t available_in = compressed_size;
  const uint8_t* next_in = compressed;
  size_t available_out = *decompressed_size;
  uint8_t* next_out = decompressed;
  BrotliState* s = BrotliCreateState(squash_brotli_malloc, squash_brotli_free, squash_codec_get_context (codec));

  try {
    res = BrotliDecompressStream (&available_in, &next_in, &available_out,
        &next_out, &total_out, s);
  } catch (const std::bad_alloc& e) {
    (void) e;
    BrotliDestroyState(s);
    return squash_error (SQUASH_MEMORY);
  } catch (...) {
    BrotliDestroyState(s);
    return squash_error (SQUASH_FAILED);
  }

  BrotliDestroyState(s);
  *decompressed_size = total_out;
  return squash_brotli_status_to_squash_status (res);
}
Exemple #2
0
static SquashStatus
squash_brotli_decompress_stream (SquashStream* stream, SquashOperation operation) {
  SquashBrotliStream* s = (SquashBrotliStream*) stream;

  if (s->finished) {
    return SQUASH_OK;
  }

  try {
    size_t total_out;
    BrotliResult res = BrotliDecompressStream (&s->base_object.avail_in, &s->base_object.next_in,
                                               &s->base_object.avail_out, &s->base_object.next_out,
                                               &total_out, s->decompressor);
    if (res == BROTLI_RESULT_SUCCESS) {
      s->finished = true;
      return SQUASH_OK;
    }
    if (SQUASH_LIKELY(res ==  BROTLI_RESULT_NEEDS_MORE_OUTPUT || res == BROTLI_RESULT_NEEDS_MORE_INPUT)) {
      return (res == BROTLI_RESULT_NEEDS_MORE_OUTPUT) ? SQUASH_PROCESSING : SQUASH_OK;
    }
    return squash_error (SQUASH_FAILED);
  } catch (const std::bad_alloc& e) {
    (void) e;
    return squash_error (SQUASH_MEMORY);
  } catch (...) {
    return squash_error (SQUASH_FAILED);
  }
}
Exemple #3
0
static SquashStatus
squash_brotli_process_stream (SquashStream* stream, SquashOperation operation) {
  SquashBrotliStream* s = (SquashBrotliStream*) stream;

  if (stream->stream_type == SQUASH_STREAM_COMPRESS) {
    const int be_ret =
      BrotliEncoderCompressStream(s->ctx.encoder,
                                  squash_brotli_encoder_operation_from_squash_operation(operation),
                                  &(stream->avail_in), &(stream->next_in),
                                  &(stream->avail_out), &(stream->next_out),
                                  NULL);

    if (SQUASH_UNLIKELY(be_ret != 1))
      return squash_error (SQUASH_FAILED);
    else if (stream->avail_in != 0 || BrotliEncoderHasMoreOutput(s->ctx.encoder))
      return SQUASH_PROCESSING;
    else
      return SQUASH_OK;
  } else if (stream->stream_type == SQUASH_STREAM_DECOMPRESS) {
    const BrotliResult bd_ret =
      BrotliDecompressStream(&(stream->avail_in), &(stream->next_in),
                             &(stream->avail_out), &(stream->next_out),
                             NULL,
                             s->ctx.decoder);

    switch (bd_ret) {
      case BROTLI_RESULT_SUCCESS:
        return SQUASH_OK;
      case BROTLI_RESULT_NEEDS_MORE_INPUT:
        return SQUASH_OK;
      case BROTLI_RESULT_NEEDS_MORE_OUTPUT:
        return SQUASH_PROCESSING;
      case BROTLI_RESULT_ERROR:
        return SQUASH_FAILED;
    }

    if (SQUASH_UNLIKELY(bd_ret != BROTLI_RESULT_SUCCESS))
      return squash_error (SQUASH_FAILED);
  } else {
    squash_assert_unreachable ();
  }

  squash_assert_unreachable ();
}
Exemple #4
0
static int Decompress(FILE* fin, FILE* fout, const char* dictionary_path) {
  /* Dictionary should be kept during first rounds of decompression. */
  uint8_t* dictionary = NULL;
  uint8_t* input;
  uint8_t* output;
  size_t total_out;
  size_t available_in;
  const uint8_t* next_in;
  size_t available_out = kFileBufferSize;
  uint8_t* next_out;
  BrotliResult result = BROTLI_RESULT_ERROR;
  BrotliState* s = BrotliCreateState(NULL, NULL, NULL);
  if (!s) {
    fprintf(stderr, "out of memory\n");
    return 0;
  }
  if (dictionary_path != NULL) {
    size_t dictionary_size = 0;
    dictionary = ReadDictionary(dictionary_path, &dictionary_size);
    BrotliSetCustomDictionary(dictionary_size, dictionary, s);
  }
  input = (uint8_t*)malloc(kFileBufferSize);
  output = (uint8_t*)malloc(kFileBufferSize);
  if (!input || !output) {
    fprintf(stderr, "out of memory\n");
    goto end;
  }
  next_out = output;
  result = BROTLI_RESULT_NEEDS_MORE_INPUT;
  while (1) {
    if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
      if (feof(fin)) {
        break;
      }
      available_in = fread(input, 1, kFileBufferSize, fin);
      next_in = input;
      if (ferror(fin)) {
        break;
      }
    } else if (result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) {
      fwrite(output, 1, kFileBufferSize, fout);
      if (ferror(fout)) {
        break;
      }
      available_out = kFileBufferSize;
      next_out = output;
    } else {
      break; /* Error or success. */
    }
    result = BrotliDecompressStream(&available_in, &next_in,
        &available_out, &next_out, &total_out, s);
  }
  if (next_out != output) {
    fwrite(output, 1, (size_t)(next_out - output), fout);
  }

  if ((result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) || ferror(fout)) {
    fprintf(stderr, "failed to write output\n");
  } else if (result != BROTLI_RESULT_SUCCESS) { /* Error or needs more input. */
    fprintf(stderr, "corrupt input\n");
  }

end:
  free(dictionary);
  free(input);
  free(output);
  BrotliDestroyState(s);
  return (result == BROTLI_RESULT_SUCCESS) ? 1 : 0;
}
nsresult 
nsJARInputStream::ContinueInflate(char* aBuffer, uint32_t aCount,
                                  uint32_t* aBytesRead)
{
    bool finished = false;

    // No need to check the args, ::Read did that, but assert them at least
    NS_ASSERTION(aBuffer,"aBuffer parameter must not be null");
    NS_ASSERTION(aBytesRead,"aBytesRead parameter must not be null");

    // Keep old total_out count
    const uint32_t oldTotalOut = mZs.total_out;
    
    // make sure we aren't reading too much
    mZs.avail_out = std::min(aCount, (mOutSize-oldTotalOut));
    mZs.next_out = (unsigned char*)aBuffer;

#ifndef MOZ_JAR_BROTLI
    MOZ_ASSERT(mMode == MODE_INFLATE);
#endif
    if (mMode == MODE_INFLATE) {
        // now inflate
        int zerr = inflate(&mZs, Z_SYNC_FLUSH);
        if ((zerr != Z_OK) && (zerr != Z_STREAM_END)) {
            nsZipArchive::sFileCorruptedReason = "nsJARInputStream: error while inflating";
            return NS_ERROR_FILE_CORRUPTED;
        }
        finished = (zerr == Z_STREAM_END);
#ifdef MOZ_JAR_BROTLI
    } else {
        MOZ_ASSERT(mMode == MODE_BROTLI);
        /* The brotli library wants size_t, but z_stream only contains
         * unsigned int for avail_* and unsigned long for total_*.
         * So use temporary stack values. */
        size_t avail_in = mZs.avail_in;
        size_t avail_out = mZs.avail_out;
        size_t total_out = mZs.total_out;
        BrotliResult result = BrotliDecompressStream(
            &avail_in, const_cast<const unsigned char**>(&mZs.next_in),
            &avail_out, &mZs.next_out, &total_out, mBrotliState);
        /* We don't need to update avail_out, it's not used outside this
         * function. */
        mZs.total_out = total_out;
        mZs.avail_in = avail_in;
        if (result == BROTLI_RESULT_ERROR) {
            nsZipArchive::sFileCorruptedReason = "nsJARInputStream: brotli decompression error";
            return NS_ERROR_FILE_CORRUPTED;
        }
        finished = (result == BROTLI_RESULT_SUCCESS);
#endif
    }

    *aBytesRead = (mZs.total_out - oldTotalOut);

    // Calculate the CRC on the output
    mOutCrc = crc32(mOutCrc, (unsigned char*)aBuffer, *aBytesRead);

    // be aggressive about ending the inflation
    // for some reason we don't always get Z_STREAM_END
    if (finished || mZs.total_out == mOutSize) {
        if (mMode == MODE_INFLATE) {
            inflateEnd(&mZs);
        }

        // stop returning valid data as soon as we know we have a bad CRC
        if (mOutCrc != mInCrc) {
            nsZipArchive::sFileCorruptedReason = "nsJARInputStream: crc mismatch";
            return NS_ERROR_FILE_CORRUPTED;
        }
    }

    return NS_OK;
}
Exemple #6
0
/**
  Decompresses a Brotli compressed source buffer.

  Extracts decompressed data to its original form.
  If the compressed source data specified by Source is successfully decompressed
  into Destination, then EFI_SUCCESS is returned. If the compressed source data
  specified by Source is not in a valid compressed data format,
  then EFI_INVALID_PARAMETER is returned.

  @param  Source      The source buffer containing the compressed data.
  @param  SourceSize  The size of source buffer.
  @param  Destination The destination buffer to store the decompressed data.
  @param  DestSize    The destination buffer size.
  @param  BuffInfo    The pointer to the BROTLI_BUFF instance.

  @retval EFI_SUCCESS Decompression completed successfully, and
                      the uncompressed buffer is returned in Destination.
  @retval EFI_INVALID_PARAMETER
                      The source buffer specified by Source is corrupted
                      (not in a valid compressed format).
**/
EFI_STATUS
BrotliDecompress (
  IN CONST VOID*  Source,
  IN UINTN        SourceSize,
  IN OUT VOID*    Destination,
  IN OUT UINTN    DestSize,
  IN VOID *       BuffInfo
  )
{
  UINT8 *        Input;
  UINT8 *        Output;
  const UINT8 *  NextIn;
  UINT8 *        NextOut;
  size_t         TotalOut;
  size_t         AvailableIn;
  size_t         AvailableOut;
  BrotliResult   Result;
  BrotliState *  BroState;
  VOID *         Temp;

  TotalOut = 0;
  AvailableOut = FILE_BUFFER_SIZE;
  Result = BROTLI_RESULT_ERROR;
  BroState = BrotliCreateState(BrAlloc, BrFree, BuffInfo);
  Temp = Destination;

  if (BroState == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  Input = (UINT8 *)BrAlloc(BuffInfo, FILE_BUFFER_SIZE);
  Output = (UINT8 *)BrAlloc(BuffInfo, FILE_BUFFER_SIZE);
  if ((Input==NULL) || (Output==NULL)) {
    BrFree(BuffInfo, Input);
    BrFree(BuffInfo, Output);
    BrotliDestroyState(BroState);
    return EFI_INVALID_PARAMETER;
  }
  NextOut = Output;
  Result = BROTLI_RESULT_NEEDS_MORE_INPUT;
  while (1) {
    if (Result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
      if (SourceSize == 0) {
        break;
      }
      if (SourceSize >= FILE_BUFFER_SIZE) {
        AvailableIn = FILE_BUFFER_SIZE;
      }else{
        AvailableIn = SourceSize;
      }
      CopyMem(Input, Source, AvailableIn);
      Source = (VOID *)((UINT8 *)Source + AvailableIn);
      SourceSize -= AvailableIn;
      NextIn = Input;
    } else if (Result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) {
      CopyMem(Temp, Output, FILE_BUFFER_SIZE);
      AvailableOut = FILE_BUFFER_SIZE;
      Temp = (VOID *)((UINT8 *)Temp +FILE_BUFFER_SIZE);
      NextOut = Output;
    } else {
      break; /* Error or success. */
    }
    Result = BrotliDecompressStream(
                          &AvailableIn,
                          &NextIn,
                          &AvailableOut,
                          &NextOut,
                          &TotalOut,
                          BroState
                          );
  }
  if (NextOut != Output) {
    CopyMem(Temp, Output, (size_t)(NextOut - Output));
  }

  DestSize = TotalOut;

  BrFree(BuffInfo, Input);
  BrFree(BuffInfo, Output);
  BrotliDestroyState(BroState);
  return (Result == BROTLI_RESULT_SUCCESS) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
}