Какова безопасная альтернатива realpath()?
Я работаю над программой, которая использует realpath(), чтобы получить абсолютный путь к файлу. К сожалению, эта функция принимает строковый буфер, который, как ожидается, будет настолько большим, что он достаточно большой и небезопасен, когда это приложение должно работать на нескольких платформах. Есть ли безопасная версия этой функции, которая позволяет избежать проблемы с переполнением буфера, возможно, используя динамическое выделение памяти?
Ответы
Ответ 1
См. здесь информацию о безопасном и портативном использовании realpath
:
http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html
В принципе, современные стандарты позволяют передавать указатель NULL, а realpath
выделяет буфер соответствующей длины. Если вы хотите быть переносимыми в устаревшие системы, которые не поддерживают этот стандарт, просто проверьте #ifdef PATH_MAX
и используйте буфер фиксированного размера длиной PATH_MAX
. Насколько я знаю, нет устаревших систем, которым не хватает константы PATH_MAX
, но которые не поддерживают аргументы NULL для realpath
.
Ответ 2
Из man-страницы:
Если resol_path указан как NULL, тогда realpath() использует malloc (3) для размещения буфера до PATH_MAX байты для хранения разрешенного пути, и возвращает указатель на этот буфер. Вызывающий должен освободить эту буфер с использованием бесплатного (3) буфера с использованием бесплатного (3).
Итак, похоже, вы можете просто сделать это:
char *real_path = realpath(path, NULL);
// use real_path
free(real_path);
Ответ 3
Есть способ сделать то же самое в Boost, используя boost:: filesystem:
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
try{
path absolutePath = canonical("./../xxx"); //will throw exception if file not exists!
}
catch{...}{
cout << "File not exists";
}
cout << absolutePath.string();
Есть способ QT сделать это (получен из здесь):
QFileInfo target_file_name(argv[1]);
QString absolute_path = target_file_name.absolutePath()
Существует немного сложная реализация realpath в С++. Не могу сказать ничего об этом безопасности, но он должен допускать длину пути больше, чем PATH_MAX
. Скоро начнем тестировать.