1 पॉइंट द्वारा GN⁺ 2025-08-25 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • RFC 9839 सॉफ़्टवेयर डेवलपमेंट के दौरान टेक्स्ट फ़ील्ड में शामिल हो सकने वाले समस्याग्रस्त Unicode characters को स्पष्ट रूप से परिभाषित करता है
  • यह RFC अलग-अलग भाषाओं और लाइब्रेरीज़ में इन characters को संभालने में एकरूपता की कमी से पैदा होने वाली समस्याओं पर बात करता है
  • 9839 कम समस्याग्रस्त तीन subsets प्रस्तावित करता है, जिनका ज़रूरत के अनुसार चयनात्मक उपयोग किया जा सकता है
  • मौजूदा PRECIS framework की तुलना में इसे लागू करना अधिक आसान और सरल है
  • RFC 9839 के लिए Go language library भी जारी की गई है, जिससे व्यावहारिक उपयोग में मदद मिलती है

पृष्ठभूमि और RFC 9839 का अवलोकन

  • Unicode लगभग सभी टेक्स्ट डेटा प्रोसेसिंग में एक मानक के रूप में इस्तेमाल होता है
  • लेकिन वास्तविक डेटा संरचनाओं या प्रोटोकॉल डिज़ाइन में सभी Unicode characters को अनुमति देने से समस्याएँ पैदा होती हैं
  • Paul Hoffman और लेखक ने बार-बार सामने आने वाली Unicode समस्याओं के लिए स्पष्ट मानदंड देने के उद्देश्य से IETF को individual draft जमा किया
  • 2 वर्षों की चर्चा के बाद इसे आधिकारिक मानक के रूप में अपनाया गया और RFC 9839 के रूप में प्रकाशित किया गया
  • यह दस्तावेज़ समस्याग्रस्त character types, वे क्यों समस्या हैं (तकनीकी और मानकीकरण कारण), और उपयोगकर्ता जिन तीन subsets में से चुन सकते हैं, उनका विस्तार से वर्णन करता है

RFC 9839 की मुख्य बातें

  • सॉफ़्टवेयर और नेटवर्क वातावरण में text fields डिज़ाइन करते समय यह एक आवश्यक संदर्भ दस्तावेज़ है
  • RFC 9839 10 पेज का है, इसलिए IETF मानक दस्तावेज़ों में यह अपेक्षाकृत संक्षिप्त है
  • इसे मुख्य रूप से सॉफ़्टवेयर डेवलपर्स और नेटवर्क इंजीनियर्स को ध्यान में रखकर आसान भाषा में समझाया गया है

समस्याग्रस्त Unicode characters के उदाहरण

  • उदाहरण के लिए JSON के username फ़ील्ड में नीचे जैसा string आ सकता है
    {  
        "username": "\u0000\u0089\uDEAD\uD9BF\uDFFF"  
    }  
    
  • हर code point की समस्या
    • U+0000 : अर्थहीन NULL character, जो कुछ programming languages के व्यवहार में बाधा डालता है
    • U+0089 : C1 control code (CHARACTER TABULATION WITH JUSTIFICATION), जिसका व्यवहार जटिल है और एकसमान नहीं है
    • U+DEAD : unpaired surrogate character, जो UTF-16 की सीमाओं से उत्पन्न समस्या है। इससे आदर्श न होने वाला डेटा बनता है
    • \uD9BF\uDFFF (वास्तविक U+7FFFF) : Noncharacter, जिसका आदान-प्रदान मानक के अनुसार निषिद्ध है
  • ऐसे code points डेटा संरचनाओं और प्रोटोकॉल के भीतर consistent handling को असंभव बनाते हैं और अप्रत्याशित errors पैदा करते हैं
  • RFC 9839 इन समस्याग्रस्त characters को औपचारिक रूप से परिभाषित करता है और किन प्रकारों को बाहर करना है, यह स्पष्ट रूप से बताता है

JSON का डिज़ाइन और उसकी सीमाएँ

  • इसके लिए JSON के निर्माता Doug Crockford ज़िम्मेदार नहीं हैं
  • यह ऐसे समय में डिज़ाइन किया गया था जब Unicode पर्याप्त परिपक्व नहीं था, इसलिए character set को कड़ाई से सीमित नहीं किया जा सका
  • अब मानक बदला नहीं जा सकता, इसलिए अनुभव के आधार पर समस्याग्रस्त characters को बाहर रखने का तरीका आवश्यक है

IETF के PRECIS framework से अंतर

  • 2025 के RFC 9839 से पहले भी IETF ने RFC 8264 (PRECIS Framework) जैसे विभिन्न मानक उपलब्ध कराए थे
    • यह framework internationalized strings की तैयारी, लागू करने और तुलना करने के तरीकों को विस्तार से बताता है
    • 43 पेज का यह दस्तावेज़ पृष्ठभूमि विवरण और समाधान दोनों में व्यापक है
  • PRECIS की कमी यह है कि यह Unicode versions पर बहुत अधिक निर्भर है, और जटिल होने के कारण इसे लागू करना कठिन है
  • RFC 9839 संक्षिप्त और व्यावहारिकता-केंद्रित है, इसलिए नए प्रोटोकॉल परिभाषित करते समय इसे तेज़ी से अपनाना आसान है

RFC 9839 के subsets और उपयोग के उदाहरण

  • 9839 तीन व्यावहारिक subsets (scalars, XML, assignables) प्रस्तुत करता है
  • हर subset में बाहर किए जाने वाले समस्याग्रस्त characters की सीमा थोड़ी अलग है
  • नीचे प्रमुख data formats और RFC 9839 के subsets समस्याग्रस्त characters को कैसे संभालते हैं, उसका सार दिया गया है
    • CBOR, TOML, XML, YAML जैसे कुछ formats surrogate या control characters को आंशिक रूप से बाहर करते हैं
    • I-JSON surrogate और noncharacter को बाहर करता है
    • सामान्य JSON, Protobufs इन्हें बाहर नहीं करते
    • XML, YAML charset की विशेषताओं के कारण noncharacter/control codes को केवल आंशिक रूप से बाहर करते हैं
      • संदर्भ: XML और YAML Basic Multilingual Pane के बाहर के noncharacter को बाहर नहीं करते

Go language के लिए RFC 9839 लाइब्रेरी

  • RFC 9839 के तीनों subsets के लिए character validation सपोर्ट करने वाली एक छोटी Go लाइब्रेरी जारी की गई है
  • इसका पर्याप्त परीक्षण किया जा चुका है, हालांकि optimization अभी जारी है
  • वास्तविक कार्यस्थल में testing और feedback का स्वागत है

RFC 9839 का महत्व और कार्य-प्रक्रिया

  • RFC 9839 को सह-लेखकों और कई दौर के feedback के साथ 15 से अधिक draft revisions के बाद आधिकारिक रूप से प्रकाशित किया गया
  • समुदाय के अनेक विशेषज्ञों की चर्चा और योगदान के जरिए यह प्रारंभिक मसौदे की तुलना में कहीं अधिक परिपक्व दस्तावेज़ बन गया
  • योगदानकर्ताओं का उल्लेख “Acknowledgements” सेक्शन में किया गया है

RFC individual submission का अनुभव

  • RFC 9839 को individual submission के रूप में आगे बढ़ाया गया
  • Working Group के माध्यम से होने वाले पारंपरिक तरीके की तुलना में मेहनत और प्रक्रिया का बोझ अधिक है
  • Working Group में भागीदारी के अनुभव की तुलना में पारंपरिक तरीका अधिक कुशल और अनुशंसित माना गया है

