/* Determines the size of an UTF-16 stream from an UTF-8 string * Returns 1 if successful or -1 on error */ int libuna_utf16_stream_size_from_utf8( const libuna_utf8_character_t *utf8_string, size_t utf8_string_size, size_t *utf16_stream_size, libcerror_error_t **error ) { static char *function = "libuna_utf16_stream_size_from_utf8"; size_t utf8_string_index = 0; libuna_unicode_character_t unicode_character = 0; if( utf8_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 string.", function ); return( -1 ); } if( utf8_string_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 string size value exceeds maximum.", function ); return( -1 ); } if( utf16_stream_size == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-16 stream size.", function ); return( -1 ); } /* Add the byte order mark */ *utf16_stream_size = 1; while( utf8_string_index < utf8_string_size ) { /* Convert the UTF-8 character bytes into a Unicode character */ if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_string, utf8_string_size, &utf8_string_index, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to copy Unicode character from UTF-8.", function ); return( -1 ); } /* Determine how many UTF-16 character bytes are required */ if( libuna_unicode_character_size_to_utf16( unicode_character, utf16_stream_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED, "%s: unable to determine size of Unicode character in UTF-16.", function ); return( -1 ); } } /* Convert the number of characters into bytes */ *utf16_stream_size *= 2; return( 1 ); }
/* Copies an UTF-16 stream from an UTF-8 string * Returns 1 if successful or -1 on error */ int libuna_utf16_stream_copy_from_utf8( uint8_t *utf16_stream, size_t utf16_stream_size, int byte_order, const libuna_utf8_character_t *utf8_string, size_t utf8_string_size, libcerror_error_t **error ) { static char *function = "libuna_utf16_stream_copy_from_utf8"; size_t utf16_stream_index = 0; size_t utf8_string_index = 0; libuna_unicode_character_t unicode_character = 0; if( utf16_stream == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-16 stream.", function ); return( -1 ); } if( utf16_stream_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-16 stream size value exceeds maximum.", function ); return( -1 ); } if( ( byte_order != LIBUNA_ENDIAN_BIG ) && ( byte_order != LIBUNA_ENDIAN_LITTLE ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported byte order.", function ); return( -1 ); } if( utf8_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 string.", function ); return( -1 ); } if( utf8_string_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 string size value exceeds maximum.", function ); return( -1 ); } if( libuna_utf16_stream_copy_byte_order_mark( utf16_stream, utf16_stream_size, &utf16_stream_index, byte_order, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED, "%s: unable to copy UTF-16 byte order mark.", function ); return( -1 ); } while( utf8_string_index < utf8_string_size ) { /* Convert the UTF-8 string bytes into a Unicode character */ if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_string, utf8_string_size, &utf8_string_index, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to copy Unicode character from UTF-8 string.", function ); return( -1 ); } /* Convert the Unicode character into UTF-16 stream bytes */ if( libuna_unicode_character_copy_to_utf16_stream( unicode_character, utf16_stream, utf16_stream_size, &utf16_stream_index, byte_order, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED, "%s: unable to copy Unicode character to UTF-16 stream.", function ); return( -1 ); } } return( 1 ); }
/* Copies an UTF-8 string from an UTF-8 stream * Returns 1 if successful or -1 on error */ int libuna_utf8_string_copy_from_utf8_stream( libuna_utf8_character_t *utf8_string, size_t utf8_string_size, const uint8_t *utf8_stream, size_t utf8_stream_size, liberror_error_t **error ) { static char *function = "libuna_utf8_string_copy_from_utf8_stream"; size_t utf8_string_iterator = 0; size_t utf8_stream_iterator = 0; libuna_unicode_character_t unicode_character = 0; uint8_t zero_byte = 0; if( utf8_string == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 string.", function ); return( -1 ); } if( utf8_string_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 string size value exceeds maximum.", function ); return( -1 ); } if( utf8_stream == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 stream.", function ); return( -1 ); } if( utf8_stream_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 stream size value exceeds maximum.", function ); return( -1 ); } if( utf8_stream_size < 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: missing UTF-8 stream bytes.", function ); return( -1 ); } /* Check if UTF-8 stream starts with a byte order mark (BOM) */ if( utf8_stream_size >= 3 ) { if( ( utf8_stream[ 0 ] == 0x0ef ) && ( utf8_stream[ 1 ] == 0x0bb ) && ( utf8_stream[ 2 ] == 0x0bf ) ) { utf8_stream_iterator += 3; } } /* Check if the UTF-8 stream is terminated with zero bytes */ if( utf8_stream[ utf8_stream_size - 1 ] != 0 ) { zero_byte = 1; } while( utf8_stream_iterator < utf8_stream_size ) { /* Convert the UTF-8 stream bytes into a Unicode character */ if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_stream, utf8_stream_size, &utf8_stream_iterator, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to copy Unicode character from UTF-8 stream.", function ); return( -1 ); } /* Convert the Unicode character into UTF-8 character bytes */ if( libuna_unicode_character_copy_to_utf8( unicode_character, utf8_string, utf8_string_size, &utf8_string_iterator, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_OUTPUT_FAILED, "%s: unable to copy Unicode character to UTF-8.", function ); return( -1 ); } } if( zero_byte != 0 ) { if( utf8_string_iterator >= utf8_string_size ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: UTF-8 string too small.", function ); return( -1 ); } utf8_string[ utf8_string_iterator++ ] = 0; } return( 1 ); }
/* Retrieves the sub item for the specific UTF-8 encoded path * The path separator is the \ character * Returns 1 if successful, 0 if no such item or -1 on error */ int libolecf_item_get_sub_item_by_utf8_path( libolecf_item_t *item, const uint8_t *utf8_string, size_t utf8_string_length, libolecf_item_t **sub_item, libcerror_error_t **error ) { libolecf_internal_item_t *internal_item = NULL; libcdata_tree_node_t *directory_tree_node = NULL; libcdata_tree_node_t *sub_directory_tree_node = NULL; uint8_t *utf8_string_segment = NULL; static char *function = "libolecf_item_get_sub_item_by_utf8_path"; libuna_unicode_character_t unicode_character = 0; size_t utf8_string_index = 0; size_t utf8_string_segment_length = 0; int result = 0; if( item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid item.", function ); return( -1 ); } internal_item = (libolecf_internal_item_t *) item; if( internal_item->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid item - missing IO handle.", function ); return( -1 ); } if( sub_item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid sub item.", function ); return( -1 ); } if( *sub_item != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: sub item already set.", function ); return( -1 ); } directory_tree_node = internal_item->directory_tree_node; if( utf8_string_length > 0 ) { /* Ignore a leading separator */ if( utf8_string[ utf8_string_index ] == (uint8_t) LIBOLECF_SEPARATOR ) { utf8_string_index++; } } if( ( utf8_string_length == 0 ) || ( utf8_string_length == 1 ) ) { result = 1; } else while( utf8_string_index < utf8_string_length ) { utf8_string_segment = (uint8_t *) &( utf8_string[ utf8_string_index ] ); utf8_string_segment_length = utf8_string_index; while( utf8_string_index < utf8_string_length ) { if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_string, utf8_string_length, &utf8_string_index, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy UTF-8 string to Unicode character.", function ); return( -1 ); } if( ( unicode_character == (libuna_unicode_character_t) LIBOLECF_SEPARATOR ) || ( unicode_character == 0 ) ) { utf8_string_segment_length += 1; break; } } utf8_string_segment_length = utf8_string_index - utf8_string_segment_length; if( utf8_string_segment_length == 0 ) { result = 0; } else { result = libolecf_directory_tree_get_sub_node_by_utf8_name( directory_tree_node, utf8_string_segment, utf8_string_segment_length, internal_item->io_handle->byte_order, &sub_directory_tree_node, error ); } if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve directory tree sub node by UTF-8 name.", function ); return( -1 ); } else if( result == 0 ) { break; } directory_tree_node = sub_directory_tree_node; } if( result != 0 ) { if( libolecf_item_initialize( sub_item, internal_item->io_handle, internal_item->file_io_handle, internal_item->file, directory_tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create sub item.", function ); return( -1 ); } } return( result ); }
/* Copies a byte stream from an UTF-8 string * Returns 1 if successful or -1 on error */ int libuna_byte_stream_copy_from_utf8( uint8_t *byte_stream, size_t byte_stream_size, int codepage, const libuna_utf8_character_t *utf8_string, size_t utf8_string_size, libcerror_error_t **error ) { static char *function = "libuna_byte_stream_copy_from_utf8"; size_t byte_stream_index = 0; size_t utf8_string_index = 0; libuna_unicode_character_t unicode_character = 0; if( byte_stream == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid byte stream.", function ); return( -1 ); } if( byte_stream_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid byte stream size value exceeds maximum.", function ); return( -1 ); } if( utf8_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 string.", function ); return( -1 ); } if( utf8_string_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 string size value exceeds maximum.", function ); return( -1 ); } while( utf8_string_index < utf8_string_size ) { /* Convert the UTF-8 string bytes into a Unicode character */ if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_string, utf8_string_size, &utf8_string_index, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to copy Unicode character from UTF-8 string.", function ); return( -1 ); } /* Convert the Unicode character into a byte stream */ if( libuna_unicode_character_copy_to_byte_stream( unicode_character, byte_stream, byte_stream_size, &byte_stream_index, codepage, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED, "%s: unable to copy Unicode character to byte stream.", function ); return( -1 ); } } return( 1 ); }
/* Determines the size of an UTF-7 stream from an UTF-8 string * Returns 1 if successful or -1 on error */ int libuna_utf7_stream_size_from_utf8( const libuna_utf8_character_t *utf8_string, size_t utf8_string_size, size_t *utf7_stream_size, liberror_error_t **error ) { static char *function = "libuna_utf7_stream_size_from_utf8"; size_t utf8_string_iterator = 0; libuna_unicode_character_t unicode_character = 0; uint32_t utf7_stream_base64_data = 0; if( utf8_string == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 string.", function ); return( -1 ); } if( utf8_string_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 string size value exceeds maximum.", function ); return( -1 ); } if( utf7_stream_size == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-7 stream size.", function ); return( -1 ); } while( utf8_string_iterator < utf8_string_size ) { /* Convert the UTF-8 character bytes into a Unicode character */ if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_string, utf8_string_size, &utf8_string_iterator, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to copy Unicode character from UTF-8.", function ); return( -1 ); } /* Determine how many UTF-7 character bytes are required */ if( libuna_unicode_character_size_to_utf7_stream( unicode_character, utf7_stream_size, &utf7_stream_base64_data, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_OUTPUT_FAILED, "%s: unable to determine size of Unicode character in UTF-7.", function ); return( -1 ); } } return( 1 ); }
/* Determines the size of a UTF-32 string from a UTF-8 stream * Returns 1 if successful or -1 on error */ int libuna_utf32_string_size_from_utf8_stream( const uint8_t *utf8_stream, size_t utf8_stream_size, size_t *utf32_string_size, liberror_error_t **error ) { static char *function = "libuna_utf32_string_size_from_utf8_stream"; size_t utf8_stream_iterator = 0; libuna_unicode_character_t unicode_character = 0; if( utf8_stream == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 stream.", function ); return( -1 ); } if( utf8_stream_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 stream size value exceeds maximum.", function ); return( -1 ); } if( utf8_stream_size < 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: missing UTF-8 stream bytes.", function ); return( -1 ); } if( utf32_string_size == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-32 string size.", function ); return( -1 ); } *utf32_string_size = 0; /* Check if UTF-8 stream starts with a byte order mark (BOM) */ if( utf8_stream_size >= 3 ) { if( ( utf8_stream[ 0 ] == 0x0ef ) && ( utf8_stream[ 1 ] == 0x0bb ) && ( utf8_stream[ 2 ] == 0x0bf ) ) { utf8_stream_iterator += 3; } } /* Check if the UTF-8 stream is terminated with a zero byte */ if( utf8_stream[ utf8_stream_size - 1 ] != 0 ) { *utf32_string_size += 1; } while( utf8_stream_iterator < utf8_stream_size ) { /* Convert the UTF-8 stream bytes into a Unicode character */ if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_stream, utf8_stream_size, &utf8_stream_iterator, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to copy Unicode character from UTF-8 stream.", function ); return( -1 ); } /* Determine how many UTF-32 character bytes are required */ if( libuna_unicode_character_size_to_utf32( unicode_character, utf32_string_size, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to unable to determine size of Unicode character in UTF-32.", function ); return( -1 ); } } return( 1 ); }
/* Copies an UTF-32 string from an UTF-8 string * Returns 1 if successful or -1 on error */ int libuna_utf32_string_copy_from_utf8( libuna_utf32_character_t *utf32_string, size_t utf32_string_size, const libuna_utf8_character_t *utf8_string, size_t utf8_string_size, liberror_error_t **error ) { static char *function = "libuna_utf32_string_copy_from_utf8"; size_t utf8_string_iterator = 0; size_t utf32_string_iterator = 0; libuna_unicode_character_t unicode_character = 0; if( utf32_string == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-32 string.", function ); return( -1 ); } if( utf32_string_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-32 string size value exceeds maximum.", function ); return( -1 ); } if( utf8_string == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 string.", function ); return( -1 ); } if( utf8_string_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 string size value exceeds maximum.", function ); return( -1 ); } while( utf8_string_iterator < utf8_string_size ) { /* Convert the UTF-8 character bytes into a Unicode character */ if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_string, utf8_string_size, &utf8_string_iterator, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_INPUT_FAILED, "%s: unable to copy Unicode character from UTF-8.", function ); return( -1 ); } /* Convert the Unicode character into UTF-32 character bytes */ if( libuna_unicode_character_copy_to_utf32( unicode_character, utf32_string, utf32_string_size, &utf32_string_iterator, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_CONVERSION, LIBERROR_CONVERSION_ERROR_OUTPUT_FAILED, "%s: unable to copy Unicode character to UTF-32.", function ); return( -1 ); } } return( 1 ); }
/* Retrieves the key for the specific UTF-8 encoded path * The path separator is the \ character * Returns 1 if successful, 0 if no such key or -1 on error */ int libregf_file_get_key_by_utf8_path( libregf_file_t *file, const uint8_t *utf8_string, size_t utf8_string_length, libregf_key_t **key, libcerror_error_t **error ) { libfdata_tree_node_t *key_tree_node = NULL; libfdata_tree_node_t *key_tree_sub_node = NULL; libregf_internal_file_t *internal_file = NULL; libregf_key_item_t *key_item = NULL; libregf_key_item_t *sub_key_item = NULL; uint8_t *utf8_string_segment = NULL; static char *function = "libregf_file_get_key_by_utf8_path"; libuna_unicode_character_t unicode_character = 0; size_t utf8_string_index = 0; size_t utf8_string_segment_length = 0; uint32_t name_hash = 0; int result = 0; if( file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file.", function ); return( -1 ); } internal_file = (libregf_internal_file_t *) file; if( internal_file->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid file - missing IO handle.", function ); return( -1 ); } if( utf8_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-8 string.", function ); return( -1 ); } if( utf8_string_length > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-8 string length value exceeds maximum.", function ); return( -1 ); } if( key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid key.", function ); return( -1 ); } if( *key != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: key already set.", function ); return( -1 ); } if( utf8_string_length > 0 ) { /* Ignore a leading separator */ if( utf8_string[ utf8_string_index ] == (uint8_t) LIBREGF_SEPARATOR ) { utf8_string_index++; } } if( libfdata_tree_get_root_node( internal_file->key_tree, &key_tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve key tree root node.", function ); return( -1 ); } if( libfdata_tree_node_get_node_value( key_tree_node, (intptr_t *) internal_file->file_io_handle, (libfdata_cache_t *) internal_file->key_cache, (intptr_t **) &key_item, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve root key item.", function ); return( -1 ); } if( key_item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing root key item.", function ); return( -1 ); } if( utf8_string_length == utf8_string_index ) { result = 1; } else while( utf8_string_index < utf8_string_length ) { utf8_string_segment = (uint8_t *) &( utf8_string[ utf8_string_index ] ); utf8_string_segment_length = utf8_string_index; name_hash = 0; while( utf8_string_index < utf8_string_length ) { if( libuna_unicode_character_copy_from_utf8( &unicode_character, utf8_string, utf8_string_length, &utf8_string_index, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy UTF-8 string to Unicode character.", function ); return( -1 ); } if( ( unicode_character == (libuna_unicode_character_t) LIBREGF_SEPARATOR ) || ( unicode_character == 0 ) ) { utf8_string_segment_length += 1; break; } name_hash *= 37; name_hash += (uint32_t) towupper( (wint_t) unicode_character ); } utf8_string_segment_length = utf8_string_index - utf8_string_segment_length; if( utf8_string_segment_length == 0 ) { result = 0; } else { result = libregf_key_tree_get_sub_key_values_by_utf8_name( key_tree_node, internal_file->file_io_handle, internal_file->key_cache, name_hash, utf8_string_segment, utf8_string_segment_length, internal_file->io_handle->ascii_codepage, &key_tree_sub_node, &sub_key_item, error ); } if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub key values by name.", function ); return( -1 ); } else if( result == 0 ) { break; } key_tree_node = key_tree_sub_node; } if( result != 0 ) { if( libregf_key_initialize( key, internal_file->io_handle, internal_file->file_io_handle, key_tree_node, internal_file->key_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create key.", function ); return( -1 ); } } return( result ); }