Помимо проблем безопасности, вы пытаетесь динамически распределить буфер.
Вы можете использовать 2 подхода.
- Всегда
malloc
внутри вашей функции и документируйте, что она возвращает malloced
результат.
- Следуйте пути некоторых стандартных библиотечных функций, требуйте, чтобы пользователь передал указатель на допустимый буфер и его размер и возвратил фактически скопированный размер. Некоторые из этих функций разрешают проход
check
, когда вы передаете буфер null
, они не пытаются выделить его, а вместо этого возвращают размер, необходимый для хранения структуры.
Мне кажется, что вы уже реализовали подход № 1.
Для подхода № 2 используйте эту подпись:
int getMyPassword( char* buffer, size_t buff_size, size_t* p_num_copied )
{
unsigned char arr[] = { 'p', 'a', 's', 's', 'w', 'o', 'r' , 'd', '\0' };
if ( buffer == 0 )
{
*p_num_copied = sizeof(arr);
return SUCCESS;
}
if ( buff_size < sizeof(arr) )
{
*p_num_copied = sizeof(arr);
return BUFFER_TOO_SMALL;
}
memcpy( buffer, arr, sizeof(arr) );
*p_num_copied = sizeof( arr );
return SUCCESS;
}
Преимущество метода # 2 заключается в том, что вызывающая сторона во многих случаях может выделять буфер в стеке, особенно если вы объявляете максимальный требуемый размер буфера. Еще одним преимуществом является то, что управление памятью теперь полностью обрабатывается клиентом. В библиотеке общего назначения вы не хотите создавать клиента в зависимости от конкретной схемы распределения памяти библиотеки.
В ответ на комментарий
Если вы всегда хотите использовать выделенное значение в своем клиентском коде, то я бы так и сделал:
char* clientGetPasswordFromLibrary( )
{
// in our day and age it's fine to allocate this much on stack
char buffer[256];
size_t num_copied;
int status = getMyPassword( buffer, sizeof(buffer), &num_copied );
char* ret_val = NULL;
if ( status == BUFFER_TOO_SMALL )
{
ret_val = malloc( num_copied );
if ( ret_val == NULL )
{
return NULL;
}
getMyPassword( ret_val, num_copied, &num_copied );
}
else
{
ret_val = malloc( num_copied );
if ( ret_val == NULL )
{
return NULL;
}
memcpy( ret_val, buffer, num_copied );
}
return ret_val;
}