1 टिप्पणियां

 
GN⁺ 2025-08-25
Hacker News की राय
  • मुझे लगता है कि यह स्पष्ट है कि कुछ characters समस्याएँ पैदा करते हैं, लेकिन सबसे खराब स्थिति तब होती है जब data structure या protocol designers हर तरह के characters को मनमाने ढंग से अनुमति न देने की प्रवृत्ति रखते हैं, यहाँ तक कि properly escaped characters को भी। उदाहरण के लिए, मेरा मानना है कि username validation किसी दूसरी layer में होना चाहिए। जैसे username 60 characters से कम हो, emoji या zalgo characters निषिद्ध हों, null byte निषिद्ध हो, आदि की जाँच की जाए और API उचित error लौटाए। मैं नहीं चाहता कि JSON parsing चरण में pre-validation की बजाय ऐसी समस्याओं के कारण failure हो। बेशक, usernames में कुछ character classes स्पष्ट रूप से अनुपयुक्त हैं। लेकिन अगर मैं tabs वगैरह वाले वास्तव में उपयोग होने वाले text files भेज रहा हूँ, तो मैं उम्मीद करूँगा कि मेरी language के utf8 string type में जिसे संभाला जा सकता है, वह encodable भी हो। खासकर null byte के कई उपयोग हैं, और यह वास्तव में JSON में भी कभी-कभी दिखता है। फिर भी, अगर केवल सीमित "सामान्य" Unicode set का उपयोग करना चाहिए, तो बेहतर है कि कोई standard मौजूद हो बजाय इसके कि हर कोई अपना mini-standard बनाए। निष्कर्षतः, idea अपने आप में अच्छा लगता है, लेकिन blog post में दी गई reasoning मुझे ज़्यादा convincing नहीं लगी

    • 2025 तक, मुझे लगता है कि low-level wire protocols में strings के लिए केवल नीचे दिए गए representations में से किसी एक का ही वास्तव में बचाव किया जा सकता है

      • "Unicode Scalars" (well-formed UTF-16, Python string type)
      • "potentially invalid UTF-16" (WTF-8, JavaScript string type)
      • "potentially invalid UTF-8" (byte array, Go string type)
      • ऊपर के किसी एक representation के साथ "no U+0000" option जोड़ना (ऐसी languages/libraries के साथ interop के लिए जो buffer overflow vulnerabilities से पहले design की गई थीं)
    • सच कहूँ तो, मैं चाहता हूँ कि plain text files में C0 (newline और, अनिच्छा से सही, HT को छोड़कर) तथा C1 characters का उपयोग न हो। मैं समझता हूँ कि लोग ANSI color markup जैसी चीजें store करना चाहते हैं, लेकिन ऐसे मामलों में वह वास्तव में plain text नहीं बल्कि किसी तरह का text markup format होता है। यह Markdown जैसा है, बस C0 range encoding का उपयोग करता है। सिर्फ इसलिए कि data cat command आदि में अच्छा दिखता है, यह नहीं कहा जा सकता कि वह plain text है। मैं मानता हूँ कि plain text में encoded markup formats interoperability के कारण बहुत हैं

    • यह राय कि data structures और protocols में arbitrary character groups को प्रतिबंधित करना शुरू करना सबसे खराब बात है, अपने आप में वास्तविकता से कटी हुई सोच लगती है। असल में सबसे खराब स्थिति तो वह है जहाँ parsers जैसी software defects के कारण security breaches हों

    • मुझे संदेह है कि कोई system usernames में UTF-8 की अनुमति देता है। कोई भी identifier जिसे programmatically manipulate या evaluate किया जाता है — login username, password आदि — उसे अनिवार्य रूप से ASCII होना चाहिए। ISO-8859-1 भी नहीं, केवल ASCII। Unicode ऐसे उपयोग के लिए उपयुक्त नहीं है। username को display करना हो तो अलग बात है, लेकिन system login identifier के रूप में non-ASCII encoding पर पूरी तरह रोक होनी चाहिए। keyboard software भी ASCII से बाहर visual representation के लिए UTF-8 consistency की गारंटी नहीं दे सकता, और OS तथा settings के अनुसार चीजें और उलझती हैं। भविष्य में बची binaries और Unicode-interpreting AI एक जैसा समझेंगे, इसकी भी कोई गारंटी नहीं है। साथ ही consistency के संदर्भ में, IVS की स्थिति या normalization (NFC/NFD/NFKC/NFKD) समस्याओं को RFC 9839 और article स्पष्ट रूप से in-scope/out-of-scope बताकर नहीं संभालते। ऐसा लगता है कि purpose section ही गायब है। बस लगभग इतना सा अस्पष्ट संकेत है कि "noncharacter code points" जैसी कोई चीज़ होती है

    • मैं जानना चाहता हूँ कि usernames में emoji को प्रतिबंधित क्यों किया जाना चाहिए

  • मैं यह बताना चाहता हूँ कि IETF ने 2025 तक Bad Unicode support का इंतज़ार नहीं किया। इसने पहले से ही RFC 8264: PRECIS Framework में विभिन्न Bad Unicode समस्याओं को व्यापक रूप से संभाला है। RFC 8265(लिंक), 8266(लिंक) आदि संबंधित RFCs भी देखना उपयोगी होगा। आम तौर पर, passwords जैसी चीजें जो text direction बदल सकती हैं या अलग input devices पर अलग तरह से encode हो सकती हैं, उन्हें username/password में उपयोग नहीं किया जाना चाहिए। इन RFC profiles के माध्यम से इन्हें सुरक्षित रूप से संभाला जा सकता है। इस तरह के उद्देश्य के लिए "failing closed" (अधिक सख्ती से block करना) अधिक सुरक्षित है। भले ही नए emoji आते रहें, मैं usernames में उन्हें अनुमति देकर हर page को प्रभावित करने की बजाय उन्हें block कर conservatively चलना पसंद करूँगा

    • फिर भी, अगर बहुत ज़्यादा बंद रखा जाए, तो 20 साल बाद भी 20 साल पुराने emoji unsupported रह जाएँगे और अंततः सिर्फ user dissatisfaction बढ़ेगा
  • Unicode के "अच्छे" हिस्से स्पष्ट हैं, लेकिन यह जानना निराशाजनक है कि कुछ ऐसे characters भी हैं जिन्हें अपवादस्वरूप बाहर रखना पड़ता है। यह भाषाओं की लेखन प्रणालियों को व्यापक रूप से समाहित करने की कोशिश में अत्यधिक जटिल हो जाने का परिणाम है। हमेशा यह सोचना पड़ता है कि कौन-सा character special treatment चाहता है, और यह थकाने वाला है। इसलिए मैं Unicode strings को अपने आप में एक अलग data unit मानकर संभालता हूँ। input लेता हूँ, store करता हूँ, render करता हूँ, data equality compare करता हूँ, लेकिन content को interpret करने की कोशिश नहीं करता। यहाँ तक कि strings को concatenate करना या उनमें हेरफेर करना भी असहज लगता है

    • Unicode अंतहीन trivia और खराब decisions की खाई जैसा लगता है। उदाहरण के लिए, संबंधित RFCs में पुराने ASCII control characters (display confusion की आशंका) के बारे में warning है, लेकिन Explicit Directional Overrides जैसे गंभीर security issue वाले direction-changing characters का कोई ज़िक्र नहीं है

    • एक आसान उदाहरण लें, अगर पहली string का अंत एक orphan emoji modifier पर हो और दूसरी की शुरुआत किसी modifiable emoji से हो, तो समस्या पैदा हो जाती है। जैसे-जैसे अधिक जटिल cases बढ़ते हैं, समस्या भी बढ़ती जाती है

    • complexity बड़ी है, लेकिन इनमें से surrogates और control codes भाषा लेखन के लिए नहीं बल्कि अजीब design के ऐतिहासिक अवशेष हैं

    • Unicode असुविधाजनक है, लेकिन मुझे लगता है कि यह पुराने अन्य encoding standards से कम असुविधाजनक है

  • मुझे लगता है कि अधिकांश समस्याओं का समाधान invalid UTF-8 byte sequences को reject करने या समग्र रूप से error लौटाने से हो सकता है। उदाहरण के लिए, surrogates आदि मूलतः UTF-8 में illegal हैं, इसलिए अगर कोई language utf-8 उपयोग करती है, तो उसे ऐसे sequences पर error लौटाना चाहिए। वास्तव में समस्याग्रस्त चीज़ें वे "code points" हैं जो problematic हैं (non-printing, आदि)। इसे illegal byte sequences से स्पष्ट रूप से अलग concept के रूप में संभालना अधिक उपयोगी है

    • यह काफ़ी उचित लगता है। ऐसे choices application implementer के हिस्से हैं, generic library के नहीं। मैंने कभी ऐसा JSON parser नहीं देखा जो सिर्फ usernames को संभालता हो
  • Unicode पहले से ही हर code point की category (General Category) परिभाषित करता है ताकि अजीब character types को वर्गीकृत किया जा सके। संबंधित Wikipedia article देखा जा सकता है। उदाहरण के लिए, Python में unicodedata.category(chr(0)) "Cc" (control) लौटाता है, और unicodedata.category(chr(0xdead)) "Cs" (surrogate) लौटाता है

  • मुझे लगता है कि सभी "legacy control" characters को केवल literal ही नहीं बल्कि escaped strings (e.g., "\u0027") से भी बाहर करना ज़रूरत से ज़्यादा है। C1 कम उपयोग होता है, इसलिए ठीक है, लेकिन कुछ C0 characters के वास्तविक उपयोग के उदाहरण हैं। escape, EOF, NUL आदि के स्पष्ट उपयोग अभी भी मौजूद हैं

    • कुछ असामान्य C0 characters (जैसे U+001E Record Separator) data streams में काफ़ी उपयोगी हैं। documents में इन्हें block किया जा सकता है, लेकिन stream data में ये उपयोगी हैं

    • मैंने program source code में form feed (U+000C) character का उपयोग देखा है। Emacs मूल रूप से page-by-page navigation के लिए इसे support करता है, इसलिए यह कभी-कभी शामिल होता है

  • मुझे नहीं लगता कि Unicode अच्छा है। character set कोई भी हो, वास्तव में किन kinds of characters का उपयोग करना है (control characters, graphic characters, maximum length, आदि), यह अंततः हर application के हिसाब से तय करना पड़ता है। JSON आदि में inclusion/exclusion की कोशिश से बहुत फ़ायदा नहीं होता। चाहे Unicode हो, ASCII हो या कोई और character set, किसी specific subset (या superset) को नाम देना कभी-कभी उपयोगी हो सकता है, लेकिन यह भ्रम नहीं होना चाहिए कि वह सबके लिए अच्छा विकल्प है। RFC 9839 कुछ Unicode subsets को नाम देता है, लेकिन इससे यह गारंटी नहीं मिलती कि वे मेरे service के लिए स्वतः सही होंगे। मेरा निष्कर्ष यह है कि Unicode का बिल्कुल उपयोग न करना या उसे अनिवार्य न बनाना भी विचार करने लायक है

    • असली समस्या combining characters हैं। इनके कारण Unicode एक character set से characters के वर्णन के लिए DSL में बदल गया है
  • मैं सोच रहा हूँ कि input को control किया जाए, या फिर untrusted input के लिए safe output देने वाले data type (web+log+debug के लिए) में उसे wrap किया जाए

  • मैं चाहता हूँ कि standard में इस बात की limit हो कि एक graphic unit में कितने Unicode scalar values आ सकते हैं। आख़िरी बार जब मैंने देखा था (हालाँकि कुछ साल पहले), standard में ऐसी कोई limit नहीं थी; इसके बजाय streaming applications के लिए केवल यह recommendation थी कि graphic unit को 128 bytes तक सीमित करें। अगर standard में ऐसी सीमा स्पष्ट रूप से हो, तो implementation बहुत आसान हो जाएगी और अनावश्यक restrictions भी नहीं लगेंगी

  • मैंने वास्तव में ऐसे cases देखे हैं जहाँ program इस धारणा पर लिखा गया था कि "कोई control characters नहीं हैं" और वह टूट गया (form feed page separation के लिए, escape characters terminal purposes के लिए आम हैं)। "सब कुछ UTF-8 है" वाली धारणा भी टूटती रहती है (पुरानी data files, logs आदि)। अगर आप text पर अर्थपूर्ण processing नहीं कर रहे, तो सबसे अच्छा है कि content को बिना बदले सिर्फ byte sequence की तरह pass through कर दें। लेकिन Microsoft Windows की वजह से कभी-कभी char16_t sequences pass करने पड़ते हैं। UTF-16, UTF-8 से I/O के लिहाज़ से मूलभूत रूप से अलग है। conversion के समय external data → internal form बदलते हुए क्रमशः WTF-8 (UTF-16) और surrogate escape (UTF-8) approach का उपयोग करना चाहिए। इन दोनों approaches को मिलाया नहीं जा सकता