2013-08-05 3 views
1

Небольшая деталь попалась на глаза во время чтения документации _splitpath_s(). Он принимает путь диска пункта (например .; C: \ Temp \ MyFile.exe) в 1-м параметра, а затем делит его на диск, каталог, папку и расширение имен. Однако, странно, он запрашивает длину строкового буфера, который будет содержать имя диска в обратном направлении в своем параметре 3 rd.Почему _splitpath_s() принимает строковый буфер произвольного размера для возврата буквы диска?

Насколько я знаю, буква диска может быть только двухбуквенной строкой; письмо, за которым следует точка с запятой, например A:, B:, C: и т. д. Поэтому во всех случаях она всегда должна быть двухсимвольной. Но если да, то почему _splitpath_s() спрашивают длину буквы диска? Есть ли какой-нибудь случай, в котором письмо с буквой может быть в другом формате? Какая проблема возникла бы в худшем случае, если бы она не просила о ее длине и просто предположила, что она равна 2?

errno_t _splitpath_s(
    const char * path, 
    char * drive, 
    size_t driveNumberOfElements, 
    char * dir, 
    size_t dirNumberOfElements, 
    char * fname, 
    size_t nameNumberOfElements, 
    char * ext, 
    size_t extNumberOfElements 
); 
+0

Для согласованности? –

ответ

2

точка _s функций должна быть параноидально переполнения буфера. Поэтому все буферы должны быть связаны с размером.

Ваше предложение использовать двухсимвольную строку означает, что либо двоеточие будет опущено (что с точки зрения использования будет раздражать), либо будет означать, что строка не завершена NUL, что, вероятно, является неожиданным (особенно поскольку это будет несовместимо со всеми другими выходными параметрами, которые равны с NUL-завершением), а затем может привести к другим уязвимостям безопасности.

Даже если вы внесли изменения в свое предложение использовать буфер фиксированного размера из трех символов вместо двух, в C, объявление параметров массива для функций на самом деле ничего не делает; компилятор не будет обеспечивать, чтобы аргумент был массивом правильного размера. То есть, функция, как:

void foo(int array[3]); 

не на самом деле не отличается от:

void foo(int* array); 

Если _splitpath_s не принимают параметр driveNumberOfElements, было бы легче для абонентов случайно пройти буферы, которые слишком маленький. Хотя верно, что абоненты все еще могут это сделать в своей нынешней форме, наличие явного driveNumberOfElements параметра должно заставлять абонентов оплачивать примерно.

И, наконец, теоретически, диски когда-нибудь могут не ограничиваться отдельными символами, поэтому версия _splitpath_s, которая принимает параметр driveNumberOfElements, немного более надежна для будущего. (На практике, однако, такое изменение сломало бы много существующего кода.)

 Смежные вопросы

  • Нет связанных вопросов^_^