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

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值