2407d,让d的printf安全

原文

理念

printf是个非常有用的构造.它可能是有史以来最多优化和调试函数.但是,因为它可能按不安全方式使用,它不能在@safeD代码中使用.

添加检查与其相应的格式限定符不匹配的参数,可缓解其中的许多问题.该提案解决剩余的问题,并使printf@safe代码中可用.

理由

printf是一个有许多优点主力函数:
1,它可能是有史以来优化和调试最多的非平凡函数.
2,它非常轻量,因为生成最少的代码调用它
3,无其他依赖,也可工作,比如将D移植到新平台
4,无需d运行时Phobos即可工作
5,在BetterC模式下工作
6,这是周知

但是,它有个不安全的接口.D正在朝着默认安全的方向发展,这就使得使用printf很笨拙.在调用前加上debug可在@safe代码中接受printf调用,但是当在非调试版本中需要printf时,这不管用.

printf不安全问题是:
1,参数格式限定符不匹配.编译器检查这些不匹配可缓解它
2,%s参数指向串的指针.虽然只能读取串,但指针仍无限制遍历串.

3,%.s参数带(int,char)形式的参数.整数是要打印的符数,但<=0值有不安全的行为.
4,格式串不是字面,编译器无法检查它.

这些是可修复的问题,或可限制它,来让它内存安全.

描述

仅当格式串串字面时,才会有效.

重写%s格式限定符

目前,编译器根据参数类型检查格式限定符.如果有不匹配,则诊断错误.如果格式限定符%s,则此建议,重写格式限定符匹配参数类型.

如果格式限定符%s,且相应参数charwchar_tD数组,则用%.*s(或%.*ls)替换格式,且用以下形式两个参数替换参数:

cast(int)argument.length & 0x7FFF_FFFF, argument.ptr

此掩码确保长度.*s安全工作的区间内.如果实际长度超过0x7FFF_FFFF,则截断整个串输出,但至少它是内存安全.

Sprintf,fprintf,snprintf

DIP适合标有pragma(printf)@safe@trusted函数.

重大更改和弃用

没有已知的重大更改.

接着

PB:此时,我发现令人反感的是(a),是用一堆编译器内部重写来实现的更好的接口,而不是普通的D代码;(b)它掩盖了现有Cprintf函数,而不是与它并存.

这是printf上面的简单包装.考虑:

printf("%s\n", 3);

这崩溃导致C程序.目前,对D,将报错.根据该提案,如下重写它:

printf("%d\n", 3);

重写只会针对%s格式限定符.
对以下内容:

char* s;
printf("%s\n", s);

不会重写,但该调用不安全:

char[] s;
printf("%s\n", s);

目前编译器拒绝它.根据该提案,如下重写它:

char[] s;
printf("%.*s\n", cast(int)s.length & 0x7FFF_FFFF);

这将使它安全.

我想不出该提案让printf现有用法不可用.如果有,则有解决方法:
1.对格式使用变量而不是串字面:

char* fmt = "hello %s!\n";
printf(fmt, "betty");

2.此行为是由按"pragma(printf)"标记的函数触发的.如果不想要它,就不要这样.或按如下声明printf:

extern (C) int printf(const(char)*, ...);

:如果需要个更安全的DMDprintf,它不会有Phoboswritef的所有臃肿和包袱,则,让我们写一个.但是,用普通D编写它并在普通D模块中放置它,而不是在用户背后悄悄重定义printf.

对我们来说,添加printf检查参数代码是个无可挑剔的胜利.CC++编译器似乎也在添加它.这只是个小小的改进.

相关推荐

  1. 2407d,dprintf安全

    2024-07-17 11:48:04       30 阅读
  2. 2401d,d导入C问题

    2024-07-17 11:48:04       59 阅读
  3. 2402d,d静态构造器

    2024-07-17 11:48:04       45 阅读
  4. 2402d,d变量2

    2024-07-17 11:48:04       49 阅读
  5. 2404d,d语言1月会议

    2024-07-17 11:48:04       31 阅读
  6. 2401d,ddip1027如何支持sql

    2024-07-17 11:48:04       48 阅读
  7. 2406,D2024年二月会议

    2024-07-17 11:48:04       25 阅读
  8. 2403d,d语言直接利用llama.cpp

    2024-07-17 11:48:04       36 阅读
  9. 2404d,d取参数标识元组

    2024-07-17 11:48:04       34 阅读
  10. 2403d,无串插件传播uda

    2024-07-17 11:48:04       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 11:48:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 11:48:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 11:48:04       57 阅读
  4. Python语言-面向对象

    2024-07-17 11:48:04       68 阅读

热门阅读

  1. 【python】python装饰器整理

    2024-07-17 11:48:04       20 阅读
  2. 金豺狼优化算法(GWO)及其Python和MATLAB实现

    2024-07-17 11:48:04       25 阅读
  3. ChatGPT等模型SQL优化提示词

    2024-07-17 11:48:04       23 阅读
  4. 使用mysql shell搭建MGR

    2024-07-17 11:48:04       25 阅读
  5. 工作常用sql 总结-长期更新

    2024-07-17 11:48:04       17 阅读
  6. 基于深度学习的游戏AI

    2024-07-17 11:48:04       21 阅读
  7. Linux Kernel 6.10 释出

    2024-07-17 11:48:04       17 阅读
  8. Django跨域问题解决

    2024-07-17 11:48:04       19 阅读
  9. layui 监听弹窗关闭并刷新父级table

    2024-07-17 11:48:04       17 阅读
  10. 【Linux】基本指令

    2024-07-17 11:48:04       21 阅读
  11. Linux内存从0到1学习笔记(8.19 ION简介)---更新中

    2024-07-17 11:48:04       20 阅读
  12. D4:知识蒸馏

    2024-07-17 11:48:04       22 阅读
  13. SVN常用命令

    2024-07-17 11:48:04       22 阅读