Introduction from RFC 3454, "Preparation of Internationalized Strings":

This document describes a framework for preparing Unicode text
strings in order to increase the likelihood that string input and
string comparison work in ways that make sense for typical users
throughout the world.  The stringprep protocol is useful for protocol
identifier values, company and personal names, internationalized
domain names, and other text strings.


psyced supports stringprep and resourceprep functions as required by XMPP. They allow you to use any unicode characters in JIDs and provide for comparison logic. This is kind of neat, but can be a source of trouble when you are supposed to talk to someone with a chinese JID from a french keyboard (if the JID is on a piece of paper and you need to get it materialized on the screen for example).

PSYC instead is inclined to allow uniforms and non-local nicknames in ASCII only, thus accepting a simple lower_case() operation for safe comparison. See also Uniform#Legal characters in resource names. This isn't the most politically correct approach maybe, but it makes things faster, simpler and maybe a bit safer in everyday use. It may have to handle funny looking xmpp: uniforms however.

The decision on this topic isn't final though. The rest of this document is details and discussion held in german.

Contents

wozu ist das gut

Das ganze ist Teil der i18n-Bestrebungen und soll dafür sorgen, dass, wenn der User etwas eingibt, das wichtig fürs Protokoll ist er auch annährend das rausbekommt, was er will.

Eins der wichtigsten Features ist, dass es bei einigen Profilen 'case folding' betreibt, was ne Umschreibung dafür ist, dass es ein unicodefähiges lower_case() ist.

wie funktioniert das

Setzt sich aus verschiedenen Tabellen und Profilen zusammen, die sagen, wie die Abbildung verläuft (für saga: das sind matrizen, allerdings nicht invertierbar) Die wichtigsten:

  • nameprep macht schon einiges von dem idna-Kram, e.g. das mapping von ßßß.example.com zu ssssss.example.com, kümmert sich aber noch nicht um punycode
  • saslprep macht gewisse Zeichen in Passwörter gleich. Also endlich richtig fiese Sonderzeichen ohne Angst vorm Urlaub.
  • xmpp-Nodeprep 'normalisiert' die Usernamen in einer Art und Weise, die wir wohl für psyc unverändert übernehmen können:
    • Fippo -> fippo (ja, es lowercase't!)
    • aß -> ass
    • a² -> a2
  • xmpp-resourceprep macht essentiell das gleiche wie nodeprep, nur case-sensitive, außerdem sind whitespace und diverse andere Sachen hier erlaubt

ldmud-Implementierung

Performancemäßig sind die Dinger ein wenig aufwand, 500.000 Aufrufe von nameprep dauern 73 Sekunden, wobei ich potentiell einmal zuviel xalloce, sich die Performance also nur verbessern kann. Aber lässt sich glaub ich verschmerzen. Implementierung ist prinzipiell fertig, ich muss Lars noch wegen besagtem alloc fragen und dann sollte das zusammen mit punycode-Funktionalität (das ist beides Part von libidn) schnell in den Driver fliegen. Ich mag Sachen, die sich an einem Abend wuppen lassen.

Einsatzbereiche im muve

net/jabber, sonst sind wir noch die letzten, die das implementieren :-) Ist übrigens bei vorhandensein der efun aktiviert und funktioniert hervorragend. Bis auf die Tatsache, dass der restliche muve als 'achsel_schweiss' und 'achsel_schweiß' für verschiedene Leute hält.

<lynX> Ich dachte der Typ heisst Axel.. aber in der tat sind das unterschiedliche Nachnamen, denn der eine schwitzt und der andere schweisst. Auch "Fuß" und "fuss" haben total unterschiedliche Semantik.

critique

saga:
ich bin da vielleicht etwas unsensibel, weil meine namen das allesamt einfach nicht nötig haben, aber ich bin der meinung (ausser für jabber, konformität ist schon etwas wichtig), dass wir das sonst nicht brauchen.
wenn irgendein netter chinese unbedingt seine mailadresse (oder seine psycuni) in kantonesisch will, dann, meinetwegen. dass kann man gerne einführen, nötigenfalls auch im muve. nur muss allen beteiligten dabei klar sein, dass ich keine kantonesischen mailadressen tippen kann und will. ich werde auch nicht (was fippo in PSYC mal als beispiel anführte) mir irgendeine charmap nehmen und mir ähnlich aussehende zeichen zusammensuchen, die von (mechanismen wie) stringprep dann normalisiert werden.

fragt sich also, ob wir den nicht durch [a-z]* ausdrückbaren personen eine adresse die ihrem namen entspricht, wirklich verwehren wollen.
wenn nicht, würde ich echte "aliase" (nicht im bisherigen psyc-sinn) durchaus akzeptieren, oder auch nur redirects von der englischen adresse zur kantonesischen, und und und. aber über stringprep würde ich das nicht machen, wirklich nicht.

fippo:
ok. Sobald wir es auf jabber-Seite supporten können wir uns durchaus dafür entscheiden, für PSYC restriktivere Maßstäbe anzulegen. Worauf wir achten sollten ist, dass im Rahmen unserer legal_nicks auch durchaus die durch net/jabber getroffene Einschränkung weiterhin sinnvoll ist, nicht dass lynXies muves mit ihrem umlaut-erlaubenden (speziell 'ß') legal_name auf die Fresse fliegen.

Und /alias bietet eine hervorragende Lösung fürs kantonesische... einmal mittels charmap zusammenklickern und dann glücklich sein. nichtsdestotrotz ist die Kritik an Sinn und Zweck der Aktion zwar berechtigt, aber das ist (noch) nicht unser Schlachtfeld. Ich muss zugeben, dass es lange her ist, seit ich nicht-ascii jabberids gesehen hab. Email hat hier ein Denkverhalten antrainiert.

<lynX> naja wir können mit ifdefs mal ein gefühl dafür bekommen wie sich das zeug anfühlt.. übrigens sind seit der utf8-isierung aller muves auch bei mir keine umlaute in nicknames mehr erlaubt.

canonicalization && case preservation

Also... die Jabber-Theorie besagt, dass man das Zeug nur zum Vergleichen kanonifiziert. In die Pakete schreibt man weiterhin die nicht-kanonische Fassung rein, was vor allem eine Beibehaltung der Groß/Kleinschreibung im Hostnamen und User-Part bedeutet. Wir fahren eine andere Strategie: wir machen ganz an der Ecke einmal kanon und scheren uns intern überhaupt nicht um das Zeug. Solang wie die andere Seite der Spec folgt entstehen daraus keine Probleme.

  • Nachteil: wir verlieren case
  • Vorteil: wir brauchen das Zeug nur ein einziges Mal zu machen und nicht bei jedem Vergleich.

Potentielle Lösung: der ldmud-stringstruktur ein normalized_unicode Feld zustecken, bei stringprep() dieses setzen und bei Vergleichen zuerst damit rumpfuschen. Aufwand steht jedoch in keinem Verhältnis zum Nutzen.

<lynX> Andere Möglichkeit: Ich hatte mal den Plan ins Auge gefasst, ferne Objekte nicht mehr an Ihrer Uniform (string) herumzureichen, sondern an dem geparsten Uniform-Array gemäß parse_uniform (äh parseURL heisst das noch). Da würde dann sorgenlos ein Feld für die abnormte Version, reinpassen welche dann für Vergleiche herdient. Also #define UNorm ins url.h und los. Schade, dass man wieder den halben psyced rewriten muss, um URL-Arrays generell statt Uniformen handhaben zu können.

Conclusion

psyced uses this to implement XMPP requirements correctly while nicknames in PSYC are currently limited in choice such that stringprep is not necessary.

see also