coding习惯 + Bug记录整理

发布于:2025-06-20 ⋅ 阅读:(19) ⋅ 点赞:(0)

整理些平时不好的coding习惯导致的bug📝

1、包装类型导致的NPE

处理项目的一个bug,看日志是发生了空指针,相关代码如下:

@Data
public class Dto {

	private Integer offset;

	private Integer limit;
	
}
if (dto.getLimit() < 0 || dto.getLimit() > 100) {
	throw new RuntimeException("参数非法");
}

这里对外API文档写的offset和limit有默认值0和20,但实际代码里并未赋值,这里用的是int的包装类,不传时,默认值为null,而下面 < 0 的比较,会触发自动拆箱,调用Integer对象的intValue()方法,因此,空指针

2、xxApiWrapper命名

发现一个类命名的单词,wrapper,用它结尾命名一个封装📦类,很不错

在这里插入图片描述

/**
 * 封装调用xx系统的API
 */
public class ServiceApiWrapper {

}

3、@see注释

有时候,一些字段是枚举类型,但Dto类中我们更想用String,此时,可以@see 跟一个全类名,方便点击跳转到对应的类上:

/**
 * @see com.llg.common.SourceTypeEnum
 */
private String sourceType;

4、MySQL模糊匹配特殊字符bug

用户反馈有个模糊查询,输入_下划线,返回的有带-中划线的结果,debug到对应位置的代码:

criteria.andCondition("upper(group_id) like upper('%" + searchKey + "%')");

这里很明显是用户输入的下划线被当成通配符了,作用是匹配单个字符,对于这种情况,要考虑两个点:

  • SQL注入
  • 特殊字符
字符 类型 含义
% 通配符 匹配任意数量字符(包括0个)
_ 通配符 匹配单个字符
\ 转义符 取消后续字符的特殊含义

永远不要直接拼接用户输入到你的SQL中,对于特殊字符,用这个工具类处理一下,加转义符,取消后面字符的特殊含义:

public class SqlUtil {
    // https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#operator_like
    public static String escapeLikeValue(String value) {
        if (value == null) {
            return null;
        }
        return value
                .replace("\\", "\\\\")
                .replace("%", "\\%")
                .replace("_", "\\_");
    }
}

对于SQL注入,其实最好的就是预处理,SQL模板化,让SQL和传入的值分开,但这里项目用了tk mybatis框架,考虑加个正则表达式拦一下,能解决一部分,但并不是最优解:

private static final Pattern RISK_SQL = Pattern.compile("[\\s#/*'\"]");
if (RISK_SQL.matcher(searchKey).find()) {
	throw new RuntimeException("输入非法");
}

但这么改其实漏洞🕳️也不少,比如union 或者结束; 搭配Drop table等等:

SELECT * FROM users WHERE id = 1 UNION SELECT password FROM users
'); DROP TABLE x; --

总之,这种拼接SQL的,要特别注意SQL注入导致数据泄漏或者数据被删的问题。


网站公告

今日签到

点亮在社区的每一天
去签到