1 คะแนน โดย GN⁺ 2025-08-25 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • RFC 9839 นิยาม อักขระยูนิโค้ดที่เป็นปัญหา ซึ่งอาจอยู่ในฟิลด์ข้อความระหว่างการพัฒนาซอฟต์แวร์ไว้อย่างชัดเจน
  • RFC นี้กล่าวถึงปัญหาจากการที่ ภาษาและไลบรารีที่แตกต่างกัน จัดการกับอักขระเหล่านี้ได้ไม่สอดคล้องกัน
  • ใน 9839 มีการเสนอ ชุดย่อยสามแบบ ที่มีปัญหาน้อยกว่า เพื่อให้เลือกใช้งานได้ตามต้องการ
  • เมื่อเทียบกับ PRECIS framework เดิมแล้ว นำไปใช้ได้ง่ายและเรียบง่ายกว่า
  • มีการเผยแพร่ ไลบรารีภาษา Go สำหรับ RFC 9839 ควบคู่กันไป เพื่อช่วยให้ใช้งานจริงได้สะดวกขึ้น

ภูมิหลังและภาพรวมของ RFC 9839

  • ยูนิโค้ดถูกใช้เป็นมาตรฐานในการจัดการข้อมูลข้อความแทบทุกประเภท
  • แต่ในการออกแบบโครงสร้างข้อมูลหรือโปรโตคอลจริง หากอนุญาตอักขระยูนิโค้ดทั้งหมด อาจทำให้เกิดปัญหาได้
  • Paul Hoffman และผู้เขียนได้ส่ง individual draft ไปยัง IETF เพื่อเสนอเกณฑ์ที่ชัดเจนต่อปัญหายูนิโค้ดที่เกิดซ้ำอยู่เรื่อย ๆ
  • หลังจากการหารือเป็นเวลา 2 ปี จึงได้รับการรับรองเป็นมาตรฐานอย่างเป็นทางการและประกาศเป็น RFC 9839
  • เอกสารนี้อธิบายอย่างละเอียดถึง ประเภทของอักขระที่เป็นปัญหา เหตุใดจึงเป็นปัญหา (ทั้งในเชิงเทคนิคและเชิงมาตรฐาน) และชุดย่อยสามแบบที่ผู้ใช้สามารถเลือกใช้ได้

เนื้อหาหลักของ RFC 9839

  • เป็นเอกสารที่ควรอ้างอิงโดยจำเป็นเมื่อต้องออกแบบ ฟิลด์ข้อความ ในซอฟต์แวร์และสภาพแวดล้อมเครือข่าย
  • RFC 9839 มีความยาว 10 หน้า ซึ่งถือว่าค่อนข้างกระชับเมื่อเทียบกับเอกสารมาตรฐานของ IETF
  • อธิบายไว้ให้เข้าใจง่าย โดยมุ่งไปที่นักพัฒนาซอฟต์แวร์และวิศวกรเครือข่ายเป็นหลัก

ตัวอย่างอักขระยูนิโค้ดที่เป็นปัญหา

  • ตัวอย่างเช่น ในฟิลด์ username ของ JSON อาจมีสตริงดังนี้
    {  
        "username": "\u0000\u0089\uDEAD\uD9BF\uDFFF"  
    }  
    
  • ปัญหาของแต่ละ code point
    • U+0000 : อักขระ NULL ที่ไม่มีความหมายและอาจรบกวนการทำงานของภาษาโปรแกรมบางภาษา
    • U+0089 : โค้ดควบคุม C1 (CHARACTER TABULATION WITH JUSTIFICATION) ซึ่งมีพฤติกรรมซับซ้อนและไม่สม่ำเสมอ
    • U+DEAD : surrogate ที่ไม่ได้จับคู่ เป็นปัญหาที่เกิดจากข้อจำกัดของ UTF-16 ทำให้เกิดข้อมูลที่ไม่พึงประสงค์
    • \uD9BF\uDFFF (U+7FFFF จริง) : noncharacter ซึ่งตามมาตรฐานห้ามใช้ในการแลกเปลี่ยนข้อมูล
    โฆษณา
  • code point ลักษณะนี้ทำให้เกิด การจัดการที่ไม่สอดคล้องกัน ภายในโครงสร้างข้อมูลและโปรโตคอล และอาจก่อให้เกิดข้อผิดพลาดที่คาดไม่ถึง
  • RFC 9839 จึงนิยามอักขระปัญหาเหล่านี้อย่างเป็นทางการ และ ระบุประเภทที่ควรถูกตัดออกอย่างชัดเจน

การออกแบบของ JSON และข้อจำกัด

  • ไม่ใช่ความรับผิดของ Doug Crockford ผู้สร้าง JSON
  • JSON ถูกออกแบบขึ้นในช่วงที่ยูนิโค้ดยังไม่เติบโตเต็มที่ จึงไม่สามารถจำกัดชุดอักขระได้อย่างเข้มงวด
  • ตอนนี้ไม่สามารถเปลี่ยนมาตรฐานได้แล้ว จึงจำเป็นต้องใช้วิธี ตัดอักขระที่เป็นปัญหาออกตามประสบการณ์ที่พบจริง

ความแตกต่างจาก PRECIS framework ของ IETF

  • ก่อน RFC 9839 ในปี 2025 ทาง IETF ก็มีมาตรฐานหลากหลายฉบับ เช่น RFC 8264 (PRECIS Framework)
    • framework นี้อธิบายวิธีการปรับแต่ง การประยุกต์ใช้ และการเปรียบเทียบสตริงสากลไว้อย่างละเอียด
    • มีความยาว 43 หน้า และ ครอบคลุมทั้งคำอธิบายพื้นหลังและแนวทางแก้ปัญหา
  • PRECIS พึ่งพาเวอร์ชันของยูนิโค้ดอย่างมาก และมีข้อเสียคือซับซ้อนและนำไปใช้ได้ยาก
  • RFC 9839 กระชับและเน้นการใช้งานจริงมากกว่า ทำให้ นำไปใช้ได้รวดเร็ว เมื่อต้องนิยามโปรโตคอลใหม่

ชุดย่อยของ RFC 9839 และตัวอย่างการใช้งาน

  • 9839 นำเสนอชุดย่อยที่ใช้งานได้จริง 3 แบบ ได้แก่ scalars, XML และ assignables
  • แต่ละชุดย่อยมีขอบเขตของอักขระที่เป็นปัญหาซึ่งจะถูกตัดออกแตกต่างกันเล็กน้อย
  • ต่อไปนี้คือสรุปตารางว่าฟอร์แมตข้อมูลหลัก ๆ และชุดย่อยของ RFC 9839 จัดการกับอักขระที่เป็นปัญหาอย่างไร
    • ฟอร์แมตบางชนิด เช่น CBOR, TOML, XML, YAML จะตัด surrogate หรืออักขระควบคุมออกบางส่วน
    • I-JSON ตัด surrogate และ noncharacter ออก
    • JSON ทั่วไป, Protobufs ไม่ได้ตัดออก
    • XML, YAML เนื่องจากคุณสมบัติของ charset จึงตัด noncharacter/โค้ดควบคุมออกได้เพียงบางส่วน
      • หมายเหตุ: XML และ YAML ไม่ได้ตัด noncharacter ที่อยู่นอก Basic Multilingual Pane ออก
      โฆษณา

ไลบรารี RFC 9839 สำหรับภาษา Go

  • มีการเผยแพร่ไลบรารี Go ขนาดเล็กที่รองรับ การตรวจสอบอักขระ สำหรับชุดย่อยทั้งสามของ RFC 9839
  • มีการทดสอบอย่างเพียงพอแล้ว แต่การปรับแต่งประสิทธิภาพยังอยู่ระหว่างดำเนินการ
  • ยินดีรับการทดสอบและข้อเสนอแนะจากการใช้งานจริง

ความสำคัญของ RFC 9839 และกระบวนการทำงาน

  • RFC 9839 ผ่านการรับฟังความคิดเห็นจากผู้เขียนร่วมหลายครั้ง และมีการแก้ไข draft มากกว่า 15 รอบก่อนประกาศอย่างเป็นทางการ
  • ด้วยการอภิปรายและการมีส่วนร่วมจากผู้เชี่ยวชาญในชุมชนจำนวนมาก จึงพัฒนาเป็น เอกสารที่สมบูรณ์กว่าร่างแรกอย่างมาก
  • มีการระบุผู้มีส่วนร่วมไว้ในส่วน “Acknowledgements”

ประสบการณ์จากการส่ง RFC แบบ individual submission

  • RFC 9839 ดำเนินการในรูปแบบ individual submission
  • เมื่อเทียบกับวิธีดั้งเดิมผ่าน Working Group แล้ว มี ภาระทั้งด้านความพยายามและขั้นตอน มากกว่า
  • เมื่อเทียบกับประสบการณ์ในการเข้าร่วม Working Group วิธีดั้งเดิมมีประสิทธิภาพมากกว่าและน่าแนะนำกว่า

