C++ 有没有安全的strcmp?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1623769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there any safe strcmp?
提问by P-P
I made a function like this:
我做了一个这样的功能:
bool IsSameString(char* p1, char* p2)
{
return 0 == strcmp(p1, p2);
}
The problem is that sometimes, by mistake, arguments are passed which are not strings (meaning that p1
or p2
is not terminated with a null character).
Then, strcmp
continues comparing until it reaches non-accessible memory and crashes.
Is there a safe version of strcmp
? Or can I tell whether p1
(and p2
) is a string or not in a safe manner?
问题是有时会错误地传递不是字符串的参数(意味着p1
或p2
不以空字符结尾)。然后,strcmp
继续比较,直到到达不可访问的内存并崩溃。有安全版本strcmp
吗?或者我可以以安全的方式判断p1
(和p2
)是否是字符串?
回答by Wernsey
No, there's no (standard) way to tell whether a char *
actually points to valid memory.
不,没有(标准)方法可以判断 a 是否char *
实际指向有效内存。
In your situation, it is better to use std::string
rather than char *
s for all your strings, along with the overloaded ==
operator. If you do this, the compiler would enforce type safety.
在您的情况下,最好对所有字符串使用std::string
而不是char *
s 以及重载==
运算符。如果这样做,编译器将强制执行类型安全。
EDIT:As per the comments below if you find yourself in a situation where you sometimes pass char *
s that may or may not be valid strings to functions that expect null-terminated strings then something is fundamentally wrong with your approach, so basically
@janm's answer below.
编辑:根据下面的评论,如果您发现自己有时将char *
可能是也可能不是有效字符串的 s传递给期望以空字符结尾的字符串的函数,那么您的方法从根本上就存在问题,所以基本上@janm 的回答如下.
回答by Igor Oks
In some cases std::strncmp
can solve your problem:
在某些情况下std::strncmp
可以解决您的问题:
int strncmp ( const char * str1, const char * str2, size_t num );
It compares up to num characters of the C string str1 to those of the C string str2.
它将 C 字符串 str1 的最多 num 个字符与 C 字符串 str2 的字符进行比较。
Also, take a look, what the US DHS National Cyber Security Division recommendson this matter:
另外,看看美国国土安全部国家网络安全部门对此事的建议:
Ensure that strings are null terminated before passing into strcmp. This can be enforced by always placing a \0 in the last allocated byte of the buffer.
确保字符串在传入 strcmp 之前以空字符结尾。这可以通过始终在缓冲区的最后分配字节中放置 \0 来强制执行。
char str1[] ="something";
char str2[] = "another thing";
/* In this case we know strings are null terminated. Pretend we don't. */
str1[sizeof(str1)-1] = 'struct MyString
{
MyString() : str(0), len(0) {}
MyString( char* x ) { len = strlen(x); str = strdup(x); }
?MyString() { if(str) free(str); }
char* str;
size_t len;
};
bool IsSameString(MyString& p1, MyString& p2)
{
return 0 == strcmp(p1.str, p2.str);
}
MyString str1("test");
MyString str2("test");
if( IsSameString( str1, str2 ) {}
';
str2[sizeof(str2)-1] = '##代码##';
/* Now the following is safe. */
if (strcmp(str1, str2)) { /* do something */ } else { /* do something else */ }
回答by janm
If you are passing strings to strcmp() that are not null terminated you have already lost. The fact that you have a string that is not null terminated (but should be) indicates that you have deeper issues in your code. You cannot change strcmp() to safely deal with this problem.
如果您向 strcmp() 传递非空终止的字符串,则您已经丢失了。您有一个不是空终止(但应该是)的字符串这一事实表明您的代码中存在更深层次的问题。您不能更改 strcmp() 来安全地处理此问题。
You should be writing your code so that can never happen. Start by using the string class. At the boundaries where you take data into your code you need to make sure you deal with the exceptional cases; if you get too much data you need to Do The Right Thing. That does not involve running off the end of your buffer. If you must perform I/O into a C style buffer, use functions where you specify the length of the buffer and detect and deal with cases where the buffer is not large enough at that point.
你应该编写你的代码,这样就永远不会发生。首先使用字符串类。在将数据带入代码的边界处,您需要确保处理异常情况;如果您获得太多数据,您需要做正确的事情。这不涉及跑掉缓冲区的末尾。如果必须对 C 样式缓冲区执行 I/O,请使用指定缓冲区长度的函数,并检测和处理此时缓冲区不够大的情况。
回答by sharptooth
There's no cure for this that is portable. The convention states that there's an extra character holding a null character that belongs to the same correctly allocated block of memory as the string itself. Either this convention is followed and everything's fine or undefined behaviour occurs.
没有办法治愈这种便携性。约定指出,有一个额外的字符包含一个空字符,该字符与字符串本身属于同一个正确分配的内存块。要么遵循此约定,要么发生一切正常或未定义的行为。
If you know the length of the string you compare against you can use strncmp()
but his will not help if the string passed to your code is actually shorter than the string you compare against.
如果您知道与您比较的字符串的长度,您可以使用,strncmp()
但如果传递给您的代码的字符串实际上比您比较的字符串短,他将无济于事。
回答by Satbir
you can use strncmp, But if possible use std::string to avoid many problems :)
您可以使用 strncmp,但如果可能,请使用 std::string 来避免许多问题:)
回答by Paolo Tedesco
回答by David Allan Finch
There is no best answer to this as you can't verify the char* is a string. The only solution is to create a type and use it for string for example str::string or create your own if you want something lighter. ie
对此没有最佳答案,因为您无法验证 char* 是字符串。唯一的解决方案是创建一个类型并将其用于字符串,例如 str::string 或者如果您想要更轻的东西,则创建自己的类型。IE
##代码##回答by RED SOFT ADAIR
You dont write, what platform you are using. Windows has the following functions:
你不写,你用的是什么平台。Windows 具有以下功能:
IsBadStringPtr
might be what you are looking for, if you are using windows.
IsBadStringPtr
如果您使用的是windows,可能就是您要找的东西。