惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
V
Vulnerabilities – Threatpost
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
Y
Y Combinator Blog
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
MyScale Blog
MyScale Blog
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
量子位
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
C
Cybersecurity and Infrastructure Security Agency CISA
L
Lohrmann on Cybersecurity
L
LINUX DO - 最新话题
The Register - Security
The Register - Security
T
Tailwind CSS Blog
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
T
Troy Hunt's Blog
Stack Overflow Blog
Stack Overflow Blog
Cloudbric
Cloudbric
S
Secure Thoughts
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
L
LangChain Blog
Recorded Future
Recorded Future
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Tor Project blog
人人都是产品经理
人人都是产品经理
F
Full Disclosure
O
OpenAI News
Webroot Blog
Webroot Blog
A
Arctic Wolf
TaoSecurity Blog
TaoSecurity Blog
P
Privacy & Cybersecurity Law Blog
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
H
Heimdal Security Blog
B
Blog RSS Feed
Vercel News
Vercel News

叶落阁

叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁 叶落阁
叶落阁
叶落阁 · 2024-09-30 · via 叶落阁

前言

最近同事在接入西班牙语的数据时, 发现了一个问题, 涉及到西班牙语中包含重音符号的数据比对出了问题, 同事已经找出可能是字符串规范化(Normalize)的问题, 但是现象很奇怪, 今天就做了一些测试, 将测试结果记录下来. 以供大家参考.

常用规范化:

  • NFC: 规范化组合型, 如 é 是一个字符
  • NFD: 规范化分解型, 如 é 是两个字符 e´
  • NFKC: 兼容性规范化组合型
  • NFKD: 兼容性规范化分解型

先说结论

在 HTML/JavasCript/Java/PostGreSQL 中, 不会自动对字符串的规范话进行转换, 也就是说, 从前端(html/js)传递到后端(java), 再传递到数据库(PostGreSQL)的过程中, 字符串的规范化是不变的, 所以只是文字传递, 不会出现问题.

出问题的地方是文件系统:

  • Windows 文件系统(如 NTFS)通常使用 NFC 形式存储文件名。
  • macOS 文件系统(如 HFS+ 或 APFS)通常使用 NFD 形式存储文件名。
  • Linux 文件系统(如 ext4)通常使用 NFC,但这也可能因环境和设置而异。

导致上传文件时, 文件名的规范化不一致, 会导致文件名比对是不一致的.

问题现象

同名的文件名上传时, 会进入数据库比对一下文件名是否存在, 但是由于文件名的规范化不一致, 会导致文件名比对不一致. 从而重复上传文件.

比如我们做一个简单的测试, 如下代码, 页面上有两个元素, 一个文本输入框, 一个文件上传框, 当文件上传框选择文件后, 会比对文件名和文本输入框的值是否一致, 如果不一致, 则提示文件名不一致.

我们在本地新建一个文件, 文件名为 é.txt, 这个文件名的文本是 NFC 的形式, 当 MacOS 去页面上传文件, 会提示文件名不一致, windows 则提示文件名一致.

这是因为 MacOS 文件系统使用 NFD 形式存储文件名, 和文本输入框的值(NFC)不一致, 导致比对不一致.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
</head>
<body>
<input type="text" name="filename" value="é.txt" id='filename'>
<input type="file" multiple accept="*/*" onchange="previewFiles()" id="fileInput">
</body>
<script>
    // 监听事件,
    const previewFiles = (e) => {
        const files = document.querySelector('#fileInput').files;
        const filename = document.querySelector('#filename').value;
        console.log('filename normalize:', detectNormalizationForm(filename));
        console.log('file.name normalize:', detectNormalizationForm(files[0].name));
        // 比对 id 为 filename 的值 和 上传的文件名是否一致
        if (files.length === 0 || files[0].name !== filename) {
            alert('文件名不一致');
            return;
        } else {
            alert('文件名一致');
        }
    }

    function detectNormalizationForm(str) {
        if (str === str.normalize('NFC')) {
            return 'NFC';
        } else if (str === str.normalize('NFD')) {
            return 'NFD';
        } else if (str === str.normalize('NFKC')) {
            return 'NFKC';
        } else if (str === str.normalize('NFKD')) {
            return 'NFKD';
        } else {
            return 'Unknown';  // 如果没有匹配的规范化形式
        }
    }
</script>
</html>

问题解决

前端

前端可以在 axios/ajax 等统一请求的地方, 对请求的参数进行规范化, 保证传递的参数是 NFC 形式.

在前端处理是有局限性的, 比如上传文件时, 无法对文件内容进行处理

后端

后端也有几个地方需要处理

  1. 拦截 Controller, HandlerInterceptor 等请求处理的地方, 对请求参数进行规范化
  2. Excel 工具类, 解析成对象的地方, 对 Excel 中的字符串进行规范化(要求所有上传的 Excel 都使用这个方法进行解析)

数据库

可以在 Mybatis 拦截器中, 对所有的 SQL 进行规范化, 保证数据库中的数据都是 NFC 形式.

最后

如无必要, 勿增实体.

字符串作为系统中最常用的类型, 全部添加规范化会对系统的性能产生一定的影响. 系统如果涉及到重音符号的地方不多, 可以只在必要的地方进行规范化.


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]