17 lines
1.7 KiB
TypeScript
17 lines
1.7 KiB
TypeScript
|
|
// N4 — ถอดรหัสชื่อไฟล์ที่ FormData ของ Server Action ส่งมา
|
|||
|
|
// browser ใส่ชื่อไฟล์ (UTF-8) ลง header Content-Disposition ของ multipart body ตรง ๆ
|
|||
|
|
// แต่ undici ของ Node (ตัว parse request.formData() ที่ Next.js ใช้) ถอดรหัส header
|
|||
|
|
// เป็น latin1 ทำให้ชื่อที่ไม่ใช่ ASCII เพี้ยน ("คำร้อง.pdf" → "คำร้à¸à¸‡.pdf")
|
|||
|
|
// — เข้ารหัสกลับเป็น byte แล้วถอดด้วย UTF-8 จะได้ชื่อเดิมคืน
|
|||
|
|
// guard 2 ชั้นกันแตะชื่อที่ถูกต้องอยู่แล้ว: ชื่อที่ undici ถอดมามีแต่ตัวอักษร
|
|||
|
|
// ช่วง U+0000–U+00FF เท่านั้น ดังนั้นไม่มีตัวไหนใน U+0080–U+00FF เลย = ASCII ล้วนหรือ
|
|||
|
|
// ชื่อที่ส่งมาถูกต้อง (ไทยอยู่ U+0E00+) = ไม่แต้อยู่เดิม / ถอดแล้วได้ U+FFFD
|
|||
|
|
// (ไบต์ไม่ประกอบเป็น UTF-8 ที่สมบูรณ์ — ชื่อเป็น latin1 จริง) = เก็บของเดิมไว้
|
|||
|
|
const LATIN1_MOJIBAKE_RE = /[\u0080-ÿ]/;
|
|||
|
|
|
|||
|
|
export function decodeUploadFilename(name: string): string {
|
|||
|
|
if (!LATIN1_MOJIBAKE_RE.test(name)) return name;
|
|||
|
|
const fixed = Buffer.from(name, "latin1").toString("utf8");
|
|||
|
|
return fixed.includes("<22>") ? name : fixed;
|
|||
|
|
}
|