Meh*_*dad 28 c security strtok
strtok我需要注意哪些特性是不安全的(在缓冲区溢出方面)?
对我来说有点奇怪的是strtok_s(在Visual C++中它是"安全的")有一个额外的"上下文"参数,但看起来它在其他方面是相同的......它是相同的,还是它实际上是不同的?
Hei*_*bug 24
根据本文档的strtok_s部分:
6.7.3.1 strtok_s函数strtok_s函数修复了strtok函数中的两个问题:
- 新参数s1max可防止strtok_s存储在被标记化的字符串之外.(被分为标记的字符串既是函数的输入也是输出,因为strtok_s将空字符存储到字符串中.)
- 新参数ptr消除了阻止strtok重入的静态内部状态(子条款1.1.12).(ISO/IEC 9899函数wcstok和ISO/IEC 9945(POSIX)函数strtok_r完全解决了这个问题.)
Bob*_*Bob 13
没有什么不安全的.您只需要了解它是如何工作的以及如何使用它.在编写代码和单元测试之后,只需花费几分钟的时间就可以使用valgrind重新运行单元测试,以确保使用内存限制.手册页说明了一切:
BUGS
使用这些功能时要小心.如果您确实使用它们,请注意:
- 这些函数修改了第一个参数.
- 这些函数不能用于常量字符串.
- 分隔字符的标识丢失了.
- 该
strtok()函数在解析时使用静态缓冲区,因此它不是线程安全的.使用strtok_r(),如果这对你很重要.
在Visual C ++中,strtok是安全的(但无处不在),因为它使用线程本地存储来保存两次调用之间的状态。在其他任何地方,全局变量都用于保存strtok()状态。
但是,即使在strtok是线程安全的VC ++中,它仍然有点怪异-您不能同时在同一线程中的不同字符串上使用strtok()。例如,这不能很好地工作:
token = strtok( string, seps );
while(token)
{
printf("token=%s\n", token)
token2 = strtok(string2, seps);
while(token2)
{
printf("token2=%s", token2);
token2 = strtok( NULL, seps );
}
token = strtok( NULL, seps );
}
Run Code Online (Sandbox Code Playgroud)
它之所以无法正常工作的原因-对于每个线程,只能在线程本地存储中保存单个状态,并且在这里一个状态将需要2个状态-第一个字符串和第二个字符串。因此,尽管strtok在VC ++中是线程安全的,但它不是可重入的。
strtok_s(或其他任何地方的strtok_r)提供的内容-显式状态,并且该strtok成为可重入的。
| 归档时间: |
|
| 查看次数: |
21781 次 |
| 最近记录: |