- lib/decode-upload-filename.js: 전형적 Latin-1 래핑 UTF-8 복원 - multer 경영성과 업로드는 기본 latin1 + 서버에서 decodeUploadFilename - utf8 defParamCharset는 이중 디코딩으로 á 패턴 등이 날 수 있어 제거 Made-with: Cursor
43 lines
1.3 KiB
JavaScript
43 lines
1.3 KiB
JavaScript
"use strict";
|
|
|
|
/**
|
|
* multipart `filename` 복원.
|
|
*
|
|
* 브라우저는 UTF-8 파일명을 `Content-Disposition`에 넣을 때, 바이트를 ISO-8859-1(Latin-1) 코드 포인트
|
|
* (U+00xx) 한 글자씩으로 보내는 경우가 많습니다. 이 경우 `decodeURIComponent(escape(s))` 또는
|
|
* `Buffer.from(s, "latin1").toString("utf8")`로 UTF-8 문자열로 되돌릴 수 있습니다.
|
|
*
|
|
* 일부 환경에서는 이미 잘못 합쳐진 유니코드(예: U+00E1 등)만 남아 복구가 불가능할 수 있습니다.
|
|
*
|
|
* @param {string} name multer `originalname`
|
|
* @returns {string}
|
|
*/
|
|
function decodeUploadFilename(name) {
|
|
if (name == null || typeof name !== "string") return "";
|
|
const raw = name.trim();
|
|
if (!raw) return "";
|
|
const nfc = raw.normalize("NFC");
|
|
if (/[\uAC00-\uD7A3]/.test(nfc)) return nfc;
|
|
|
|
try {
|
|
const viaEscape = decodeURIComponent(escape(nfc));
|
|
if (!viaEscape.includes("\uFFFD") && viaEscape !== nfc) {
|
|
return viaEscape.normalize("NFC");
|
|
}
|
|
} catch (_) {
|
|
/* escape가 만들어 낸 % 시퀀스가 URI로 부적합한 경우 */
|
|
}
|
|
|
|
try {
|
|
const buf = Buffer.from(nfc, "latin1");
|
|
const asUtf8 = buf.toString("utf8");
|
|
if (!asUtf8.includes("\uFFFD")) {
|
|
return asUtf8.normalize("NFC");
|
|
}
|
|
} catch (_) {}
|
|
|
|
return nfc;
|
|
}
|
|
|
|
module.exports = { decodeUploadFilename };
|