strcpy与strncpy的安全版本

2024-03-02 06:08
文章标签 安全 版本 strcpy strncpy

本文主要是介绍strcpy与strncpy的安全版本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

char* src = new char[10];

memset(src, 1, 10);

char* dest = new char[20];

strcpy(dest, src);

在这个例子中,我们不容易发现strcpy这个语句中有Bug。因为src没有休止符。

目前公司的做法是采用codescan工具找出strcpy,并使用strncpy代替。但实际上,这种方法也不是安全的做法。strcpy之所以不安全是由于接口本身的bug,strncpy可以再某种程度上避免strcpy所带来的缺陷。但strncpy任然不是安全的。因为有可能出现目标指针的字节数不足存放源指针所指向的内容。

如:

char* src = "hello world!";

char* dest = new char[10];

strncpy(dest, src, strlen(src)); // 这里有bug

目前对于strcpy,strncpy,从VS2005开始已经推出相应的安全版本:

接口的定义改变如下:

char* strcpy(char* dest, const char* src) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src)

char* strcpy(char* dest, const char* src, size_t count) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src, size_t count)

后者之所以比前者安全,是因为他们在接口增加了一个参数numElems来表明dest中的字节数,防止目标指针dest中的空间不够而导致出现Bug,同时返回值改成返回错误代码,而不是为了一些所谓的方便而返回char*。这样接口的定义就比原来安全很多。

所以我们应该把strcpy改成strncpy_s。这样会更为安全。

最后总结下:

接口的定义往往很重要。但同时也有一些相应的规范。如:

1)在接口中,如果出现需要修改的目标指针,需要增加相应的可存放字节数。

2)接口一般返回int(errno_t实际上就是int),这样可以标志返回错误类型。(注:在使用异常的环境下则不同,一般不返回。还有在一些比较特殊的情况下直接返回我们想要的类型。)

这篇关于strcpy与strncpy的安全版本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/765149

相关文章

springboot3.4和mybatis plus的版本问题的解决

《springboot3.4和mybatisplus的版本问题的解决》本文主要介绍了springboot3.4和mybatisplus的版本问题的解决,主要由于SpringBoot3.4与MyBat... 报错1:spring-boot-starter/3.4.0/spring-boot-starter-

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

golang1.23版本之前 Timer Reset方法无法正确使用

《golang1.23版本之前TimerReset方法无法正确使用》在Go1.23之前,使用`time.Reset`函数时需要先调用`Stop`并明确从timer的channel中抽取出东西,以避... 目录golang1.23 之前 Reset ​到底有什么问题golang1.23 之前到底应该如何正确的

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Debian如何查看系统版本? 7种轻松查看Debian版本信息的实用方法

《Debian如何查看系统版本?7种轻松查看Debian版本信息的实用方法》Debian是一个广泛使用的Linux发行版,用户有时需要查看其版本信息以进行系统管理、故障排除或兼容性检查,在Debia... 作为最受欢迎的 linux 发行版之一,Debian 的版本信息在日常使用和系统维护中起着至关重要的作

你的华为手机升级了吗? 鸿蒙NEXT多连推5.0.123版本变化颇多

《你的华为手机升级了吗?鸿蒙NEXT多连推5.0.123版本变化颇多》现在的手机系统更新可不仅仅是修修补补那么简单了,华为手机的鸿蒙系统最近可是动作频频,给用户们带来了不少惊喜... 为了让用户的使用体验变得很好,华为手机不仅发布了一系列给力的新机,还在操作系统方面进行了疯狂的发力。尤其是近期,不仅鸿蒙O

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入