[C.C++] C语言中conversion用法,C语言类型转换(type conversions in C)

900 0
Honkers 2025-7-30 03:07:38 | 显示全部楼层 |阅读模式

java/C++这类语言对类型的要求非常严格,但是C语言对类型几乎没什么限制.

它可以非常灵活的处理不同类型之间的转换.

正因为它的这种灵活性,也导致了程序员在使用各种混合的数据类型时,并不关心这些类型混用带来的危害.

往往这些细节引起大量软件漏洞.降低了软件的安全性,而且使维护成本增高.

这也是C语言编写的程序饱受诟病的原因之一吧.

先说说整数类型转换情况:

0.从一个窄的无符号类型,转换到一个宽的有符号类型.值保留不会改变.( 比如unsigned short --> int)

这个很简单,因为更宽的有符号类型总能容纳下比它窄的类型.哪怕是无符号数.

1.从一个窄的有符号类型,转换到一个宽的无符号类型.编译器进行符号拓展(movsx).有可能发生值改变.( 比如char -->unsigned short)

1349854653_4357.jpg

2.从一个窄的有符号类型,转换到一个宽的有符号类型.编译器进行符号拓展(movsx).转换后的值保留,不会改变.(比如short -->int)

1349854714_3788.jpg

3.从一个窄的无符号类型,转换到一个宽的无符号类型.编译器进行零拓展(movzx).转换后的值保留,不会改变.( 比如unsigned short -->unsigned int)

这个学过汇编的都知道.一条movzx指令就搞定了.

4.从一个宽类型,转换到一个窄类型.编译器进行截断.有可能发生值改变.( 比如unsigned short -->unsigned char)

1349854539_7425.jpg

5.在无符号类型和无符号类型之间转换时.他们的bit位的模式是一致的.但是有可能发生值改变.( 比如unsigned short -->short)

1349854863_7557.jpg

下面看一段有脆弱点的代码:

int read_user_data(int sockfd)

{

int length, sockfd, n;

char buffer[1024];

length = get_user_length(sockfd);

if(length > 1024){

error("illegal input, not enough room in buffer\n");

return 1;

}

if(read(sockfd, buffer, length) < 0){

error("read: %m");

return 1;

}

return 0;

}

首先get_user_length()函数从用户指定的socket取得用户数据的大小并且返回一个int类型的length.

然后根据返回的length调用read函数.读取用户数据.

注意,这里发生了一次类型转换.

length是int型.read函数原型是#include ssize_t read(int fd, void *buf, size_t count).(size_t在32位机器上定义为unsigned int)

所以这里length由singed int 转换到了 unsigned int.

但是如果用户给了一个为负值的长度.

那么read函数将读取一块很大的内存.也就产生了任意读取的bug.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行