From 7e90bd36c92285a16a1fca0a6638d6d9184a29b1 Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Wed, 25 Nov 2020 12:07:26 +0100 Subject: [PATCH] Changes for EWF write --- .gitignore | 1 + libewf/libewf_checksum.c | 7 +- libewf/libewf_checksum.h | 4 +- libewf/libewf_chunk_data.c | 7 - libewf/libewf_empty_block.c | 96 +++++--- libewf/libewf_empty_block.h | 2 +- libewf/libewf_handle.c | 7 - libewf/libewf_hash_sections.c | 7 +- msvscpp/Makefile.am | 1 + .../ewf_test_empty_block.vcproj | 214 +++++++++++++++++ msvscpp/libewf.sln | 10 + tests/Makefile.am | 12 + tests/ewf_test_empty_block.c | 220 ++++++++++++++++++ tests/test_library.ps1 | 2 +- tests/test_library.sh | 2 +- 15 files changed, 542 insertions(+), 50 deletions(-) create mode 100644 msvscpp/ewf_test_empty_block/ewf_test_empty_block.vcproj create mode 100644 tests/ewf_test_empty_block.c diff --git a/.gitignore b/.gitignore index c84550e..c1c1869 100644 --- a/.gitignore +++ b/.gitignore @@ -142,6 +142,7 @@ stamp-h[1-9] /tests/ewf_test_date_time /tests/ewf_test_date_time_values /tests/ewf_test_deflate +/tests/ewf_test_empty_block /tests/ewf_test_error /tests/ewf_test_file_entry /tests/ewf_test_filename diff --git a/libewf/libewf_checksum.c b/libewf/libewf_checksum.c index b237bac..e859815 100644 --- a/libewf/libewf_checksum.c +++ b/libewf/libewf_checksum.c @@ -31,7 +31,7 @@ #include "libewf_libcerror.h" #include "libewf_types.h" -#if defined( HAVE_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) +#if defined( HAVE_ZLIB_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) /* Calculates the little-endian Adler-32 of a buffer * It uses the initial value to calculate a new Adler-32 @@ -68,7 +68,8 @@ int libewf_checksum_calculate_adler32( return( -1 ); } - if( size > (size_t) UINT_MAX ) + if( ( size > (size_t) UINT_MAX ) + || ( size > (size_t) SSIZE_MAX ) ) { libcerror_error_set( error, @@ -87,5 +88,5 @@ int libewf_checksum_calculate_adler32( return( 1 ); } -#endif /* defined( HAVE_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) */ +#endif /* defined( HAVE_ZLIB_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) */ diff --git a/libewf/libewf_checksum.h b/libewf/libewf_checksum.h index 5a82973..fe76d0f 100644 --- a/libewf/libewf_checksum.h +++ b/libewf/libewf_checksum.h @@ -32,7 +32,7 @@ extern "C" { #endif -#if defined( HAVE_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) +#if defined( HAVE_ZLIB_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) int libewf_checksum_calculate_adler32( uint32_t *checksum_value, @@ -45,7 +45,7 @@ int libewf_checksum_calculate_adler32( #define libewf_checksum_calculate_adler32( checksum_value, buffer, size, initial_value, error ) \ libewf_deflate_calculate_adler32( checksum_value, buffer, size, initial_value, error ) -#endif /* defined( HAVE_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) */ +#endif /* defined( HAVE_ZLIB_ADLER32 ) && ( defined( HAVE_ZLIB ) || defined( ZLIB_DLL ) ) */ #if defined( __cplusplus ) } diff --git a/libewf/libewf_chunk_data.c b/libewf/libewf_chunk_data.c index 2c9180d..a0fade2 100644 --- a/libewf/libewf_chunk_data.c +++ b/libewf/libewf_chunk_data.c @@ -230,12 +230,6 @@ int libewf_chunk_data_pack( if( ( compression_level != EWF_COMPRESSION_NONE ) || ( ( compression_flags & LIBEWF_FLAG_COMPRESS_EMPTY_BLOCK ) != 0 ) ) { -#if defined( TEST_EMPTY_BLOCK_MEMCMP ) - if( memory_compare( - chunk_data->data, - &( chunk_data->data[ 1 ] ) - chunk_data->data_size - 1 ) == 0 ) -#else result = libewf_empty_block_test( chunk_data->data, chunk_data->data_size, @@ -253,7 +247,6 @@ int libewf_chunk_data_pack( return( -1 ); } else if( result == 1 ) -#endif { if( ( chunk_data->data )[ 0 ] == 0 ) { diff --git a/libewf/libewf_empty_block.c b/libewf/libewf_empty_block.c index 6caf657..0c83644 100644 --- a/libewf/libewf_empty_block.c +++ b/libewf/libewf_empty_block.c @@ -20,11 +20,65 @@ */ #include +#include #include +#include "libewf_empty_block.h" #include "libewf_libcerror.h" -#include "libewf_empty_block.h" +/* Check for empty block + * An empty block is a block that contains the same value for every byte + * Returns 1 if block is empty, 0 if not or -1 on error + */ +int libewf_empty_block_test( + const uint8_t *block_buffer, + size_t block_size, + libcerror_error_t **error ) +{ + static char *function = "libewf_empty_block_test"; + + if( block_buffer == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid block buffer.", + function ); + + return( -1 ); + } + if( block_size > (size_t) SSIZE_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid block size value exceeds maximum.", + function ); + + return( -1 ); + } + if( block_size == 0 ) + { + return( 0 ); + } + else if( block_size == 1 ) + { + return( 1 ); + } + if( memory_compare( + block_buffer, + &( block_buffer[ 1 ] ), + block_size - 1 ) != 0 ) + { + return( 0 ); + } + return( 1 ); +} + +/* Previous version keep for now */ +#ifdef TEST_EMPTY_BLOCK_MEMCMP /* The largest primary (or scalar) available * supported by a single load and store instruction @@ -40,11 +94,10 @@ int libewf_empty_block_test( size_t block_size, libcerror_error_t **error ) { - libewf_aligned_t *aligned_block_iterator = NULL; - libewf_aligned_t *aligned_block_start = NULL; - uint8_t *block_iterator = NULL; - uint8_t *block_start = NULL; - static char *function = "libewf_empty_block_test"; + uint8_t *block_iterator = NULL; + uint8_t *block_start = NULL; + static char *function = "libewf_empty_block_test"; + size_t aligned_block_size = 0; if( block_buffer == NULL ) { @@ -88,30 +141,17 @@ int libewf_empty_block_test( block_iterator += 1; block_size -= 1; } - /* Align the block iterator - */ - while( ( (intptr_t) block_iterator % sizeof( libewf_aligned_t ) ) != 0 ) - { - if( *block_start != *block_iterator ) - { - return( 0 ); - } - block_iterator += 1; - block_size -= 1; - } - aligned_block_start = (libewf_aligned_t *) block_start; - aligned_block_iterator = (libewf_aligned_t *) block_iterator; + aligned_block_size = ( block_size / sizeof( libewf_aligned_t ) ) * sizeof( libewf_aligned_t ); - while( block_size > sizeof( libewf_aligned_t ) ) + if( memory_compare( + block_start, + &( block_start[ sizeof( libewf_aligned_t ) ] ), + aligned_block_size - sizeof( libewf_aligned_t ) ) != 0 ) { - if( *aligned_block_start != *aligned_block_iterator ) - { - return( 0 ); - } - aligned_block_iterator += 1; - block_size -= sizeof( libewf_aligned_t ); + return( 0 ); } - block_iterator = (uint8_t *) aligned_block_iterator; + block_iterator = &( block_start[ aligned_block_size ] ); + block_size -= aligned_block_size; } while( block_size != 0 ) { @@ -125,3 +165,5 @@ int libewf_empty_block_test( return( 1 ); } +#endif /* TEST_EMPTY_BLOCK_MEMCMP */ + diff --git a/libewf/libewf_empty_block.h b/libewf/libewf_empty_block.h index f51e317..5e79704 100644 --- a/libewf/libewf_empty_block.h +++ b/libewf/libewf_empty_block.h @@ -40,5 +40,5 @@ int libewf_empty_block_test( } #endif -#endif +#endif /* !defined( _LIBEWF_EMPTY_BLOCK_H ) */ diff --git a/libewf/libewf_handle.c b/libewf/libewf_handle.c index c0407a1..76edf13 100644 --- a/libewf/libewf_handle.c +++ b/libewf/libewf_handle.c @@ -5264,12 +5264,6 @@ ssize_t libewf_handle_prepare_write_chunk( if( ( compression_level != EWF_COMPRESSION_NONE ) || ( ( internal_handle->io_handle->compression_flags & LIBEWF_FLAG_COMPRESS_EMPTY_BLOCK ) != 0 ) ) { -#if defined( TEST_EMPTY_BLOCK_MEMCMP ) - if( memory_compare( - chunk_buffer, - &( ( (uint8_t *) chunk_buffer )[ 1 ] ), - chunk_buffer_size - 1 ) == 0 ) -#else result = libewf_empty_block_test( chunk_buffer, chunk_buffer_size, @@ -5287,7 +5281,6 @@ ssize_t libewf_handle_prepare_write_chunk( return( -1 ); } else if( result == 1 ) -#endif { if( ( (uint8_t *) chunk_buffer )[ 0 ] == 0 ) { diff --git a/libewf/libewf_hash_sections.c b/libewf/libewf_hash_sections.c index baf17a1..03dc771 100644 --- a/libewf/libewf_hash_sections.c +++ b/libewf/libewf_hash_sections.c @@ -195,7 +195,12 @@ int libewf_hash_sections_clone( "%s: unable to copy source to destination hash sections.", function ); - goto on_error; + memory_free( + *destination_hash_sections ); + + *destination_hash_sections = NULL; + + return( -1 ); } ( *destination_hash_sections )->xhash = NULL; ( *destination_hash_sections )->xhash_size = 0; diff --git a/msvscpp/Makefile.am b/msvscpp/Makefile.am index 6ddbc66..17d30a2 100644 --- a/msvscpp/Makefile.am +++ b/msvscpp/Makefile.am @@ -7,6 +7,7 @@ MSVSCPP_FILES = \ ewf_test_date_time/ewf_test_date_time.vcproj \ ewf_test_date_time_values/ewf_test_date_time_values.vcproj \ ewf_test_deflate/ewf_test_deflate.vcproj \ + ewf_test_empty_block/ewf_test_empty_block.vcproj \ ewf_test_error/ewf_test_error.vcproj \ ewf_test_file_entry/ewf_test_file_entry.vcproj \ ewf_test_filename/ewf_test_filename.vcproj \ diff --git a/msvscpp/ewf_test_empty_block/ewf_test_empty_block.vcproj b/msvscpp/ewf_test_empty_block/ewf_test_empty_block.vcproj new file mode 100644 index 0000000..7c3dac5 --- /dev/null +++ b/msvscpp/ewf_test_empty_block/ewf_test_empty_block.vcproj @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvscpp/libewf.sln b/msvscpp/libewf.sln index d2c19e4..7c9b2a7 100644 --- a/msvscpp/libewf.sln +++ b/msvscpp/libewf.sln @@ -100,6 +100,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ewf_test_deflate", "ewf_tes {EBDF4B5C-2DB4-41F8-8A4A-B9A4FFB5CC92} = {EBDF4B5C-2DB4-41F8-8A4A-B9A4FFB5CC92} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ewf_test_empty_block", "ewf_test_empty_block\ewf_test_empty_block.vcproj", "{0AAB2AB4-3720-429C-BC09-474C0667AA6F}" + ProjectSection(ProjectDependencies) = postProject + {610F33E3-5FBB-4749-9C3F-6D4BC90BEA70} = {610F33E3-5FBB-4749-9C3F-6D4BC90BEA70} + {EBDF4B5C-2DB4-41F8-8A4A-B9A4FFB5CC92} = {EBDF4B5C-2DB4-41F8-8A4A-B9A4FFB5CC92} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ewf_test_error", "ewf_test_error\ewf_test_error.vcproj", "{23895087-0ED8-48B9-8FD9-8841057B435A}" ProjectSection(ProjectDependencies) = postProject {610F33E3-5FBB-4749-9C3F-6D4BC90BEA70} = {610F33E3-5FBB-4749-9C3F-6D4BC90BEA70} @@ -581,6 +587,10 @@ Global {70CC5794-EB91-468A-B608-0940B72E4582}.Release|Win32.Build.0 = Release|Win32 {70CC5794-EB91-468A-B608-0940B72E4582}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 {70CC5794-EB91-468A-B608-0940B72E4582}.VSDebug|Win32.Build.0 = VSDebug|Win32 + {0AAB2AB4-3720-429C-BC09-474C0667AA6F}.Release|Win32.ActiveCfg = Release|Win32 + {0AAB2AB4-3720-429C-BC09-474C0667AA6F}.Release|Win32.Build.0 = Release|Win32 + {0AAB2AB4-3720-429C-BC09-474C0667AA6F}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 + {0AAB2AB4-3720-429C-BC09-474C0667AA6F}.VSDebug|Win32.Build.0 = VSDebug|Win32 {23895087-0ED8-48B9-8FD9-8841057B435A}.Release|Win32.ActiveCfg = Release|Win32 {23895087-0ED8-48B9-8FD9-8841057B435A}.Release|Win32.Build.0 = Release|Win32 {23895087-0ED8-48B9-8FD9-8841057B435A}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 diff --git a/tests/Makefile.am b/tests/Makefile.am index 1e9a643..139b00a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -77,6 +77,7 @@ check_PROGRAMS = \ ewf_test_date_time \ ewf_test_date_time_values \ ewf_test_deflate \ + ewf_test_empty_block \ ewf_test_error \ ewf_test_file_entry \ ewf_test_filename \ @@ -185,6 +186,17 @@ ewf_test_deflate_LDADD = \ ../libewf/libewf.la \ @LIBCERROR_LIBADD@ +ewf_test_empty_block_SOURCES = \ + ewf_test_empty_block.c \ + ewf_test_libcerror.h \ + ewf_test_libewf.h \ + ewf_test_macros.h \ + ewf_test_unused.h + +ewf_test_empty_block_LDADD = \ + ../libewf/libewf.la \ + @LIBCERROR_LIBADD@ + ewf_test_error_SOURCES = \ ewf_test_error.c \ ewf_test_libewf.h \ diff --git a/tests/ewf_test_empty_block.c b/tests/ewf_test_empty_block.c new file mode 100644 index 0000000..93203ed --- /dev/null +++ b/tests/ewf_test_empty_block.c @@ -0,0 +1,220 @@ +/* + * Library empty_block type test program + * + * Copyright (C) 2006-2020, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#if defined( HAVE_STDLIB_H ) || defined( WINAPI ) +#include +#endif + +#include "ewf_test_libcerror.h" +#include "ewf_test_libewf.h" +#include "ewf_test_macros.h" +#include "ewf_test_unused.h" + +#include "../libewf/libewf_empty_block.h" + +#if defined( __GNUC__ ) && !defined( LIBEWF_DLL_IMPORT ) + +/* Tests the libewf_empty_block_test function + * Returns 1 if successful or 0 if not + */ +int ewf_test_empty_block_test( + void ) +{ + uint8_t buffer[ 512 ]; + + libcerror_error_t *error = NULL; + void *memset_result = NULL; + int result = 0; + + /* Initialize test + */ + memset_result = memory_set( + buffer, + 0, + 512 ); + + EWF_TEST_ASSERT_IS_NOT_NULL( + "memset_result", + memset_result ); + + /* Test regular cases + */ + result = libewf_empty_block_test( + buffer, + 512, + &error ); + + EWF_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + EWF_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libewf_empty_block_test( + &( buffer[ 1 ] ), + 512 - 1, + &error ); + + EWF_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + EWF_TEST_ASSERT_IS_NULL( + "error", + error ); + + buffer[ 500 ] = (uint8_t) 'A'; + + result = libewf_empty_block_test( + buffer, + 512, + &error ); + + buffer[ 500 ] = 0; + + EWF_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + EWF_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libewf_empty_block_test( + buffer, + 0, + &error ); + + EWF_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + EWF_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libewf_empty_block_test( + buffer, + 1, + &error ); + + EWF_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + EWF_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ + result = libewf_empty_block_test( + NULL, + 512, + &error ); + + EWF_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + EWF_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libewf_empty_block_test( + buffer, + (size_t) SSIZE_MAX + 1, + &error ); + + EWF_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + EWF_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + return( 0 ); +} + +#endif /* defined( __GNUC__ ) && !defined( LIBEWF_DLL_IMPORT ) */ + +/* The main program + */ +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) +int wmain( + int argc EWF_TEST_ATTRIBUTE_UNUSED, + wchar_t * const argv[] EWF_TEST_ATTRIBUTE_UNUSED ) +#else +int main( + int argc EWF_TEST_ATTRIBUTE_UNUSED, + char * const argv[] EWF_TEST_ATTRIBUTE_UNUSED ) +#endif +{ + EWF_TEST_UNREFERENCED_PARAMETER( argc ) + EWF_TEST_UNREFERENCED_PARAMETER( argv ) + +#if defined( __GNUC__ ) && !defined( LIBEWF_DLL_IMPORT ) + + EWF_TEST_RUN( + "libewf_empty_block_test", + ewf_test_empty_block_test ); + +#endif /* defined( __GNUC__ ) && !defined( LIBEWF_DLL_IMPORT ) */ + + return( EXIT_SUCCESS ); + +#if defined( __GNUC__ ) && !defined( LIBEWF_DLL_IMPORT ) + +on_error: + return( EXIT_FAILURE ); + +#endif /* defined( __GNUC__ ) && !defined( LIBEWF_DLL_IMPORT ) */ +} + diff --git a/tests/test_library.ps1 b/tests/test_library.ps1 index b0a7aa4..b9e7f28 100644 --- a/tests/test_library.ps1 +++ b/tests/test_library.ps1 @@ -6,7 +6,7 @@ $ExitSuccess = 0 $ExitFailure = 1 $ExitIgnore = 77 -$LibraryTests = "checksum chunk_data chunk_table compression date_time date_time_values deflate error file_entry filename hash_sections hash_values io_handle media_values notify read_io_handle sector_range segment_table single_files write_io_handle" +$LibraryTests = "checksum chunk_data chunk_table compression date_time date_time_values deflate empty_block error file_entry filename hash_sections hash_values io_handle media_values notify read_io_handle sector_range segment_table single_files write_io_handle" $LibraryTestsWithInput = "handle support" $OptionSets = "" diff --git a/tests/test_library.sh b/tests/test_library.sh index dab5568..fdad743 100755 --- a/tests/test_library.sh +++ b/tests/test_library.sh @@ -7,7 +7,7 @@ EXIT_SUCCESS=0; EXIT_FAILURE=1; EXIT_IGNORE=77; -LIBRARY_TESTS="checksum chunk_data chunk_table compression date_time date_time_values deflate error file_entry filename hash_sections hash_values io_handle media_values notify read_io_handle sector_range segment_table single_files write_io_handle"; +LIBRARY_TESTS="checksum chunk_data chunk_table compression date_time date_time_values deflate empty_block error file_entry filename hash_sections hash_values io_handle media_values notify read_io_handle sector_range segment_table single_files write_io_handle"; LIBRARY_TESTS_WITH_INPUT="handle support"; OPTION_SETS="";