什么是realpath()的安全替代方案?

时间:2022-06-28 16:04:33

I am working on a program which uses realpath() to get the absolute path of a file. Unfortunately, this function takes a string buffer that is expected to be so large that it is big enough and that's not safe when this application has to run across multiple platforms. Is there a safe version of this function which avoids the buffer overflow issue, perhaps using dynamic memory allocation?

我正在开发一个程序,它使用realpath()获取文件的绝对路径。不幸的是,这个函数使用了一个字符串缓冲区,这个缓冲区预期会非常大,以至于足够大,当这个应用程序必须在多个平台上运行时,这是不安全的。这个函数是否有一个安全版本可以避免缓冲区溢出问题,也许可以使用动态内存分配?

3 个解决方案

#1


18  

See here for information on safe and portable use of realpath:

有关realpath的安全性和可移植性使用信息,请参阅这里:

http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html

http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html

Basically, modern standards allow you to pass a NULL pointer, and realpath will allocate a buffer of the appropriate length. If you want to be portable to legacy systems which do not support this standard, simply check #ifdef PATH_MAX and use a fixed-size buffer of length PATH_MAX. As far as I know, there are no legacy systems that lack a constant PATH_MAX but which do not support NULL arguments to realpath.

基本上,现代标准允许您传递一个空指针,而realpath将分配一个适当长度的缓冲区。如果您想要移植到不支持此标准的遗留系统,只需检查#ifdef PATH_MAX并使用长度为PATH_MAX的固定大小缓冲区。据我所知,没有遗留系统缺少一个常量PATH_MAX,但是它不支持对realpath的空参数。

#2


13  

From the manpage:

从:

If resolved_path is specified as NULL, then realpath() uses malloc(3) to allocate a buffer of up to PATH_MAX bytes to hold the resolved pathname, and returns a pointer to this buffer. The caller should deallocate this buffer using free(3).buffer using free(3).

如果resolved_path被指定为NULL,那么realpath()使用malloc(3)分配一个最多为PATH_MAX字节的缓冲区来保存解析后的路径名,并返回一个指向该缓冲区的指针。调用者应该使用free(3)来释放这个缓冲区。缓冲区使用免费(3)。

So it seems like you can just do this:

看起来你可以这么做:

char *real_path = realpath(path, NULL);
// use real_path
free(real_path);

#3


2  

There is a way to do the same in Boost using boost::filesystem:

在使用Boost时,也有一种方法可以做到这一点:文件系统:

#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(); 

There is QT way to do it (got from here):

有QT方法(从这里得到):

QFileInfo target_file_name(argv[1]);
QString absolute_path = target_file_name.absolutePath() 

There is a bit complicated implementation of realpath in C++. Cannot tell anything about it's safety, but it should allow path with length more then PATH_MAX. Going to test it soon.

c++中的realpath实现有点复杂。不能说明它的安全性,但它应该允许路径长度更大,然后是PATH_MAX。很快就要进行测试了。

#1


18  

See here for information on safe and portable use of realpath:

有关realpath的安全性和可移植性使用信息,请参阅这里:

http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html

http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html

Basically, modern standards allow you to pass a NULL pointer, and realpath will allocate a buffer of the appropriate length. If you want to be portable to legacy systems which do not support this standard, simply check #ifdef PATH_MAX and use a fixed-size buffer of length PATH_MAX. As far as I know, there are no legacy systems that lack a constant PATH_MAX but which do not support NULL arguments to realpath.

基本上,现代标准允许您传递一个空指针,而realpath将分配一个适当长度的缓冲区。如果您想要移植到不支持此标准的遗留系统,只需检查#ifdef PATH_MAX并使用长度为PATH_MAX的固定大小缓冲区。据我所知,没有遗留系统缺少一个常量PATH_MAX,但是它不支持对realpath的空参数。

#2


13  

From the manpage:

从:

If resolved_path is specified as NULL, then realpath() uses malloc(3) to allocate a buffer of up to PATH_MAX bytes to hold the resolved pathname, and returns a pointer to this buffer. The caller should deallocate this buffer using free(3).buffer using free(3).

如果resolved_path被指定为NULL,那么realpath()使用malloc(3)分配一个最多为PATH_MAX字节的缓冲区来保存解析后的路径名,并返回一个指向该缓冲区的指针。调用者应该使用free(3)来释放这个缓冲区。缓冲区使用免费(3)。

So it seems like you can just do this:

看起来你可以这么做:

char *real_path = realpath(path, NULL);
// use real_path
free(real_path);

#3


2  

There is a way to do the same in Boost using boost::filesystem:

在使用Boost时,也有一种方法可以做到这一点:文件系统:

#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(); 

There is QT way to do it (got from here):

有QT方法(从这里得到):

QFileInfo target_file_name(argv[1]);
QString absolute_path = target_file_name.absolutePath() 

There is a bit complicated implementation of realpath in C++. Cannot tell anything about it's safety, but it should allow path with length more then PATH_MAX. Going to test it soon.

c++中的realpath实现有点复杂。不能说明它的安全性,但它应该允许路径长度更大,然后是PATH_MAX。很快就要进行测试了。