From f201b023573625e9f8afd4cf47d5f96fb14b0ea9 Mon Sep 17 00:00:00 2001 From: Tomas Mlcoch Date: Wed, 29 May 2013 13:42:54 +0200 Subject: [PATCH] compression_wrapper: Better error messages for XZ errors and more tests. --- src/compression_wrapper.c | 53 ++++++++++++++++++++++++++++++-- tests/test_compression_wrapper.c | 65 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/compression_wrapper.c b/src/compression_wrapper.c index d5f0d57..55bba9d 100644 --- a/src/compression_wrapper.c +++ b/src/compression_wrapper.c @@ -708,10 +708,59 @@ cr_read(CR_FILE *cr_file, void *buffer, unsigned int len, GError **err) // Decode lret = lzma_code(stream, LZMA_RUN); + if (lret != LZMA_OK && lret != LZMA_STREAM_END) { - g_debug("%s: XZ: Error while decoding (%d)", __func__, lret); + const char *err_msg; + + switch (lret) { + case LZMA_MEM_ERROR: + err_msg = "Memory allocation failed"; + break; + case LZMA_FORMAT_ERROR: + // .xz magic bytes weren't found. + err_msg = "The input is not in the .xz format"; + break; + case LZMA_OPTIONS_ERROR: + // For example, the headers specify a filter + // that isn't supported by this liblzma + // version (or it hasn't been enabled when + // building liblzma, but no-one sane does + // that unless building liblzma for an + // embedded system). Upgrading to a newer + // liblzma might help. + // + // Note that it is unlikely that the file has + // accidentally became corrupt if you get this + // error. The integrity of the .xz headers is + // always verified with a CRC32, so + // unintentionally corrupt files can be + // distinguished from unsupported files. + err_msg = "Unsupported compression options"; + break; + case LZMA_DATA_ERROR: + err_msg = "Compressed file is corrupt"; + break; + case LZMA_BUF_ERROR: + // Typically this error means that a valid + // file has got truncated, but it might also + // be a damaged part in the file that makes + // the decoder think the file is truncated. + // If you prefer, you can use the same error + // message for this as for LZMA_DATA_ERROR. + err_msg = "Compressed file is truncated or " + "otherwise corrupt"; + break; + default: + // This is most likely LZMA_PROG_ERROR. + err_msg = "Unknown error, possibly a bug"; + break; + } + + g_debug("%s: XZ: Error while decoding (%d): %s", + __func__, lret, err_msg); g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_XZ, - "XZ: Error while deconding(%d)", lret); + "XZ: Error while decoding (%d): %s", + lret, err_msg); return CR_CW_ERR; // Error while decoding } diff --git a/tests/test_compression_wrapper.c b/tests/test_compression_wrapper.c index 6e490cf..193b036 100644 --- a/tests/test_compression_wrapper.c +++ b/tests/test_compression_wrapper.c @@ -438,6 +438,8 @@ test_cr_error_handling(void) g_error_free(tmp_err); tmp_err = NULL; + // Opening dir for writing + f = cr_open("/", CR_CW_MODE_WRITE, CR_CW_NO_COMPRESSION, &tmp_err); g_assert(!f); g_assert(tmp_err); @@ -445,6 +447,69 @@ test_cr_error_handling(void) g_error_free(tmp_err); tmp_err = NULL; + f = cr_open("/", CR_CW_MODE_WRITE, CR_CW_GZ_COMPRESSION, &tmp_err); + g_assert(!f); + g_assert(tmp_err); + g_assert_cmpint(tmp_err->code, ==, CRE_GZ); + g_error_free(tmp_err); + tmp_err = NULL; + + f = cr_open("/", CR_CW_MODE_WRITE, CR_CW_BZ2_COMPRESSION, &tmp_err); + g_assert(!f); + g_assert(tmp_err); + g_assert_cmpint(tmp_err->code, ==, CRE_IO); + g_error_free(tmp_err); + tmp_err = NULL; + + f = cr_open("/", CR_CW_MODE_WRITE, CR_CW_XZ_COMPRESSION, &tmp_err); + g_assert(!f); + g_assert(tmp_err); + g_assert_cmpint(tmp_err->code, ==, CRE_XZ); + g_error_free(tmp_err); + tmp_err = NULL; + + // Opening plain text file as compressed + + char buf[256]; + int ret; + + // gzread can read compressed as well as uncompressed, so this test + // is useful. + f = cr_open(FILE_COMPRESSED_1_PLAIN, CR_CW_MODE_READ, + CR_CW_GZ_COMPRESSION, &tmp_err); + g_assert(f); + ret = cr_read(f, buf, 256, &tmp_err); + g_assert_cmpint(ret, ==, FILE_COMPRESSED_1_CONTENT_LEN); + g_assert(!tmp_err); + ret = cr_close(f, &tmp_err); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert(!tmp_err); + + f = cr_open(FILE_COMPRESSED_1_PLAIN, CR_CW_MODE_READ, + CR_CW_BZ2_COMPRESSION, &tmp_err); + g_assert(f); + ret = cr_read(f, buf, 256, &tmp_err); + g_assert_cmpint(ret, ==, -1); + g_assert(tmp_err); + g_assert_cmpint(tmp_err->code, ==, CRE_BZ2); + g_error_free(tmp_err); + tmp_err = NULL; + ret = cr_close(f, &tmp_err); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert(!tmp_err); + + f = cr_open(FILE_COMPRESSED_1_PLAIN, CR_CW_MODE_READ, + CR_CW_XZ_COMPRESSION, &tmp_err); + g_assert(f); + ret = cr_read(f, buf, 256, &tmp_err); + g_assert_cmpint(ret, ==, -1); + g_assert(tmp_err); + g_assert_cmpint(tmp_err->code, ==, CRE_XZ); + g_error_free(tmp_err); + tmp_err = NULL; + ret = cr_close(f, &tmp_err); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert(!tmp_err); } -- 2.7.4