1 ความคิดเห็น

 
GN⁺ 2025-08-25
ความคิดเห็นจาก Hacker News
  • ผมคิดว่ามันชัดเจนว่ามีอักขระบางตัวที่ก่อปัญหา แต่ก็รู้สึกว่าสถานการณ์ที่แย่ที่สุดคือการที่ผู้ออกแบบโครงสร้างข้อมูลหรือโปรโตคอลมีแนวโน้มจะไม่ยอมให้อักขระทุกชนิดผ่านได้ตามอำเภอใจ แม้กระทั่งตัวที่ escape อย่างถูกต้องแล้วก็ตาม ตัวอย่างเช่น ผมมองว่าการตรวจสอบความถูกต้องของชื่อผู้ใช้ควรทำในอีกเลเยอร์หนึ่ง เช่น ตรวจว่าชื่อผู้ใช้ยาวน้อยกว่า 60 ตัวอักษร, ห้ามอีโมจิหรืออักษร zalgo, ห้าม null byte ฯลฯ แล้วให้ API ส่ง error ที่เหมาะสมกลับมา ผมไม่อยากให้มันล้มเหลวเพราะเรื่องพวกนี้ตั้งแต่ขั้นตอน parse JSON แทนที่จะตรวจสอบล่วงหน้า แน่นอนว่าสำหรับชื่อผู้ใช้ มีคลาสของอักขระบางอย่างที่ไม่เหมาะสมอย่างชัดเจน แต่ถ้าคุณกำลังส่งไฟล์ข้อความที่มีการใช้ tab character หรืออย่างอื่นจริง ๆ ผมก็คาดหวังว่าสิ่งที่จัดการได้ในชนิด utf8 "string" ของภาษาผมก็ควรถูกเข้ารหัสได้ โดยเฉพาะ null byte มีกรณีใช้งานเยอะ และใน JSON ก็เห็นอยู่บ่อย ๆ แต่ถ้าจำเป็นต้องใช้เฉพาะชุด Unicode "ปกติ" ที่จำกัดไว้ ผมก็คิดว่าการมีมาตรฐานกลางย่อมดีกว่าปล่อยให้แต่ละคนสร้างมาตรฐานย่อยของตัวเอง สรุปคือไอเดียโดยรวมดูดี แต่เหตุผลที่ยกมาในโพสต์บล็อกยังไม่น่าเชื่อถือเท่าไร

    • พูดจริงจังนะ ณ ปี 2025 ผมคิดว่าวิธีแทนสตริงที่พอจะปกป้องได้จริงใน wire protocol ระดับล่างมีอยู่แค่ตัวเลือกต่อไปนี้

      • "Unicode Scalars" (UTF-16 ที่จัดรูปแบบถูกต้อง, ชนิด string ของ Python)
      • "UTF-16 ที่อาจไม่ถูกต้อง" (WTF-8, ชนิด string ของ JavaScript)
      • "UTF-8 ที่อาจไม่ถูกต้อง" (อาร์เรย์ไบต์, ชนิด string ของ Go)
      • วิธีใดวิธีหนึ่งข้างต้นพร้อมตัวเลือก "ไม่มี U+0000" เพิ่มเข้ามา (เมื่อต้องเชื่อมต่อกับภาษา/ไลบรารีที่ออกแบบก่อนยุคช่องโหว่ buffer overflow)
    • เอาจริง ๆ ผมอยากให้ในไฟล์ plain text ไม่มีการใช้ตัวอักษร C0 (ยกเว้นตัวขึ้นบรรทัดใหม่ และ HT แบบจำใจ) และตัวอักษร C1 ผมเข้าใจนะว่ามีคนอยากเก็บอะไรอย่าง ANSI color markup แต่ในกรณีนั้นมันไม่ใช่ plain text จริง ๆ มันคือฟอร์แมต markup แบบหนึ่งสำหรับข้อความ คล้าย Markdown แต่ต่างกันตรงที่ใช้อักขระเข้ารหัสในช่วง C0 แค่เพราะข้อมูลนั้นดูสวยเวลาใช้คำสั่ง cat ไม่ได้แปลว่ามันเป็น plain text ผมก็ยอมรับว่ามีฟอร์แมต markup ที่เข้ารหัสเป็น plain text อยู่เยอะเพราะเหตุผลด้าน interoperability

    • ผมว่าความเห็นที่บอกว่าการเริ่มแบนชุดอักขระแบบตามอำเภอใจในโครงสร้างข้อมูลและโปรโตคอลเป็นสิ่งที่แย่ที่สุดนั้นค่อนข้างห่างไกลจากความเป็นจริง สิ่งที่แย่จริง ๆ คือการที่ข้อบกพร่องของซอฟต์แวร์อย่าง parser ทำให้เกิดการเจาะระบบด้านความปลอดภัย

    • ผมสงสัยว่ามีระบบไหนบ้างที่อนุญาต UTF-8 ในชื่อผู้ใช้ ตัวระบุทุกชนิดที่ถูกจัดการหรือประเมินผลทางโปรแกรมได้ (เช่น ชื่อผู้ใช้สำหรับล็อกอิน, รหัสผ่าน ฯลฯ) ควรต้องเป็น ASCII เท่านั้น ไม่ใช่ ISO-8859-1 แต่เป็น ASCII ล้วน Unicode ไม่เหมาะกับงานแบบนี้ ถึงจะไม่เป็นไรถ้าใช้ตอนแสดงชื่อผู้ใช้ แต่ถ้าเป็นตัวระบุสำหรับการล็อกอินเข้าระบบ การเข้ารหัสที่ไม่ใช่ ASCII ควรถูกห้ามทั้งหมด แม้แต่ซอฟต์แวร์คีย์บอร์ดเองก็ไม่อาจรับประกันความสม่ำเสมอของ UTF-8 ในการแสดงผลเมื่อออกนอก ASCII ได้ และยิ่งสับสนตามระบบปฏิบัติการกับการตั้งค่าที่ต่างกัน อีกทั้งก็ไม่มีอะไรรับประกันได้ว่าไบนารีที่ถูกทิ้งไว้ในอนาคตกับ AI ที่ตีความ Unicode จะเข้าใจตรงกัน นอกจากนี้ในประเด็นความสม่ำเสมอ RFC 9839 และบทความก็ยังไม่ชัดเจนว่าจัดการเรื่อง IVS หรือ normalization (NFC/NFD/NFKC/NFKD) ว่าอยู่ในขอบเขตหรืออยู่นอกขอบเขตอย่างไร ดูเหมือนว่าส่วนวัตถุประสงค์จะหายไปเลย มีเพียงการพูดแบบคลุมเครือประมาณว่ามี "non-character code point"

    • ผมสงสัยว่าทำไมต้องห้ามอีโมจิในชื่อผู้ใช้

  • อยากจะบอกว่า IETF ไม่ได้รอจนถึงปี 2025 ค่อยรองรับ Bad Unicode ก่อนหน้านี้ก็มี RFC 8264: PRECIS Framework ที่จัดการปัญหา Bad Unicode หลากหลายแบบไว้อย่างครอบคลุมแล้ว ดู RFC ที่เกี่ยวข้องอย่าง RFC 8265(ลิงก์), 8266(ลิงก์) เป็นต้น ก็น่าจะช่วยได้ โดยทั่วไป สิ่งอย่างรหัสผ่านที่อาจเปลี่ยนทิศทางข้อความหรือเข้ารหัสต่างกันไปตามอุปกรณ์ป้อนข้อมูลไม่ควรถูกใช้ในชื่อผู้ใช้/รหัสผ่าน โปรไฟล์ RFC เหล่านี้ช่วยจัดการได้อย่างปลอดภัย สำหรับจุดประสงค์แบบนี้ การ "failing closed" (บล็อกให้เข้มงวดกว่า) ปลอดภัยกว่า แม้จะมีอีโมจิใหม่ออกมา ผมก็ยังชอบแนวทางห้ามไว้ก่อนและค่อยเป็นค่อยไป มากกว่าจะปล่อยให้ใช้ในชื่อผู้ใช้แล้วไปกระทบทุกหน้า

    • แต่ถ้าปิดแน่นเกินไป อีก 20 ปีข้างหน้าก็อาจยังไม่รองรับอีโมจิจากเมื่อ 20 ปีก่อนอยู่ดี และสุดท้ายก็มีแต่เพิ่มความไม่พอใจให้ผู้ใช้
  • Unicode มีส่วนที่ "ดี" อยู่แน่นอน แต่ก็น่าผิดหวังที่เราต้องรู้ว่ามีอักขระบางตัวที่ต้องยกเว้นเป็นพิเศษ มันเป็นผลจากการพยายามรองรับวิธีบันทึกภาษาต่าง ๆ แบบครอบคลุมจนซับซ้อนเกินไป มันเหนื่อยตรงที่ต้องคอยคิดเสมอว่าอักขระไหนต้องถูกปฏิบัติเป็นกรณีพิเศษ ดังนั้นผมเลยมองสตริง Unicode ว่าเป็นหน่วยข้อมูลแบบเฉพาะตัว รับเข้า, เก็บ, render, เทียบความเท่ากันของข้อมูลได้ แต่ไม่พยายามตีความเนื้อหาของมัน แม้แต่การต่อสตริงหรือจัดการกับมันก็ยังรู้สึกไม่สบายใจ

    • Unicode เหมือนห้วงลึกที่เต็มไปด้วยเรื่องจุกจิกไม่รู้จบและการตัดสินใจที่ไม่ดี ตัวอย่างเช่น RFC ที่เกี่ยวข้องมีคำเตือนเกี่ยวกับอักขระควบคุม ASCII แบบเก่า (ที่เสี่ยงทำให้สับสนในการแสดงผล) แต่กลับไม่พูดถึงอักขระควบคุมทิศทางที่มีปัญหาด้านความปลอดภัยร้ายแรงอย่าง Explicit Directional Overrides เลย

    • ยกตัวอย่างง่าย ๆ ถ้าสตริงแรกลงท้ายด้วยตัวแก้ไขอีโมจิที่ลอยอยู่เดี่ยว ๆ และสตริงที่สองเริ่มด้วยอีโมจิที่แก้ไขได้ ปัญหาก็เกิดแล้ว และยิ่งมีเคสซับซ้อนขึ้น ปัญหาก็ยิ่งมากขึ้น

    • มันซับซ้อนมากก็จริง แต่บางอย่างในนั้น เช่น surrogate และ control code ไม่ได้มีไว้เพื่อการบันทึกภาษา แต่เป็นผลจากดีไซน์ประหลาดที่หลงเหลือมาจากอดีต

    • Unicode น่าหงุดหงิดก็จริง แต่ผมก็ยังคิดว่ามันน่าหงุดหงิดน้อยกว่ามาตรฐาน encoding แบบเก่าอื่น ๆ

  • ผมคิดว่าปัญหาส่วนใหญ่แก้ได้ด้วยการปฏิเสธลำดับไบต์ UTF-8 ที่ไม่ถูกต้อง หรือไม่ก็คืนค่า error ออกไปทั้งชุด เช่น surrogate นั้นผิดกฎใน UTF-8 อยู่แล้ว ดังนั้นถ้าเป็นภาษาที่ใช้ utf-8 ก็ควรคืน error เมื่อเจอลำดับแบบนี้ ปัญหาที่เป็นปัญหาจริง ๆ คือพวก "code point" ที่มีคุณสมบัติน่ามีปัญหา (เช่น non-printing เป็นต้น) ซึ่งควรถูกจัดการเป็นแนวคิดแยกจากลำดับไบต์ที่ผิดกฎหมายอย่างชัดเจน จะได้มีประโยชน์กว่า

    • ผมว่าเหตุผลนี้สมเหตุสมผลพอ นี่ควรเป็นทางเลือกของผู้พัฒนาแอปพลิเคชัน ไม่ใช่สิ่งที่ไลบรารีทั่วไปควรเป็นคนตัดสินใจ ผมไม่เคยเห็น JSON parser ที่มีไว้จัดการแต่ชื่อผู้ใช้เท่านั้น
  • Unicode ได้กำหนดหมวดหมู่ของแต่ละ code point (General Category) ไว้อยู่แล้วเพื่อจัดประเภทอักขระแปลก ๆ ดูได้จากบทความใน Wikipedia ที่เกี่ยวข้อง ตัวอย่างเช่น ใน Python, unicodedata.category(chr(0)) จะคืนค่า "Cc" (control), และ unicodedata.category(chr(0xdead)) จะคืนค่า "Cs" (surrogate)

  • ผมคิดว่าการตัด "legacy control" ออกทั้งหมด ไม่เฉพาะตัวลิเทอรัลแต่รวมถึงสตริงแบบ escape ด้วย (เช่น "\u0027") มันมากเกินไป C1 ไม่ค่อยได้ใช้ก็จริงจึงพอรับได้ แต่ในบรรดาอักขระ C0 บางตัวก็มีตัวอย่างการใช้งานจริง escape, EOF, NUL ฯลฯ ยังมีประโยชน์ใช้งานชัดเจนอยู่

    • อักขระ C0 ที่ค่อนข้างเฉพาะทางหน่อย (เช่น U+001E Record Separator) ผมคิดว่ามีประโยชน์มากใน data stream ต่อให้ห้ามในเอกสาร แต่ในข้อมูลแบบสตรีมมันยังมีประโยชน์

    • ผมเคยเห็นมีการใช้อักขระ form feed (U+000C) ในซอร์สโค้ดโปรแกรม Emacs รองรับการนำทางเป็นหน้าอยู่แล้วแต่เดิม เลยทำให้ของแบบนี้มีหลุดเข้ามาได้

  • ผมไม่คิดว่า Unicode จะดี ไม่ว่าจะใช้ชุดอักขระอะไร ประเภทของอักขระที่ใช้งานจริง (อักขระควบคุม, อักขระกราฟิก, ความยาวสูงสุด ฯลฯ) สุดท้ายก็ต้องกำหนดตามแต่ละแอปพลิเคชันอยู่ดี การพยายามรวม/ตัดออกใน JSON หรืออะไรทำนองนั้นไม่ค่อยช่วยมากนัก จะเป็น Unicode, ASCII หรือชุดอักขระอื่น การตั้งชื่อให้ subset (หรือ superset) เฉพาะบางแบบบางครั้งก็มีประโยชน์ แต่ไม่ควรหลงคิดว่ามันเป็นตัวเลือกที่ดีสำหรับทุกคน RFC 9839 แค่ตั้งชื่อให้ subset ของ Unicode บางชุด แต่ไม่ได้รับประกันว่านั่นจะถูกต้องเสมอสำหรับบริการที่ผมจะสร้าง ข้อสรุปของผมคือควรพิจารณาด้วยว่าจะไม่ใช้ Unicode เลยหรือไม่บังคับใช้มัน

    • ปัญหาจริงคือ combining character เพราะสิ่งนี้เอง Unicode จึงเปลี่ยนจากชุดอักขระไปเป็น DSL สำหรับบรรยายอักขระ
  • ผมกำลังคิดว่าจะควบคุมข้อมูลนำเข้า หรือจะห่อมันด้วย data type สำหรับการแสดงผลอย่างปลอดภัยกับข้อมูลที่ไม่น่าเชื่อถือ (ใช้กับ web+log+debug)

  • ผมอยากให้มาตรฐานมีข้อจำกัดเกี่ยวกับจำนวน Unicode scalar value ที่ใส่ได้ในหนึ่งหน่วยกราฟิก ตอนที่ผมเช็กล่าสุด (แม้จะเป็นเมื่อหลายปีก่อน) มาตรฐานไม่มีการจำกัดแบบนั้น มีแต่คำแนะนำว่าสำหรับแอปพลิเคชันแบบสตรีมให้จำกัดหน่วยกราฟิกไว้ที่ 128 ไบต์ ถ้ามีขีดจำกัดแบบชัดเจนในมาตรฐาน การ implement ก็น่าจะง่ายขึ้นมากและไม่ต้องมีข้อจำกัดเกินจำเป็น

  • ผมเคยเจอกรณีที่โปรแกรมพังเพราะตั้งสมมติฐานว่า "ไม่มี control character" (ทั้งที่ form feed ใช้แบ่งหน้า, escape character ก็ใช้กับเทอร์มินัลกันบ่อย) และสมมติฐานว่า "ทั้งหมดเป็น UTF-8" ก็พังได้เหมือนกัน (เช่น ไฟล์ข้อมูลเก่า, log ฯลฯ) ถ้าคุณไม่ได้จะทำอะไรกับข้อความในเชิงความหมาย การส่งต่อไปเป็นลำดับไบต์แบบไม่แก้ไขเนื้อหาเลยคือทางเลือกที่ดีที่สุด แต่บางครั้งเพราะ Microsoft Windows คุณก็จำเป็นต้องส่งลำดับ char16_t แทน UTF-16 ต่างจาก UTF-8 อย่างพื้นฐานในเรื่อง input/output เวลาแปลงข้อมูล คุณต้องใช้แนวทาง WTF-8 สำหรับภายนอก → รูปแบบภายใน (UTF-16) และใช้ surrogate escape สำหรับ (UTF-8) โดยเฉพาะ ห้ามเอาสองวิธีมาปนกันเด็ดขาด