📄 libewf_string.c
字号:
/* * libewf character type string functions * * Copyright (c) 2006-2007, Joachim Metz <forensics@hoffmannbv.nl>, * Hoffmann Investigations. All rights reserved. * * Refer to AUTHORS for acknowledgements. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the creator, related organisations, nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * - All advertising materials mentioning features or use of this software * must acknowledge the contribution by people stated in the acknowledgements. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER, COMPANY AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include "libewf_includes.h"#include <errno.h>#include <libewf/libewf_definitions.h>#include "libewf_common.h"#include "libewf_notify.h"#include "libewf_string.h"#include "ewf_char.h"/* Duplicates a string * Returns the pointer to the duplicate string, or NULL on error */LIBEWF_CHAR *libewf_string_duplicate( LIBEWF_CHAR *string, size_t size ){ LIBEWF_CHAR *duplicate = NULL; if( string == NULL ) { return( NULL ); } if( size == 0 ) { return( NULL ); } if( size > (size_t) SSIZE_MAX ) { LIBEWF_WARNING_PRINT( "libewf_string_duplicate: invalid size value exceeds maximum.\n" ); return( NULL ); } /* Add an additional character for the end of string */ size += 1; duplicate = (LIBEWF_CHAR *) libewf_common_alloc( LIBEWF_CHAR_SIZE * size ); if( duplicate == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_duplicate: unable to create duplicate string.\n" ); return( NULL ); } if( libewf_string_copy( duplicate, string, size ) == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_duplicate: unable to set duplicate string.\n" ); libewf_common_free( duplicate ); return( NULL ); } duplicate[ size - 1 ] = (LIBEWF_CHAR) '\0'; return( duplicate );}#ifdef HAVE_WIDE_CHARACTER_TYPE#ifdef HAVE_WCSTOL#define libewf_string_to_signed_long( string, end_of_string, base ) (int64_t) wcstol( string, end_of_string, base )#endif#else#ifdef HAVE_STRTOL#define libewf_string_to_signed_long( string, end_of_string, base ) (int64_t) strtol( string, end_of_string, base )#elif defined(HAVE_ATOL)#define libewf_string_to_signed_long( string, end_of_string, base ) (int64_t) atol( string )#endif#endif/* Returns the value represented by a string, returns 0 and sets errno on error */int64_t libewf_string_to_int64( const LIBEWF_CHAR *string, size_t size ){ LIBEWF_CHAR *end_of_string = NULL; int64_t value = 0; if( string == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_to_int64: invalid string.\n" ); errno = EINVAL; return( 0 ); } if( size == 0 ) { LIBEWF_WARNING_PRINT( "libewf_string_to_int64: string is emtpy.\n" ); errno = EINVAL; return( 0 ); } if( size > (size_t) SSIZE_MAX ) { LIBEWF_WARNING_PRINT( "libewf_string_to_int64: invalid size value exceeds maximum.\n" ); errno = EINVAL; return( 0 ); } end_of_string = (LIBEWF_CHAR *) &string[ size - 1 ];#if defined( libewf_string_to_signed_long ) value = libewf_string_to_signed_long( string, &end_of_string, 0 );#else#error Missing equivalent of strtol#endif if( value == (int64_t) LONG_MAX ) { LIBEWF_WARNING_PRINT( "libewf_string_to_int64: unable to convert string.\n" ); return( 0 ); } return( value );}#ifdef HAVE_WIDE_CHARACTER_TYPE#ifdef HAVE_WCSTOUL#define libewf_string_to_unsigned_long( string, end_of_string, base ) (uint64_t) wcstoul( string, end_of_string, base )#endif#else#ifdef HAVE_STRTOUL#define libewf_string_to_unsigned_long( string, end_of_string, base ) (uint64_t) strtoul( string, end_of_string, base )#elif defined(HAVE_ATOL)#define libewf_string_to_unsigned_long( string, end_of_string, base ) (uint64_t) atol( string )#endif#endif/* Returns the value represented by a string, returns 0 and sets errno on error */uint64_t libewf_string_to_uint64( const LIBEWF_CHAR *string, size_t size ){ LIBEWF_CHAR *end_of_string = NULL; uint64_t value = 0; if( string == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_to_uint64: invalid string.\n" ); errno = EINVAL; return( 0 ); } if( size == 0 ) { LIBEWF_WARNING_PRINT( "libewf_string_to_uint64: string is emtpy.\n" ); errno = EINVAL; return( 0 ); } if( size > (size_t) SSIZE_MAX ) { LIBEWF_WARNING_PRINT( "libewf_string_to_uint64: invalid size value exceeds maximum.\n" ); errno = EINVAL; return( 0 ); } end_of_string = (LIBEWF_CHAR *) &string[ size - 1 ];#if defined( libewf_string_to_unsigned_long ) value = libewf_string_to_unsigned_long( string, &end_of_string, 0 );#else#error Missing equivalent of strtoul#endif if( value == (uint64_t) LONG_MAX ) { LIBEWF_WARNING_PRINT( "libewf_string_to_uint64: unable to convert string.\n" ); return( 0 ); } return( value );}/* Split a string into elements using a delimiter character * Returns a pointer to the new instance, NULL on error */LIBEWF_CHAR **libewf_string_split( LIBEWF_CHAR *string, size_t size, LIBEWF_CHAR delimiter, uint32_t *amount ){ LIBEWF_CHAR **lines = NULL; LIBEWF_CHAR *line_start = NULL; LIBEWF_CHAR *line_end = NULL; LIBEWF_CHAR *string_end = NULL; size_t size_string = 0; size_t line_size = 0; uint32_t iterator = 0; if( string == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_split: invalid string.\n" ); return( NULL ); } if( amount == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_split: invalid amount.\n" ); return( NULL ); } if( size == 0 ) { LIBEWF_WARNING_PRINT( "libewf_string_split: string is empty.\n" ); return( NULL ); } if( size > (size_t) SSIZE_MAX ) { LIBEWF_WARNING_PRINT( "libewf_string_split: invalid size value exceeds maximum.\n" ); return( NULL ); } size_string = size; line_start = string; line_end = string; string_end = &string[ size ]; do { line_end = (LIBEWF_CHAR *) libewf_string_search( line_start, delimiter, size_string ); iterator++; if( line_end == NULL ) { break; } /* Include delimiter character */ size_string -= (size_t) ( line_end - line_start ) + 1; if( line_end == line_start ) { line_start += 1; } else if( line_end != string ) { line_start = line_end + 1; } } while( line_end != NULL ); *amount = iterator; lines = (LIBEWF_CHAR **) libewf_common_alloc_cleared( ( sizeof( LIBEWF_CHAR * ) * *amount ), 0 ); if( lines == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_split: unable to allocate dynamic array lines.\n" ); return( NULL ); } size_string = size; line_start = string; line_end = string; for( iterator = 0; iterator < *amount; iterator++ ) { if( line_end != string ) { line_start = line_end + 1; } line_end = (LIBEWF_CHAR *) libewf_string_search( line_start, delimiter, size_string ); /* Check for last value */ if( line_end == NULL ) { line_size = (size_t) ( string_end - line_start ); } else { line_size = (size_t) ( line_end - line_start ); } /* Add 1 additional byte required for the end of string character */ line_size += 1; lines[ iterator ] = (LIBEWF_CHAR *) libewf_common_alloc( LIBEWF_CHAR_SIZE * line_size ); if( lines[ iterator ] == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_split: unable to allocate line string.\n" ); libewf_string_split_values_free( lines, ( iterator - 1 ) ); return( NULL ); } if( libewf_string_copy( lines[ iterator ], line_start, line_size ) == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_split: unable to set dynamic array lines.\n" ); libewf_string_split_values_free( lines, iterator ); return( NULL ); } lines[ iterator ][ line_size - 1 ] = (LIBEWF_CHAR) '\0'; /* Include delimiter character */ size_string -= (size_t) ( line_end - line_start ) + 1; /* Correct if first value is empty */ if( line_end == string ) { line_start += 1; } } return( lines );}/* Clears a split values array */void libewf_string_split_values_free( LIBEWF_CHAR **split_values, uint32_t amount ){ uint32_t iterator = 0; if( split_values == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_split_values_free: invalid split values array.\n" ); return; } for( iterator = 0; iterator < amount; iterator++ ) { if( split_values[ iterator ] == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_split_values_free: empty value.\n" ); } else { libewf_common_free( split_values[ iterator ] ); } } libewf_common_free( split_values );}/* Copies a multi byte UTF16 string to a single byte ASCII string * Returns 1 if successful, on -1 on error */int8_t libewf_string_copy_utf16_to_ascii( LIBEWF_CHAR *utf16_string, size_t size_utf16, LIBEWF_CHAR* ascii_string, size_t size_ascii ){ size_t utf16_iterator = 2; size_t ascii_iterator = 0; uint8_t byte_order = 0; if( utf16_string == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_utf16_to_ascii: invalid UTF16 string.\n" ); return( -1 ); } if( ascii_string == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_utf16_to_ascii: invalid ASCII string.\n" ); return( -1 ); } if( ( size_utf16 > (size_t) SSIZE_MAX ) || ( size_ascii > (size_t) SSIZE_MAX ) ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_utf16_to_ascii: invalid size value exceeds maximum.\n" ); return( -1 ); } /* The UTF16 string contains twice as much bytes needed for the ASCII string * with two additional bytes representing byte order */ if( size_ascii < ( ( size_utf16 - 2 ) / 2 ) ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_utf16_to_ascii: ASCII string too small.\n" ); return( -1 ); } /* Check if UTF16 string is in big or little endian */ if( ( (uint8_t) utf16_string[ 0 ] == 0xff ) && ( (uint8_t) utf16_string[ 1 ] == 0xfe ) ) { byte_order = LIBEWF_STRING_LITTLE_ENDIAN; } else if( ( (uint8_t) utf16_string[ 0 ] == 0xfe ) && ( (uint8_t) utf16_string[ 1 ] == 0xff ) ) { byte_order = LIBEWF_STRING_BIG_ENDIAN; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -