• 发生时间:2024-03-01

  • 问题描述:

    • 开发完服务端的安装包下载的新需求后,我开始在本地验证该功能。
    • 我随意上传了本地电脑的 Downloads 目录下的一个名为 BMAPI+SDK.v1.10.1.29.1231.zip 的文件到 maker 本地测试环境,然后查询该文件的信息。
    • 查询时,maker 返回错误信息:record not found
  • 问题类别:软件开发

  • 原因分析:

    • 查看本地测试环境的日志,确认查询请求的参数是正确的。
    • 登录本地测试环境的服务器,确认对应的文件确实已经上传到数据库,文件名也是正确的。
    • 在网上搜索资料时,看到有人提到:使用 GORM 时,在 db.Where 语句中插入 Debug 方法就能打印对应的底层 SQL 语句,于是如法炮制。
    • 修改代码后,重新编译运行,发现对应的底层 SQL 语句是:SELECT * FROM preparation_package WHERE name = 'BMAPI SDK.v1.10.1.29.1231.zip'
    • 可以看到,文件名中的加号(BMAPI 后面紧跟着的加号)被替换为空格了!
    • 查阅 GORM 官方文档,找到原因:GORM 为了避免 SQL 注入,会将查询参数里的特殊字符(比如加号、分号等)转义!
  • 解决方案:

    • 采取同事的建议,服务端对上传的文件名进行校验,如发现特殊字符则返回「非法输入」的错误。同时在文档中说明上传的文件名不能包含特殊字符。
  • 实施结果:

    • 上传名字中包含特殊字符的文件时,服务器会返回错误;上传名字中不含有特殊字符的文件后,能够正常查询到其文件信息。
  • 经验总结:

    • GORM 为了避免 SQL 注入,会将查询参数里的特殊字符(比如加号、分号等)转义!
    • 定位问题时,最好找到办法打印更多信息。比如 GORM 可以使用 Debug 函数打印底层 SQL 语句。