代码精进之路
范学雷
Oracle首席软件工程师,Java SE安全组成员,OpenJDK评审成员
立即订阅
6350 人已学习
课程目录
已完结 47 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 你写的每一行代码,都是你的名片
免费
第一模块:代码“规范”篇 (16讲)
01 | 从条件运算符说起,反思什么是好代码
02 | 把错误关在笼子里的五道关卡
03 | 优秀程序员的六个关键特质
04 | 代码规范的价值:复盘苹果公司的GoToFail漏洞
05 | 经验总结:如何给你的代码起好名字?
06 | 代码整理的关键逻辑和最佳案例
07 | 写好注释,真的是小菜一碟吗?
08 | 写好声明的“八项纪律”
09 | 怎么用好Java注解?
10 | 异常处理都有哪些陷阱?
11 | 组织好代码段,让人对它“一见钟情”
12丨组织好代码文件,要有“用户思维”
13 | 接口规范,是协作的合约
14 | 怎么写好用户指南?
15 | 编写规范代码的检查清单
16丨代码“规范”篇用户答疑
第二模块:代码“经济”篇 (14讲)
17 | 为什么需要经济的代码?
18丨思考框架:什么样的代码才是高效的代码?
19 | 怎么避免过度设计?
20 | 简单和直观,是永恒的解决方案
21 | 怎么设计一个简单又直观的接口?
22丨高效率,从超越线程同步开始!
23 | 怎么减少内存使用,减轻内存管理负担?
24 | 黑白灰,理解延迟分配的两面性
25 | 使用有序的代码,调动异步的事件
26 | 有哪些招惹麻烦的性能陷阱?
27 | 怎么编写可持续发展的代码?
28 | 怎么尽量“不写”代码?
29 | 编写经济代码的检查清单
30丨“代码经济篇”答疑汇总
第三模块:代码“安全”篇 (14讲)
31 | 为什么安全的代码这么重要?
32 | 如何评估代码的安全缺陷?
33 | 整数的运算有哪些安全威胁?
34 | 数组和集合,可变量的安全陷阱
35 | 怎么处理敏感信息?
36 | 继承有什么安全缺陷?
37 | 边界,信任的分水岭
38 | 对象序列化的危害有多大?
39 | 怎么控制好代码的权力?
40 | 规范,代码长治久安的基础
41 | 预案,代码的主动风险管理
42 | 纵深,代码安全的深度防御
43 | 编写安全代码的最佳实践清单
44 | “代码安全篇”答疑汇总
加餐 (1讲)
Q&A加餐丨关于代码质量,你关心的那些事儿
结束语 (1讲)
结束语|如何成为一个编程好手?
代码精进之路
登录|注册

40 | 规范,代码长治久安的基础

范学雷 2019-04-05
如果从安全角度去考察,软件是非常脆弱的。今天还是安全的代码,明天可能就有人发现漏洞。安全攻击的问题,大部分出自信息的不对称性;而维护代码安全之所以难,大部分是因为安全问题是不可预见的。那么,该怎么保持代码的长治久安呢?

评审案例

有些函数或者接口,可能在我们刚开始写程序的时候,就已经接触,了解,甚至熟知了它们,比如说 C 语言的 read() 函数、Java 语言的 InputStream.read() 方法。我一点都不怀疑,我们熟知这些函数或接口的规范。比如说,C 语言的 read() 函数在什么情况下返回值为 0? InputStream.read() 方法在什么情况下返回值为 -1?
我知道,我们用错 read() 的概率很小。但是今天,我要和你讨论一两个不太常见,且非常有趣,的错误的用法。
让我们一起来看几段节选改编的 C 代码,代码中的 socket 表示网络连接的套接字文件描述符(file descriptor)。 你能够找到这些代码里潜在的问题吗?
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
void clientHello(int socket) {
char buffer[1024];
char* hello = "Hello from client!";
send(socket, hello, strlen(hello), 0);
printf("Hello message sent\n");
int n = read(socket, buffer, 1024);
printf("%s\n", buffer);
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
void serverHello(int socket) {
char buffer[1024];
char* hello = "Hello from server!";
int n = read(socket, buffer, 1024);
printf("%s\n", buffer);
send(socket, hello, strlen(hello), 0);
printf("Hello message sent\n");
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
void serverHello(int socket) {
char buffer[1024];
char* hello = "Hello from server!";
int n = read(socket, buffer, 1024);
if (n == 0) {
close(socket);
} else {
printf("%s\n", buffer);
send(socket, hello, strlen(hello), 0);
printf("Hello message sent\n");
}
}
现在,我们集中寻找 read() 函数返回值的使用问题。为了方便你分析,我把一个标准的 read() 函数返回值的规范摘抄如下:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《代码精进之路》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(3)

  • hua168
    像我们开发是直接调用框架函数,如果是安全问题,一般是框架自身的问题吧?

    作者回复: 一般不是框架自身的问题。

    2019-04-08
    3
  • 丁丁历险记
    由衷的感谢ie 退场。让it 文明得以更好的发展。(此处省略5000字的脏话)
    2019-10-16
    2
  • 我来也
    我还是只懂c语言。我觉得比较奇怪,buffer的长度是1024,read 1024没问题,但是printf(%s)时,如果最后一个字节不是\0,那输出就会有问题了。

    作者回复: 哈哈,buffer不是字符串,printf打印的是字符串,所以问题就来了。

    2019-04-06
    2
收起评论
3
返回
顶部