msdn对pathappend介绍的开头就有一句话说误用该接口会导致缓冲越界,建议使用更安全的PathCchAppend 或者PathCchAppendEx接口。今天就说说几个注意点:
(1)头文件包含,一般windows编程包含windows.h就可以,但是用PathAppend就必须要添加shlwapi.h,shlwapi是啥意思,打开.h文件,第一行就是Interface for the Windows light-weight utility APIs 。windows 轻量级功能接口。网上还有一个说明Shell Light-Weight Application Programming Interface,貌似更准确。大概意思也就有数。
(2)接口的两个参数Inout LPTSTR pszPath, In LPCTSTR pszMore
对长度的限制都是MAX_PATH,那附加之后,就会超过这个范围。先说单个参数。输入参数本身如果用strcpy/_tcscpy进行,那本身就已经存在越界的风险。如果这两个子串都在栈空间上,被覆盖是很容易的事。
(3)当我用debug版本测试PathAppend时,发现如果path+more超过MAX_PATH,path就会变成空串。此时PathAppend的返回值是FALSE,所以说,有返回值的接口判断返回值是避免异常最有效的手段。但是需要注意的是此时如果通过GetLastError()获取原因时,返回值是0,同时errno也是0,当然MSDN没说可以用GLE获取,但是这也是一个值得注意的地方。如何获取失败原因?不知道。所以一定要考虑到路径拼接之后的长度,包括可能会自动添加的\加上结尾的null,一共会不会超过MAX_PATH的长度,这个很关键。
(4)第(3)点中说到超过长度,还有一个后果是pszPath会直接变成空串,当然不是把path全部置0,而是第一个字节置0。其实这也是很可能会导致严重问题的设计,还是那句话,要判断返回值 ,不判断那是你的问题,接口不告诉你那是接口的问题。
(5)后来发现(3)(4)说的有问题,如果more参数是空串,那么path是不会置为空串的,而是把path截断为MAX_PATH-1的长度。同事more是空串在路径拼接的时候,也不会自动加斜杠。如果你无法指望用char path[MAX_PATH] = "c:\\test"; PathAppend(path, "");
来把c:\test变成c:\test\。
相关文章
- Java基础知识点(类的几个补充注意事项和private关键字)
- Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点
- 用Eclipse导出jar包时注意点
- Spring.Net封闭业务类为WebService注意点和问题
- Stanford CS231n实践笔记(课时22卷积神经网络工程实践技巧与注意点 cnn in practise 上)
- C++11 shared_ptr, weak_ptr速成,以及放在stl集合类里面的注意点。
- python操作字符串类型json的注意点
- Android 开发相关注意点
- java 获取类路劲注意点
- 【Mac使用基础】如何在mac上搭建MAMP,Macport 使用注意点,Macport报错