aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/compression
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-11-17 16:23:51 -0500
committerJack Lloyd <[email protected]>2018-11-23 11:15:25 -0500
commitb909778857b3e0b7eb86ac26c818e5f25baaddbd (patch)
treef8a5c9cbec26310bbfc9077563892b04db158a48 /src/lib/compression
parentc20a428ca2f7c1ef96e642f55bb898010444c499 (diff)
Make exceptions easier to translate to error codes
Avoid throwing base Botan::Exception type, as it is difficult to determine what the error is in that case. Add Exception::error_code and Exception::error_type which allows (for error code) more information about the error and (for error type) allows knowing the error type without requiring a sequence of catches. See GH #1742
Diffstat (limited to 'src/lib/compression')
-rw-r--r--src/lib/compression/bzip2/bzip2.cpp24
-rw-r--r--src/lib/compression/compress_utils.cpp4
-rw-r--r--src/lib/compression/compression.h32
-rw-r--r--src/lib/compression/lzma/lzma.cpp18
-rw-r--r--src/lib/compression/zlib/zlib.cpp22
5 files changed, 55 insertions, 45 deletions
diff --git a/src/lib/compression/bzip2/bzip2.cpp b/src/lib/compression/bzip2/bzip2.cpp
index 02d17ea07..c9dfc2ce8 100644
--- a/src/lib/compression/bzip2/bzip2.cpp
+++ b/src/lib/compression/bzip2/bzip2.cpp
@@ -48,10 +48,8 @@ class Bzip2_Compression_Stream final : public Bzip2_Stream
int rc = BZ2_bzCompressInit(streamp(), block_size, 0, 0);
- if(rc == BZ_MEM_ERROR)
- throw Exception("bzip memory allocation failure");
- else if(rc != BZ_OK)
- throw Exception("bzip compress initialization failed");
+ if(rc != BZ_OK)
+ throw Compression_Error("BZ2_bzCompressInit", ErrorType::Bzip2Error, rc);
}
~Bzip2_Compression_Stream()
@@ -63,10 +61,8 @@ class Bzip2_Compression_Stream final : public Bzip2_Stream
{
int rc = BZ2_bzCompress(streamp(), flags);
- if(rc == BZ_MEM_ERROR)
- throw Exception("bzip memory allocation failure");
- else if(rc < 0)
- throw Exception("bzip compress error " + std::to_string(-rc));
+ if(rc < 0)
+ throw Compression_Error("BZ2_bzCompress", ErrorType::Bzip2Error, rc);
return (rc == BZ_STREAM_END);
}
@@ -79,10 +75,8 @@ class Bzip2_Decompression_Stream final : public Bzip2_Stream
{
int rc = BZ2_bzDecompressInit(streamp(), 0, 0);
- if(rc == BZ_MEM_ERROR)
- throw Exception("bzip memory allocation failure");
- else if(rc != BZ_OK)
- throw Exception("bzip decompress initialization failed");
+ if(rc != BZ_OK)
+ throw Compression_Error("BZ2_bzDecompressInit", ErrorType::Bzip2Error, rc);
}
~Bzip2_Decompression_Stream()
@@ -94,10 +88,8 @@ class Bzip2_Decompression_Stream final : public Bzip2_Stream
{
int rc = BZ2_bzDecompress(streamp());
- if(rc == BZ_MEM_ERROR)
- throw Exception("bzip memory allocation failure");
- else if(rc != BZ_OK && rc != BZ_STREAM_END)
- throw Exception("bzip decompress error " + std::to_string(-rc));
+ if(rc != BZ_OK && rc != BZ_STREAM_END)
+ throw Compression_Error("BZ2_bzDecompress", ErrorType::Bzip2Error, rc);
return (rc == BZ_STREAM_END);
}
diff --git a/src/lib/compression/compress_utils.cpp b/src/lib/compression/compress_utils.cpp
index 6bdf3d0fd..f49a0ede1 100644
--- a/src/lib/compression/compress_utils.cpp
+++ b/src/lib/compression/compress_utils.cpp
@@ -39,7 +39,7 @@ void Compression_Alloc_Info::do_free(void* ptr)
auto i = m_current_allocs.find(ptr);
if(i == m_current_allocs.end())
- throw Exception("Compression_Alloc_Info::free got pointer not allocated by us");
+ throw Internal_Error("Compression_Alloc_Info::free got pointer not allocated by us");
secure_scrub_memory(ptr, i->second);
std::free(ptr);
@@ -190,7 +190,7 @@ void Stream_Decompression::finish(secure_vector<uint8_t>& buf, size_t offset)
process(buf, offset, m_stream->finish_flag());
if(m_stream.get())
- throw Exception(name() + " finished but not at stream end");
+ throw Invalid_State(name() + " finished but not at stream end");
}
}
diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h
index f331874cf..1365894e2 100644
--- a/src/lib/compression/compression.h
+++ b/src/lib/compression/compression.h
@@ -9,11 +9,12 @@
#define BOTAN_COMPRESSION_TRANSFORM_H_
#include <botan/secmem.h>
+#include <botan/exceptn.h>
#include <string>
namespace Botan {
-/*
+/**
* Interface for a compression algorithm.
*/
class BOTAN_PUBLIC_API(2,0) Compression_Algorithm
@@ -134,6 +135,35 @@ BOTAN_PUBLIC_API(2,0) Compression_Algorithm* make_compressor(const std::string&
BOTAN_PUBLIC_API(2,0) Decompression_Algorithm* make_decompressor(const std::string& type);
/**
+* An error that occurred during compression (or decompression)
+*/
+class BOTAN_PUBLIC_API(2,9) Compression_Error : public Exception
+ {
+ public:
+
+ /**
+ * @param func_name the name of the compression API that was called
+ * (eg "BZ2_bzCompressInit" or "lzma_code")
+ * @param rc the error return code from the compression API. The
+ * interpretation of this value will depend on the library.
+ */
+ Compression_Error(const char* func_name, ErrorType type, int rc) :
+ Exception("Compression API " + std::string(func_name) +
+ " failed with return code " + std::to_string(rc)),
+ m_type(type),
+ m_rc(rc)
+ {}
+
+ ErrorType error_type() const noexcept override { return m_type; }
+
+ int error_code() const noexcept override { return m_rc; }
+
+ private:
+ ErrorType m_type;
+ int m_rc;
+ };
+
+/**
* Adapts a zlib style API
*/
class Compression_Stream
diff --git a/src/lib/compression/lzma/lzma.cpp b/src/lib/compression/lzma/lzma.cpp
index 92c61840a..73bb9eb89 100644
--- a/src/lib/compression/lzma/lzma.cpp
+++ b/src/lib/compression/lzma/lzma.cpp
@@ -37,10 +37,8 @@ class LZMA_Stream : public Zlib_Style_Stream<lzma_stream, uint8_t>
{
lzma_ret rc = ::lzma_code(streamp(), static_cast<lzma_action>(flags));
- if(rc == LZMA_MEM_ERROR)
- throw Exception("lzma memory allocation failed");
- else if (rc != LZMA_OK && rc != LZMA_STREAM_END)
- throw Exception("Lzma error");
+ if(rc != LZMA_OK && rc != LZMA_STREAM_END)
+ throw Compression_Error("lzma_code", ErrorType::LzmaError, rc);
return (rc == LZMA_STREAM_END);
}
@@ -64,10 +62,8 @@ class LZMA_Compression_Stream final : public LZMA_Stream
lzma_ret rc = ::lzma_easy_encoder(streamp(), level, LZMA_CHECK_CRC64);
- if(rc == LZMA_MEM_ERROR)
- throw Exception("lzma memory allocation failed");
- else if(rc != LZMA_OK)
- throw Exception("lzma compress initialization failed");
+ if(rc != LZMA_OK)
+ throw Compression_Error("lzam_easy_encoder", ErrorType::LzmaError, rc);
}
};
@@ -79,10 +75,8 @@ class LZMA_Decompression_Stream final : public LZMA_Stream
lzma_ret rc = ::lzma_stream_decoder(streamp(), UINT64_MAX,
LZMA_TELL_UNSUPPORTED_CHECK);
- if(rc == LZMA_MEM_ERROR)
- throw Exception("lzma memory allocation failed");
- else if(rc != LZMA_OK)
- throw Exception("Bad setting in lzma_stream_decoder");
+ if(rc != LZMA_OK)
+ throw Compression_Error("lzma_stream_decoder", ErrorType::LzmaError, rc);
}
};
diff --git a/src/lib/compression/zlib/zlib.cpp b/src/lib/compression/zlib/zlib.cpp
index 57494e225..285bc4e91 100644
--- a/src/lib/compression/zlib/zlib.cpp
+++ b/src/lib/compression/zlib/zlib.cpp
@@ -54,7 +54,7 @@ class Zlib_Compression_Stream : public Zlib_Stream
int rc = ::deflateInit2(streamp(), level, Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY);
if(rc != Z_OK)
- throw Exception("zlib deflate initialization failed");
+ throw Compression_Error("deflateInit2", ErrorType::ZlibError, rc);
}
~Zlib_Compression_Stream()
@@ -66,10 +66,8 @@ class Zlib_Compression_Stream : public Zlib_Stream
{
int rc = ::deflate(streamp(), flags);
- if(rc == Z_MEM_ERROR)
- throw Exception("zlib memory allocation failure");
- else if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
- throw Exception("zlib deflate error " + std::to_string(rc));
+ if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
+ throw Compression_Error("zlib deflate", ErrorType::ZlibError, rc);
return (rc == Z_STREAM_END);
}
@@ -82,10 +80,8 @@ class Zlib_Decompression_Stream : public Zlib_Stream
{
int rc = ::inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset));
- if(rc == Z_MEM_ERROR)
- throw Exception("zlib memory allocation failure");
- else if(rc != Z_OK)
- throw Exception("zlib inflate initialization failed");
+ if(rc != Z_OK)
+ throw Compression_Error("inflateInit2", ErrorType::ZlibError, rc);
}
~Zlib_Decompression_Stream()
@@ -97,10 +93,8 @@ class Zlib_Decompression_Stream : public Zlib_Stream
{
int rc = ::inflate(streamp(), flags);
- if(rc == Z_MEM_ERROR)
- throw Exception("zlib memory allocation failure");
- else if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
- throw Exception("zlib inflate error " + std::to_string(rc));
+ if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
+ throw Compression_Error("zlib inflate", ErrorType::ZlibError, rc);
return (rc == Z_STREAM_END);
}
@@ -131,7 +125,7 @@ class Gzip_Compression_Stream final : public Zlib_Compression_Stream
int rc = deflateSetHeader(streamp(), &m_header);
if(rc != Z_OK)
- throw Exception("setting gzip header failed");
+ throw Compression_Error("deflateSetHeader", ErrorType::ZlibError, rc);
}
private: