Ce document est une traduction du document RFC 5137 de l'IETF (Internet Engineering Task Force) ; il peut comporter des erreurs ou en introduire de nouvelles. Seul fait référence l'original disponible à ftp://ftp.rfc-editor.org/in-notes/rfc5137.txt.
La traduction est proposée sous licence Creative Commons.
Date de publication : 12 décembre 2008.

RFC 5137

Network Working Group                                         J. Klensin
Document RFC : 5137 (errata)                                Février 2008
BCP          : 137                                                      
Categorie    : Best Current Practice                                    

Échappement ASCII des caractères Unicode

Statut de ce mémoire

Ce document spécifie une pratique exemplaire courante Internet pour la communauté Internet, et il appelle le débat et des suggestions d'amélioration. La distribution de ce mémoire est libre.

Résumé

Dans certaines circonstances, il est nécessaire d'avoir un mécanisme d'échappement (escape mechanism) conjointement à un protocole pour coder les caractères qui ne peuvent pas être représentés ou transmis directement. Avec le codage ASCII, l'échappement traditionnel a été la valeur numérique décimale ou bien hexadécimale du caractère, écrite de plusieurs façons différentes. Le passage à Unicode, où les caractères occupent deux octets ou plus et peuvent être codés de plusieurs façons différentes, a compliqué encore la question des échappements. Ce document discute des options disponibles actuellement et des considérations pour en sélectionner un à utiliser dans les nouveaux protocoles IETF et les protocoles en cours d'internationalisation.

Table des matières

  1. 1. Introduction
    1. 1.1. Contexte et arrière-plan
    2. 1.2. Terminologie
    3. 1.3. Liste de discussion
  2. 2. Codages représentant des points de code Unicode — Position de code contre octets UTF-8 ou UTF-16
  3. 3. Appel des caractères Unicode
  4. 4. Syntaxe des échappements de point de code
  5. 5. Variantes de présentation recommandées pour les échappements de points de code Unicode
    1. 5.1. Barre oblique inverse-U avec délimiteurs
    2. 5.2. XML et HTML
  6. 6. Formes normalement non recommandées
    1. 6.1. Le langage de programmation C : barre oblique inverse-U
    2. 6.2. Perl : une chaîne hexadécimale
    3. 6.3. Java : UTF-16 échappé
  7. 7. Observations sur la sécurité
  8. 8. Remerciements
  9. 9. Références
    1. 9.1. Références normatives
    2. 9.2. Références informatives
  10. Annexe A — Syntaxe formelle des formes non recommandées
    1. A.1. La forme du langage de programmation C
    2. A.2. La forme Perl
    3. A.3. La forme Java

1. Introduction

1.1. Contexte et arrière-plan

Dans certaines circonstances, un mécanisme d'échappement est nécessaire conjointement à un protocole pour coder les caractères qui ne peuvent pas être représentés ou transmis directement. Avec le codage ASCII [ASCII], l'échappement traditionnel a été la valeur numérique décimale ou bien hexadécimale du caractère, écrite de plusieurs façons différentes. Par exemple, dans des contextes différents, nous avons vu %dNN ou %NN pour la forme décimale, %NN, %xNN, X'nn' et %X'NN' pour la forme hexadécimale. La forme "%NN" est devenue habituelle ces dernières années pour représenter une valeur hexadécimale sans autre qualification, peut-être à cause de son utilisation dans les adresses URL et leur prévalence. Il existe même encore des applications qui utilisent des formes octales et, bien qu'elles ne soient pas entièrement généralisables, on peut voir les formes MIME « guillemets imprimables » (Quoted-Printable) et « mots codés » (Encoded-word) comme encore un autre ensemble d'échappements. Ainsi, même pour les cas assez simples du codage ASCII et d'un standard élaboré par extension d'ASCII, tel que la famille de codes ISO 8859, nous avons vécu avec plusieurs formes d'échappement différentes, chacune avec une histoire.

Lorsque l'on passe à Unicode [Unicode] [ISO10646], où les caractères occupent deux octets ou plus et peuvent être codés dans plusieurs formes différentes, la question des échappements se complique encore. Unicode représente les caractères par des points de code (code points) : des valeurs numériques hexadécimales de 0 à 10FFFF. Lorsque l'on appelle des points de code dans un flux de texte, ceux-ci sont représentés en utilisant la notation dite « U+ », comme des valeurs de U+0000 à U+10FFFF. Sérialisés en octets, ces poinst de code peuvent être représentés dans des formes différentes :

Pour l'échappement des caractères, nous avons constaté une utilisation quasi générale des représentations hexadécimales à la fois des formes sérialisées et de variations de la notation U+, connue sous le nom d'échappements de point de code (code point escapes).

Conformément aux recommandations de pratiques exemplaires [RFC2277], les nouveaux protocoles obligés de transporter du contenu textuel pour une lecture humaine DEVRAIENT être conçus de façon à pouvoir représenter le répertoire entier des caractères Unicode de ce texte.

La proposition de ce document est que les protocoles existants en cours d'internationalisation et ceux qui ont besoin d'un mécanisme d'échappement DEVRAIENT utiliser une variation appropriée selon le contexte pour les références aux points de code, comme décrit à la section 2, sauf si d'autres considérations l'emportent sur celles décrites ici.

Cette recommandation ne s'applique pas aux protocoles qui intègrent déjà UTF-8 ou un autre codage d'Unicode. En général, lorsque les protocoles sont internationalisés, il est préférable d'accepter ces formes plutôt que d'utiliser des échappements. Cette recommandation s'applique aux cas, y compris les arrangements de transition, où cela n'est pas pratique.

Outre les contextes de protocoles traités dans cette spécification, les échappements pour représenter des caractères Unicode apparaissent aussi dans les présentations aux utilisateurs, c'est-à-dire dans les interfaces utilisateurs (user interfaces). Les formats spécifiés dans ce document et le raisonnement qui y est observé peuvent aussi s'appliquer aux contextes d'interface utilisateur mais il ne s'agit pas d'une proposition pour normaliser l'interface utilisateur ou les formes de présentation.

Ce document ne fait aucune recommandation générale pour le traitement des chaînes Unicode ou leur contenu. Il suppose des chaînes à échapper qu'elles soient valides et raisonnables, la définition du « valide et du raisonnable » incombant à d'autres documents. On pourra trouver des recommandations de traitement général des chaînes Unicode à beaucoup d'endroits, y compris dans le standard Unicode même et le modèle de caractères du W3C [W3C-CharMod], ainsi que dans des règles spécifiques de protocoles particuliers.

1.2. Terminologie

Les mots-clés « DOIT », « NE DOIT PAS », « OBLIGATOIRE », « DEVRA », « NE DEVRA PAS », « DEVRAIT », « NE DEVRAIT PAS », « RECOMMANDÉ », « PEUT » et « OPTIONNEL » dans ce document doivent s'interpréter comme décrit dans le document [RFC2119].

Une terminologie supplémentaire propre à Unicode apparaît dans le document [UnicodeGlossary], mais elle n'est pas nécessaire pour comprendre cette spécification.

1.3. Liste de discussion

Les commentaires à propos de ce document devraient être adressés à la liste de diffusion discuss@apps.ietf.org.

2. Codages représentant des points de code Unicode — Position de code contre octets UTF-8 ou UTF-16

Il existe principalement deux façons d'échapper les caractères Unicode. L'une utilise le point de code dans une certaine représentation (cf. la section suivante), l'autre code les octets du codage UTF-8 ou d'un autre codage dans une certaine représentation. D'autres options sont possibles mais rares dans la pratique. Sauf raisons irrésistibles de faire autrement, la recommandation de cette spécification est que l'on DEVRAIT utiliser les points de code Unicode plutôt qu'une représentation d'octets UTF-8 (ou UTF-16). À cela, plusieurs justifications :

Les mêmes considérations concernant la représentation des octets du codage UTF-8 s'appliquent aussi aux codages ACE plus compacts tels que le codage bootstring [RFC3492] avec ou sans son profil Punycode.

Des considérations similaires s'appliquent au codage UTF-16, comme la forme \uNNNN utilisée en Java (cf. la section 6.3). Bien que ces formes soient équivalentes aux références de point de code du Plan Multilingue de Base (PMB, plan 0), un processus de décodage en deux étapes est nécessaire pour traiter les caractères de substitution (surrogates) et accéder aux plans supérieurs.

3. Appel des caractères Unicode

Indépendamment des choix d'échappement des caractères Unicode dans les environnements de protocole ou similaires, le texte appelant un point de code Unicode DEVRAIT employer la syntaxe U+NNNN[N[N]], comme spécifié dans le standard Unicode, où la chaîne NNNN... se compose de nombres hexadécimaux. Un texte qui contient réellement un caractère Unicode DEVRAIT employer une syntaxe plus appropriée au traitement automatique.

4. Syntaxe des échappements de point de code

Il existe plusieurs options d'échappement des points de code, dont quelques unes sont résumées ci-dessous. Toutes sont équivalentes pour le contenu et la sémantique, les différences tiennent à la synaxe. Le choix de la meilleure syntaxe pour un protocole particulier ou une autre application dépend de cette application : une forme peut simplement mieux « convenir » dans un contexte donné que d'autres. Il est clair néanmoins que les valeurs hexadécimales sont préférables aux autres valeurs : on NE DEVRAIT PAS utiliser de systèmes fondés sur des décalages (offsets) décimaux ou octaux.

Puisque cette spécification ne recommande pas de syntaxe particulière, les spécifications de protocoles qui utilisent des échappements DOIVENT définir la syntaxe employée, y compris les échappements nécessaires qui permettent l'utilisation littérale de la séquence d'échappement.

Le créateur de l'application devrait au moins considérer les facteurs suivants pour sélectionner un format :

5. Variantes de présentation recommandées pour les échappements de points de code Unicode

Il y a plusieurs façons différentes de représenter une position de point de code Unicode. Aucune n'apparaît la « meilleure » pour tous les contexte. En outre, lorsqu'il faut un échappement pour le mécanisme d'échappement même, le mécanisme optimal peut différer d'un contexte à l'autre.

Certaines formes couramment utilisées et dont on peut raisonnablement envisager l'emploi dans un protocole donné sont décrites ci-dessous et identifiées dans un contexte d'utilisation actuel lorsque c'est faisable. Les deux formes de cette section sont recommandées pour l'utilisation dans les protocoles Internet. D'autres formes populaires apparaissent à la section 6 avec un exposé de leurs inconvénients.

5.1. Barre oblique inverse-U avec délimiteurs

L'une des formes recommandées est une variation issue des nombreuses formes commençant par « \u » (cf. par exemple la section 6.1 ci-dessous), mais utilisant des délimiteurs explicites pour les raisons exposées ailleurs.

Spécifiquement, en notation ABNF [RFC5234] :

   EmbeddedUnicodeChar =  %x5C.75.27 4*6HEXDIG %x27
      ; commençant par "\u" en minuscule et finissant par "'".
      ; Notez que les codages sont considérés comme étant des
      ; abstractions des caractères concernés, pas des
      ; désignations d'octets spécifiques.

   HEXDIG =  "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
      "A" / "B" / "C" / "D" / "E" / "F"
      ; en fait identique à la définition dans le RFC 5234.

Les créateurs de protocoles d'applications utilisant cette forme devraient définir une méthode pour échapper la BARRE OBLIQUE INVERSE « \ » d'introduction, si besoin. Une possibilité évidente est « \\ » mais ce n'est pas la seule.

5.2. XML et HTML

L'autre forme recommandée est celle employée dans XML. Elle utilise la forme &#xNNNN;. Comme la forme Perl (section 6.2), cette forme a un délimiteur de fin clair, réduisant l'ambiguïté. HTML emploie une forme similaire mais le POINT-VIRGULE peut être omis dans certains cas. Auquel cas, les avantages du délimiteur disparaissent, donc on NE DEVRAIT PAS utiliser la forme HTML sans le POINT-VIRGULE. En revanche, ce format est souvent considéré comme étant laid et embarassant hors de son HTML d'origine, de XML et de contextes similaires.

En ABNF :

   EmbeddedUnicodeChar =   %x26.23.78 2*6HEXDIG %x3B
      ; commence par "&#x" et finit par ";"

Notez que l'on peut exprimer un caractère littéral « & » par « & » en utilisant ce style.

6. Formes normalement non recommandées

6.1. Le langage de programmation C : barre oblique inverse-U

Les formes suivantes :

      \UNNNNNNNN (pour tout caractère Unicode) et

      \uNNNN (pour les caractères Unicode dans le plan 0)

sont utilisées dans le langage de programmation C [ISO-C] lorsqu'un échappement ASCII pour les caractères Unicode incorporés est nécessaire.

Cette forme présente des inconvénients qui peuvent être importants. D'abord, une variation de casse (entre « u » pour la forme à quatre chiffres et « U » pour la forme à huit chiffres) peut sembler artificielle dans des environnements où les caractères en majuscules et en minuscules sont considérés généralement comme équivalents et pourrait embrouiller les personnes non accoutumées aux alphabets latins (même si ces personnes auraient encore plus de difficultés à lire le texte et les explications anglaises afférentes). Ensuite, comme discuté à la section 4, le simple fait qu'il y ait plusieurs conventions différentes commençant par \u ou \U est source d'erreurs pour les personnes, à faire de fausses suppositions sur ce qu'elles voient.

6.2. Perl : une chaîne hexadécimale

Perl emploie la forme \x{NNNN...}. L'avantage de cette forme tient à la présence de délimiteurs explicites, ce qui résout la question des chaînes de longueur variable ou de l'utilisation du mécanisme de changement de casse de la forme proposée pour distinguer le plan 0 des formes plus générales. D'autres langages de programmation tendraient à favoriser les formes X'NNNN...' pour les chaînes hexadécimales et peut-être U'NNNN...' pour les chaînes Unicode spécifiques, mais ces formes ne semblent pas employées dans le milieu IETF.

Notez que cette notation présente une ambiguïté possible dans la façon de comprendre deux caractères ou bien les séquences de petits numéros (low-numbered sequences), c'est-à-dire que les octets dans l'intervalle \x(00) à \x(FF) sont susceptibles d'être interprétés comme étant dans le jeu de caractères local, et non comme des points de code Unicode. À cause de cette ambiguïté apparente et parce que les documents IETF ne contiennent aucune disposition pour les pragmas (cf. [PERLUniIntro] pour plus d'informations à propos du pragma encoding dans Perl et d'autres détails), on devrait utiliser la forme Perl avec extrêmement de précaution, si ce n'est pas du tout.

6.3. Java : UTF-16 échappé

Java [Java] emploie la forme \uNNNN, mais comme référence aux valeurs UTF-16, et non aux points de code Unicode. Quoique la forme utilise une syntaxe similaire à celle décrite à la section 6.1, cette relation à UTF-16 la rend, à beaucoup d'égards, plus proche des codages de UTF-8 vus précédemment que d'un échappement désignant des points de code Unicode. Notez que la forme UTF-16, et donc la notation d'échappement Java, peut seulement représenter des caractères hors du plan 0 (c'est-à-dire au-delà de U+FFFF) en utilisant des paires de substitution, ce qui soulève des problèmes identiques à ceux des octets UTF-8 vus ci-dessus. Pour les caractères dans le plan 0, la forme Java est impossible à distinguer de la forme plan 0 seule décrite à la section 6.1. Ne serait-ce que pour cette raison, on NE DEVRAIT PAS l'utiliser comme forme d'échappement, hormis dans les contextes Java où elle est naturelle.

7. Observations sur la sécurité

Ce document propose un ensemble de règles pour coder les caractères Unicode hors autres considérations. Puisque tous les codages recommandés ne présentent aucune ambiguïté et que ne sont pas impliquées de questions de normalisation, cela ne devrait pas introduire de problèmes de sécurité, qui ne seraient pas déjà présents, du simple fait de l'utilisation de caractères non-ASCII, quelle que soit la façon de les coder. Les mécanismes suggérés devraient permettre de réduire légèrement les risques d'embrouiller les utilisateurs avec des caractères codés, en identifiant plus clairement les caractères utilisés que ne le feraient les autres mécanismes.

Un mécanisme d'échappement tel que celui spécifié dans ce document autorise plusieurs représentations des caractères. Lorsqu'un logiciel interprète la forme échappée, le risque existe que les contrôles de sécurité et tous les contrôles nécessaires aient lieu au mauvais endroit.

8. Remerciements

Ce document répond à une série de discussions au sein du domaine Applications de l'IETF et dans le cadre de l'internationalisation des courriers électroniques et des mises à jour des noms de domaine internationalisés. C'est la synthèse d'un grand nombre de discussions, des commentaires des participants qui sont vivement remerciés. L'aide de Mark Davis pour l'élaboration d'une liste des autres présentations et leur sélection fut déterminante.

Tim Bray, Peter Constable, Stephane Bortzmeyer, Chris Newman, Frank Ellermann, Clive D.W. Feather, Philip Guenther, Bjoern Hoehrmann, Simon Josefsson, Bill McQuillan, der Mouse, Phil Pennock et Julian Reschke ont relus soigneusement, apportés des corrections et faits des suggestions aux divers brouillons qui ont précédé ce document. Globalement, leurs suggestions ont motivé la révision majeure du document entre les versions -00 et -01, et les autres améliorations dans les versions qui ont suivi.

9. Références

9.1. Références normative

[ISO10646]
International Organization for Standardization, "Information Technology -- Universal Multiple-Octet Coded Character Set (UCS)", ISO/IEC 10646:2003, December 2003.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC3629]
Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.
[RFC5234]
Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
[Unicode]
The Unicode Consortium, "The Unicode Standard, Version 5.0", 2006. (Addison-Wesley, 2006. ISBN 0-321-48091-0).

9.2. Références informatives

[ASCII]
American National Standards Institute (formerly United States of America Standards Institute), "USA Code for Information Interchange", ANSI X3.4-1968, 1968.
ANSI X3.4-1968 has been replaced by newer versions with slight modifications, but the 1968 version remains definitive for the Internet.
[ISO-C]
International Organization for Standardization, "Information technology -- Programming languages -- C", ISO/IEC 9899:1999, 1999.
[Java]
Sun Microsystems, Inc., "Java Language Specification, Third Edition", 2005, <http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#95413p>.
[PERLUniIntro]
Hietaniemi, J., "perluniintro", Perl documentation 5.8.8, 2002, <http://perldoc.perl.org/perluniintro.html>.
[RFC2277]
Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, January 1998.
[RFC3492]
Costello, A., "Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)", RFC 3492, March 2003.
[UnicodeGlossary]
The Unicode Consortium, "Glossary of Unicode Terms", June 2007, <http://www.unicode.org/glossary>.
[W3C-CharMod]
Duerst, M., "Character Model for the World Wide Web 1.0", W3C Recommendation, February 2005, <http://www.w3.org/TR/charmod/>.

Annexe A — Syntaxe formelle des formes non recommandées

Bien que l'on ne donne pas dans le texte la syntaxe des formes d'échappement non recommandées (cf. la section 6), dans l'espoir d'en décourager l'utilisation, on les fournit dans cette annexe dans l'espoir que ceux qui les utiliseront le feront avec discernement. Le lecteur est prévenu que certaines de ces formes ne sont pas définies précisément dans les spécifications originales et que d'autres ont évolué dans le temps d'une manière pas très cohérente. Par conséquent, ces définitions ne sont pas normatives et ne correspondront peut-être pas exactement aux interprétations raisonnables de leurs sources.

La définition de "HEXDIG" pour les formes qui suivent apparaît dans la section 5.1.

A.1. La forme du langage de programmation C

Spécifiquement, en ABNF [RFC5234] :

   EmbeddedUnicodeChar =  BMP-form / Full-form

   BMP-form  =  %x5C.75 4HEXDIG ; commençant par "\u" en minuscule
      ; Les codages sont vus comme des abstractions des caractères
      ; pertinents, pas comme des désignations d'octets spécifiques.

   Full-form =  %x5C.55 8HEXDIG ; commençant par "\U" en majuscule

A.2. La forme Perl

   EmbeddedUnicodeChar =   %x5C.78 "{" 2*6HEXDIG "}" ; commence par "\x"

A.3. La forme Java

   EmbeddedUnicodeChar =   %x5C.7A 4HEXDIG ; commence par "\u"

Coordonnées de l'auteur

John C Klensin
1770 Massachusetts Ave, #322
Cambridge, MA 02140
USA

Phone: +1 617 245 1457
EMail: john-ietf@jck.com