- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
WICED-Studio-6.2.1
in /43xxx_Wi-Fi/WICED/internal/wiced_lib.c
function unsigned_to_hex_string()
The function does not zero pad the output string which leads to uninitialized parts of the output string.
Found by testing /43xxx_Wi-Fi/apps/demo/bt_internet_gateway/restful_smart_server.
Solved! Go to Solution.
- Labels:
-
WICED Studio
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Any parameter which should result in zero padding has the problem.
e.g. use:
int value = 0xB; char* string = (char*)malloc(sizeof(ULONG_MAX_STR) + 1); unsigned_to_hex_string( value , string, 4, 4 ); WPRINT_APP_INFO((" %s\n", string));
This should result in "000B".
I explain what happens (source below).
- digits_left will be 4
- the conversion loop runs for all 4 digits or aborts on zero value (which is the case in our example after first digit)
- because the loop has only set 1 digit of buffer[], the rest of buffer[] is uninitialized!
- unintialized data is returned
In old SDK 5.x the local buffer was initialized with "00000000" and therefor the loop worked.
/** * Converts a unsigned 32-bit long int to a hexidecimal string * * @param value[in] : The unsigned 32-bit long int to be converted * @param output[out] : The buffer which will receive the hexidecimal string. A terminating 'null' is added. Ensure that there is space in the buffer for this. * @param min_length[in] : The minimum number of characters to output (zero padding will apply if required) * @param max_length[in] : The maximum number of characters to output. The max number of characters it can have is of the length of (ULONG_MAX + 1). * * @note: No leading '0x' is added. * * @return the number of characters returned (excluding terminating null) * */ uint8_t unsigned_to_hex_string( uint32_t value, char* output, uint8_t min_length, uint8_t max_length ) { uint8_t digits_left; char buffer[sizeof(ULONG_MAX_STR) + 1]; /* Buffer for ULONG_MAX with +1 for storing the sign */ max_length = (uint8_t) MIN( max_length, sizeof( buffer ) ); digits_left = max_length; while ( ( value != 0 ) && ( digits_left != 0 ) ) { --digits_left; buffer[ digits_left ] = nibble_to_hexchar( value & 0x0000000F ); value = value >> 4; } digits_left = (uint8_t) MIN( ( max_length - min_length ), digits_left ); memcpy( output, &buffer[ digits_left ], (size_t)( max_length - digits_left ) ); /* Add terminating null */ output[( max_length - digits_left )] = '\x00'; return (uint8_t) ( max_length - digits_left ); }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
The function appears to be working correctly. It terminates the hex string by a NULL character. I checked by calling the function directly and passing integer value as argument.
int value = 100;
char* string = (char*)malloc(sizeof(ULONG_MAX_STR) + 1);
unsigned_to_hex_string( value , string, 2, 2 );
WPRINT_APP_INFO((" %s\n", string));
Can you point any specific use case where you passed an integer and the hex string is not null terminated?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
riya You did not understand the problem.
This is zero termination: "100\0"
This is zero padding: "0001"
The problem is visible with restful_smart_server demo when the BLE scanned data is sent in response.
When Hex Data e.g. 0x0B should be converted you get: "?B\0" instead of "0B\0" because the zero padding does not work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
gregor.bader_3483646 wrote:
riya You did not understand the problem.
This is zero termination: "100\0"
This is zero padding: "0001"
The problem is visible with restful_smart_server demo when the BLE scanned data is sent in response.
When Hex Data e.g. 0x0B should be converted you get: "?B\0" instead of "0B\0" because the zero padding does not work.
Can you provide the parameters to pass to unsigned_to_hex_string() that can cause issue?
unsigned_to_hex_string( uint32_t value, char* output, uint8_t min_length, uint8_t max_length )
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Any parameter which should result in zero padding has the problem.
e.g. use:
int value = 0xB; char* string = (char*)malloc(sizeof(ULONG_MAX_STR) + 1); unsigned_to_hex_string( value , string, 4, 4 ); WPRINT_APP_INFO((" %s\n", string));
This should result in "000B".
I explain what happens (source below).
- digits_left will be 4
- the conversion loop runs for all 4 digits or aborts on zero value (which is the case in our example after first digit)
- because the loop has only set 1 digit of buffer[], the rest of buffer[] is uninitialized!
- unintialized data is returned
In old SDK 5.x the local buffer was initialized with "00000000" and therefor the loop worked.
/** * Converts a unsigned 32-bit long int to a hexidecimal string * * @param value[in] : The unsigned 32-bit long int to be converted * @param output[out] : The buffer which will receive the hexidecimal string. A terminating 'null' is added. Ensure that there is space in the buffer for this. * @param min_length[in] : The minimum number of characters to output (zero padding will apply if required) * @param max_length[in] : The maximum number of characters to output. The max number of characters it can have is of the length of (ULONG_MAX + 1). * * @note: No leading '0x' is added. * * @return the number of characters returned (excluding terminating null) * */ uint8_t unsigned_to_hex_string( uint32_t value, char* output, uint8_t min_length, uint8_t max_length ) { uint8_t digits_left; char buffer[sizeof(ULONG_MAX_STR) + 1]; /* Buffer for ULONG_MAX with +1 for storing the sign */ max_length = (uint8_t) MIN( max_length, sizeof( buffer ) ); digits_left = max_length; while ( ( value != 0 ) && ( digits_left != 0 ) ) { --digits_left; buffer[ digits_left ] = nibble_to_hexchar( value & 0x0000000F ); value = value >> 4; } digits_left = (uint8_t) MIN( ( max_length - min_length ), digits_left ); memcpy( output, &buffer[ digits_left ], (size_t)( max_length - digits_left ) ); /* Add terminating null */ output[( max_length - digits_left )] = '\x00'; return (uint8_t) ( max_length - digits_left ); }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, I got your point now.
I already fixed it locally when I upgrade to sdk-6.2. The bug is indeed in standard sdk-6.2.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sir, We have created an internal ticket to take care of the issue. I will update the thread when the fix is available.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The buffer needs to be intialized with Zero and we have fixed this internally. The next release will not have this error.