-
#include <stdio.h>
-
-
/***
-
* strcmp compare two strings, return less than,equal to , or less than
-
*
-
* Purpose:
-
* strcmp compare two strings and return an integer
-
* to indicate whether the first less than the second,
-
* the two are squal ,or whether the first is greater than the second
-
*
-
* Comparison is done byte by byte on an unsigned basis,which is to
-
* say that Null(0) is less than any other character(1-255).
-
*
-
* Entry:
-
* const char *src - string for left-hand side of comparison
-
* const char *dst - string for right-hand side of comparison
-
* Exit:
-
* return -1 if src < dst
-
* return 0 if src == dst
-
* return +1 if src > dst
-
*/
-
-
/*
-
My Vsersion
-
*/
-
#ifdef __MY_SELF__
-
int strcmp(const char *src, const char *dst)
-
{
-
int ret = 0;
-
while ( !(ret = (unsigned int)*src - (unsigned int)*dst)
-
&& *src && *dst ) {
-
src ++;
-
dst ++;
-
}
-
if (ret > 0) {
-
ret = 1;
-
} else if (ret < 0) {
-
ret = -1;
-
}
-
return ret;
-
}
-
#else
-
/*
-
Microsoft Version
-
*/
-
int __cdecl strcmp (
-
const char * src,
-
const char * dst
-
)
-
{
-
int ret = 0 ;
-
-
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
-
++src, ++dst;
-
-
if ( ret < 0 )
-
ret = -1 ;
-
else if ( ret > 0 )
-
ret = 1 ;
-
-
return( ret );
-
}
-
#endif // __MY_SELF__
-
int main()
-
{
-
int ret = 0;
-
ret = strcmp("acvb","acv");
-
printf("#1 acvb acv res = %d\n");
-
ret = strcmp("acvb","acvb");
-
printf("#2 acvb acvb res = %d\n");
-
ret = strcmp("acb","acv");
-
printf("#3 acb acv res = %d\n");
-
ret = strcmp("acvgfgffb","acv");
-
printf("#4 acvgfgffb acv res = %d\n");
-
return 0;
-
}
上面的代码中有两个版本的strcmp,其中一个是我自己写的,主要目的是为了发现自己思考的漏洞。核心代码就是其他颜色标志出来。可以看出,30行中存在几个问题:
1.类型转换的时候应该使用unsigned char,还有在强制转换指针变量的时候,应该使用53行的方法(unsigned char *),然后在用*运算符取值,这样比较符合规范。
2.条件判断的时候,只要判断*src == 0 或者 *dst == 0就可以了,因为如果长度不同的时候,只要其中一个到达尾部,那么差值必然非0,则循环也就结束了。所以不需要同时判断两个变量是否为0.
3.使用
__cdecl关键字,显示的指明函数调用的方式,包括参数传递顺序、堆栈维护职责、名称修饰约定及大小写转换约定。
参考文献:
【1】微软C库的源码
【2】
__cdecl MSDN
阅读(1859) | 评论(0) | 转发(0) |