• 你的sprintf安全吗?


    使用snprintf也是不安全的。sprintf、snprintf都无法处理常见的 len += sprintf() 的场景,常常会导致bug。

    windows下更糟糕,snprintf不保证'\0'结尾。

    所以,我们需要一个更安全的sprintf。(nginx也意识到了类似的问题,因此在实现ngx_sprintf的时对接口做了类似的调整)


    声明:

    //return 0 on fail. return result length on success (may truncate).
    //we consider '-1' as a dangerous return value that may cause a lot of bugs.
    //'buf' will always ended with '\0', and return value will always be length of the result.
    //it's safe to use like: len += safe_sprintf(buf+len, buf_size-len, fmt, ....)
    int safe_sprintf(char* buf, int buf_size, char* fmt, ...)
                         __attribute__ ((__format__ (__printf__, 3, 4)));

    实现:

    int safe_sprintf(char* buf, int buf_size, char* fmt, ...)
    {
    	if (buf == NULL || buf_size <= 0) {
    		return 0;
    	}
    
    	va_list ap;
    	va_start(ap, fmt);
    	int res = vsnprintf(buf, buf_size, fmt, ap);
    	va_end(ap);
    
    	if (res == -1) {
    		buf[0] = '\0';
    		return 0;
    	}
    
    	if (res >= buf_size) {
    		res = buf_size - 1;
    		buf[res] = '\0';
    	}
    
    	return res;
    }

    注意:linux版的vsnprintf能保证'\0'结尾,windows版的vsnprintf不能保证'\0'结尾。其他平台的vsnprintf能否保证'\0'结尾未知。为了确保在所有平台上是安全的,我在赋零的时候未区分平台。都已经sprintf了,就不要想太多性能的事情了。


  • 相关阅读:
    名字空间,L,E, G , B 作用域, 内置电池
    lambda表达式
    表达式与声明的区别。
    jupyter book的使用
    centos7一键安装cacti_1.2.16版本
    docker修改阿里云镜像加速器
    centos单网卡多ip,被动模式
    centos同步时间
    centos7.x制作bond
    centos 6.X制作bond
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330362.html
Copyright © 2020-2023  润新知