Files
ai_platform/lib/decode-upload-filename.js
dsyoon 200632f580 fix(upload): decodeURIComponent(escape) 우선 한글 파일명 복원, defParamCharset utf8 제거
- lib/decode-upload-filename.js: 전형적 Latin-1 래핑 UTF-8 복원
- multer 경영성과 업로드는 기본 latin1 + 서버에서 decodeUploadFilename
- utf8 defParamCharset는 이중 디코딩으로 á 패턴 등이 날 수 있어 제거

Made-with: Cursor
2026-04-13 18:58:02 +09:00

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 };