/* * Functions for testing * * Copyright (C) 2010-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * * This software 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 software 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 software. If not, see . */ #include #include #include #include #include #include #if defined( HAVE_STDLIB_H ) || defined( WINAPI ) #include #endif #include "fsntfs_test_libbfio.h" #include "fsntfs_test_libcerror.h" #include "fsntfs_test_libclocale.h" #include "fsntfs_test_libuna.h" /* Retrieves source as a narrow string * Returns 1 if successful or -1 on error */ int fsntfs_test_get_narrow_source( const system_character_t *source, char *narrow_string, size_t narrow_string_size, libcerror_error_t **error ) { static char *function = "fsntfs_test_get_narrow_source"; size_t narrow_source_size = 0; size_t source_length = 0; #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) int result = 0; #endif if( source == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid source.", function ); return( -1 ); } if( narrow_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid narrow string.", function ); return( -1 ); } if( narrow_string_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid narrow string size value exceeds maximum.", function ); return( -1 ); } source_length = system_string_length( source ); if( source_length > (size_t) ( SSIZE_MAX - 1 ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid source length value out of bounds.", function ); return( -1 ); } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( libclocale_codepage == 0 ) { #if SIZEOF_WCHAR_T == 4 result = libuna_utf8_string_size_from_utf32( (libuna_utf32_character_t *) source, source_length + 1, &narrow_source_size, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_utf8_string_size_from_utf16( (libuna_utf16_character_t *) source, source_length + 1, &narrow_source_size, error ); #endif } else { #if SIZEOF_WCHAR_T == 4 result = libuna_byte_stream_size_from_utf32( (libuna_utf32_character_t *) source, source_length + 1, libclocale_codepage, &narrow_source_size, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_byte_stream_size_from_utf16( (libuna_utf16_character_t *) source, source_length + 1, libclocale_codepage, &narrow_source_size, error ); #endif } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to determine narrow string size.", function ); return( -1 ); } #else narrow_source_size = source_length + 1; #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ if( narrow_string_size < narrow_source_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: narrow string too small.", function ); return( -1 ); } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( libclocale_codepage == 0 ) { #if SIZEOF_WCHAR_T == 4 result = libuna_utf8_string_copy_from_utf32( (libuna_utf8_character_t *) narrow_string, narrow_string_size, (libuna_utf32_character_t *) source, source_length + 1, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_utf8_string_copy_from_utf16( (libuna_utf8_character_t *) narrow_string, narrow_string_size, (libuna_utf16_character_t *) source, source_length + 1, error ); #endif } else { #if SIZEOF_WCHAR_T == 4 result = libuna_byte_stream_copy_from_utf32( (uint8_t *) narrow_string, narrow_string_size, libclocale_codepage, (libuna_utf32_character_t *) source, source_length + 1, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_byte_stream_copy_from_utf16( (uint8_t *) narrow_string, narrow_string_size, libclocale_codepage, (libuna_utf16_character_t *) source, source_length + 1, error ); #endif } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to set narrow string.", function ); return( -1 ); } #else if( system_string_copy( narrow_string, source, source_length ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to set narrow string.", function ); return( -1 ); } narrow_string[ source_length ] = 0; #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ return( 1 ); } #if defined( HAVE_WIDE_CHARACTER_TYPE ) /* Retrieves source as a wide string * Returns 1 if successful or -1 on error */ int fsntfs_test_get_wide_source( const system_character_t *source, wchar_t *wide_string, size_t wide_string_size, libcerror_error_t **error ) { static char *function = "fsntfs_test_get_wide_source"; size_t wide_source_size = 0; size_t source_length = 0; #if !defined( HAVE_WIDE_SYSTEM_CHARACTER ) int result = 0; #endif if( source == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid source.", function ); return( -1 ); } if( wide_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid wide string.", function ); return( -1 ); } if( wide_string_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid wide string size value exceeds maximum.", function ); return( -1 ); } source_length = system_string_length( source ); if( source_length > (size_t) ( SSIZE_MAX - 1 ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid source length value out of bounds.", function ); return( -1 ); } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) wide_source_size = source_length + 1; #else if( libclocale_codepage == 0 ) { #if SIZEOF_WCHAR_T == 4 result = libuna_utf32_string_size_from_utf8( (libuna_utf8_character_t *) source, source_length + 1, &wide_source_size, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_utf16_string_size_from_utf8( (libuna_utf8_character_t *) source, source_length + 1, &wide_source_size, error ); #endif } else { #if SIZEOF_WCHAR_T == 4 result = libuna_utf32_string_size_from_byte_stream( (uint8_t *) source, source_length + 1, libclocale_codepage, &wide_source_size, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_utf16_string_size_from_byte_stream( (uint8_t *) source, source_length + 1, libclocale_codepage, &wide_source_size, error ); #endif } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to determine wide string size.", function ); return( -1 ); } #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ if( wide_string_size < wide_source_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: wide string too small.", function ); return( -1 ); } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( system_string_copy( wide_string, source, source_length ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to set wide string.", function ); return( -1 ); } wide_string[ source_length ] = 0; #else if( libclocale_codepage == 0 ) { #if SIZEOF_WCHAR_T == 4 result = libuna_utf32_string_copy_from_utf8( (libuna_utf32_character_t *) wide_string, wide_string_size, (uint8_t *) source, source_length + 1, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_utf16_string_copy_from_utf8( (libuna_utf16_character_t *) wide_string, wide_string_size, (uint8_t *) source, source_length + 1, error ); #endif } else { #if SIZEOF_WCHAR_T == 4 result = libuna_utf32_string_copy_from_byte_stream( (libuna_utf32_character_t *) wide_string, wide_string_size, (uint8_t *) source, source_length + 1, libclocale_codepage, error ); #elif SIZEOF_WCHAR_T == 2 result = libuna_utf16_string_copy_from_byte_stream( (libuna_utf16_character_t *) wide_string, wide_string_size, (uint8_t *) source, source_length + 1, libclocale_codepage, error ); #endif } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to set wide string.", function ); return( -1 ); } #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ return( 1 ); } #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */ /* Copies a string of a decimal value to a 64-bit value * Returns 1 if successful or -1 on error */ int fsntfs_test_system_string_copy_from_64_bit_in_decimal( const system_character_t *string, size_t string_size, uint64_t *value_64bit, libcerror_error_t **error ) { static char *function = "fsntfs_test_system_string_copy_from_64_bit_in_decimal"; size_t string_index = 0; system_character_t character_value = 0; uint8_t maximum_string_index = 20; int8_t sign = 1; if( string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid string.", function ); return( -1 ); } if( string_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid string size value exceeds maximum.", function ); return( -1 ); } if( value_64bit == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid value 64-bit.", function ); return( -1 ); } *value_64bit = 0; if( string[ string_index ] == (system_character_t) '-' ) { string_index++; maximum_string_index++; sign = -1; } else if( string[ string_index ] == (system_character_t) '+' ) { string_index++; maximum_string_index++; } while( string_index < string_size ) { if( string[ string_index ] == 0 ) { break; } if( string_index > (size_t) maximum_string_index ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE, "%s: string too large.", function ); return( -1 ); } *value_64bit *= 10; if( ( string[ string_index ] >= (system_character_t) '0' ) && ( string[ string_index ] <= (system_character_t) '9' ) ) { character_value = (system_character_t) ( string[ string_index ] - (system_character_t) '0' ); } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported character value: %" PRIc_SYSTEM " at index: %d.", function, string[ string_index ], string_index ); return( -1 ); } *value_64bit += character_value; string_index++; } if( sign == -1 ) { *value_64bit *= (uint64_t) -1; } return( 1 ); } /* Creates a file IO handle for test data * Returns 1 if successful or -1 on error */ int fsntfs_test_open_file_io_handle( libbfio_handle_t **file_io_handle, uint8_t *data, size_t data_size, libcerror_error_t **error ) { static char *function = "fsntfs_test_open_file_io_handle"; if( file_io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file IO handle.", function ); return( -1 ); } if( libbfio_memory_range_initialize( file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create file IO handle.", function ); goto on_error; } if( libbfio_memory_range_set( *file_io_handle, data, data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set memory range of file IO handle.", function ); goto on_error; } if( libbfio_handle_open( *file_io_handle, LIBBFIO_OPEN_READ, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open file IO handle.", function ); goto on_error; } return( 1 ); on_error: if( *file_io_handle != NULL ) { libbfio_handle_free( file_io_handle, NULL ); } return( -1 ); } /* Closes a file IO handle for test data * Returns 0 if successful or -1 on error */ int fsntfs_test_close_file_io_handle( libbfio_handle_t **file_io_handle, libcerror_error_t **error ) { static char *function = "fsntfs_test_close_file_io_handle"; int result = 0; if( file_io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file IO handle.", function ); return( -1 ); } if( libbfio_handle_close( *file_io_handle, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close file IO handle.", function ); result = -1; } if( libbfio_handle_free( file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free file IO handle.", function ); result = -1; } return( result ); }