Que se passe-t-il avec ces caractères combinant Unicode et comment pouvons-nous les filtrer?

91

กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้

Ceux-ci sont récemment apparus dans les sections de commentaires Facebook.

Comment pouvons-nous désinfecter cela?

XCS
la source
5
N'avez-vous pas posé cette question auparavant? (Question honnête.)
Ry-
5
Ce ne sont certainement pas des ascii
Chris Eberle
31
Pourquoi les votes de clôture? C'est une question liée à la programmation, car je veux savoir comment nettoyer ce type d'entrée afin que les sections de commentaires sur mon site Web ne soient pas le terrain de jeu des 13 ans ...
XCS
17
กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิ "donc les sections de commentaires sur mon site Web ne seront pas le terrain de jeu des 13 ans." En fait, sans désinfection, la publication de ces caractères peut rendre le commentaire au-dessus illisible, ce qui n'est pas du tout une expérience utilisateur agréable.
XCS
14
@pjotr Ce n'est certainement pas un bogue de navigateur. Si vous voulez que les caractères ne débordent pas de la boîte contenant, vous pouvez simplement résoudre cela avec CSS (overflow: hidden;) ...
XCS

Réponses:

80

Que se passe-t-il avec ces caractères Unicode?

C'est un personnage avec une série de personnages combinés . Parce que les caractères de combinaison en question veulent aller au-dessus du caractère de base, ils s'empilent (littéralement). Par exemple, le cas de

ก้้้้้้้้้้้้้้้้้้้้

... c'est un ก (caractère thaï ko kai ) ( U + 0E01 ) suivi de 20 copies du caractère combinant thaïlandais mai tho ( U + 0E49 ).

Comment pouvons-nous désinfecter cela?

Vous pouvez prétraiter le texte et limiter le nombre de caractères de combinaison pouvant être appliqués à un seul personnage, mais l'effort ne vaut peut-être pas la peine. Vous auriez besoin des fiches techniques pour tous les caractères actuels afin de savoir s'ils se combinent ou quoi, et vous devez vous assurer d'en autoriser au moins quelques-uns car certaines langues sont écrites avec plusieurs signes diacritiques sur une seule base . Désormais, si vous souhaitez limiter les commentaires au jeu de caractères latins, ce serait une vérification de plage plus facile, mais bien sûr, ce n'est qu'une option si vous souhaitez limiter les commentaires à quelques langues. Plus d'informations, feuilles de code, etc. sur unicode.org .

BTW, si vous voulez savoir comment un personnage a été composé, pour une autre question, j'ai récemment codé une page "Unicode Show Me" rapide et sale sur JSBin. Il vous suffit de copier et coller le texte dans la zone de texte, et cela vous montre tous les points de code (~ caractères) dont le texte est composé, avec des liens tels que ceux ci-dessus vers la page décrivant chaque caractère. Cela ne fonctionne que pour les points de code dans la plage U + FFFF et moins, car il est écrit en JavaScript et pour gérer les caractères au-dessus de U + FFFF en JavaScript, vous devez faire plus de travail que je ne le souhaitais pour cette question (car en JavaScript, un "caractère" est toujours 16 bits, ce qui signifie que pour certaines langues, un caractère peut être divisé en deux "caractères" JavaScript distincts et je n'ai pas tenu compte de cela), mais c'est pratique pour la plupart des textes ...

TJ Crowder
la source
1
Ne supprimeriez-vous pas simplement des copies répétées du même point de code combinant dos à dos en une seule copie? Quand auriez-vous besoin de combiner le même point de code sur un point de code de base plus d'une fois?
Remy Lebeau
4
@RemyLebeau: "Quand auriez-vous besoin de combiner le même codet sur un codet de base plus d'une fois?" Je ne sais pas, je sais très très peu de choses sur la façon dont vous écrivez d'autres langues - le thaï, par exemple. Je ne serais pas du tout surpris de découvrir que plus d'un point de code identique était valide dans certains. Mais faire cela ne réduit pas la complexité; vous avez toujours besoin de l'une des tables Unicode pour déterminer lesquelles combinent des caractères.
TJ Crowder
J'ai fait accepter à votre page la chaîne Unicode de l'url, par exemple jsbin.com/erajer/7/…
ubershmekel
2
Bibliothèque JavaScript pour supprimer facilement les marques de combinaison Unicode des chaînes: mths.be/stripcombiningmarks
Mathias Bynens
JavaScript utilise UTF-16 avec des « paires de substitution »
dolmen
17

Si vous avez un moteur regex avec un support Unicode décent, il est trivial de nettoyer ce type de chaînes. En Perl, par exemple, vous pouvez supprimer tout sauf la première marque de combinaison de chaque caractère (perçu par l'utilisateur) comme ceci:

#!/usr/bin/perl
use strict;
use utf8;

binmode(STDOUT, ':utf8');

my $string = "กิิ ก้้ ก็็ ก็็ กิิ ก้้ ก็็ กิิ ก้้ กิิ ก้้ ก็็ ก็็ กิิ ก้้ ก็็ กิิ ก้้";
$string =~ s/(\p{Mark})\p{Mark}+/$1/g; # Strip excess combining marks
print("$string\n");

Cela imprimera:

กิ ก้ ก็ ก็ กิ ก้ ก็ กิ ก้ กิ ก้ ก็ ก็ กิ ก้ ก็ กิ ก้

nwellnhof
la source
9
Je ne peux pas lire le tibétain, mais je crains que cette approche par force brute puisse supprimer des fonctionnalités de la façon dont le langage est conçu. J'ai vu unicode qui a des cas d'utilisation légitimes de plus d'une marque de combinaison. L'arabe est un bon exemple. J'essaierai de me rappeler de diriger ceci par mes collègues tibétains.
FlipMcF
2
Vous avez raison, il y a certainement des cas où plusieurs marques de combinaison sont légitimes. Mais vous pouvez facilement changer l'expression régulière pour autoriser un certain maximum de notes.
nwellnhof
Voté parce qu'il répond à la question «comment désinfecter cette question». Mais je pense que ce serait un cauchemar de maintenance.
FlipMcF
En outre, le RE supprime simplement la duplication adjacente . Il ne serait pas nettoyer, par exemple: <base><macron><overline><macron><overline>.... Donc, si votre texte a besoin de plusieurs caractères de combinaison différents , il passera bien; et du texte malveillant pourrait encore être créé.
Jesse Chisholm
13

"Comment pouvons-nous désinfecter cela" est mieux répondu ci-dessus par TJ Crowder

Cependant, je pense que la désinfection est la mauvaise approche, et Cristy a raison avec overflow:hiddenl'élément contenant le css.

Du moins, c'est comme ça que je résous le problème.

FlipMcF
la source
6

Ok celui-ci m'a pris du temps à comprendre, j'avais l'impression que combiner des personnages pour produire du zalgo se limitait à ceux-ci . Je m'attendais donc à ce que les regex suivantes attrapent les monstres.

([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]{2,})

et ça n'a pas marché ...

Le hic, c'est que la liste du wiki ne couvre pas la gamme complète de combinaisons de caractères.

Ce qui m'a donné un indice, c'est "ก้้้้้้้้้้้้้้้้้้้้".charCodeAt(2).toString(16)= "e49" qui, en dehors d'une plage de combinaison, tombe dans «Usage privé».

En C #, ils tombent sous UnicodeCategory.NonSpacingMarket le script suivant les élimine:

    [Test]
    public void IsZalgo()
    {
        var zalgo = new[] { UnicodeCategory.NonSpacingMark };

        File.Delete("IsModifyLike.html");
        File.AppendAllText("IsModifyLike.html", "<table>");
        for (var i = 0; i < 65535; i++)
        {
            var c = (char)i;
            if (zalgo.Contains(Char.GetUnicodeCategory(c)))
            {


                File.AppendAllText("IsModifyLike.html", string.Format("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>A&#{3};&#{3};&#{3}</td></tr>\n",  i.ToString("X"), c, Char.GetUnicodeCategory(c), i));

            }
        }
        File.AppendAllText("IsModifyLike.html", "</table>");
    }

En regardant la table générée, vous devriez être en mesure de voir lesquels se superposent. Une plage qui manque sur le wiki en est 06D6-06DCune autre 0730-0749.

METTRE À JOUR:

Voici une regex mise à jour qui devrait pêcher tous les zalgo, y compris ceux contournés dans la plage `` normale ''.

([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F\u0483-\u0486\u05C7\u0610-\u061A\u0656-\u065F\u0670\u06D6-\u06ED\u0711\u0730-\u073F\u0743-\u074A\u0F18-\u0F19\u0F35\u0F37\u0F72-\u0F73\u0F7A-\u0F81\u0F84\u0e00-\u0eff\uFC5E-\uFC62]{2,})

Le plus difficile est de les identifier, une fois que vous avez fait cela - il existe une multitude de solutions, y compris certaines bonnes ci-dessus.

J'espère que cela vous fera gagner du temps.

Matas Vaitkevicius
la source
Je dirais, ne pas spammer ce spam!
Praveen Kumar Purushothaman
@PraveenKumar Voulez-vous préciser ce que vous voulez dire?
Matas Vaitkevicius
J'apprécie votre réponse, mais c'est une question sans réponse. Alors pourquoi ajouter de nouvelles réponses inutilement? C'est juste mon avis. De plus, votre réponse n'est pas JavaScript, non?
Praveen Kumar Purushothaman
4
@PraveenKumar Il découvre pourquoi la validation normale de zalgo ([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]{2,})ne fonctionne pas. Ne trouvez-vous pas intéressant que l'empilement d'unicode ne se limite pas à ce qui se trouve sur le wiki? Qu'entendez-vous par «question à réponse perdue»? EDIT : Vous pourriez trouver étrange d'ajouter une réponse à une question de 3 ans, mais comme il m'a fallu un certain temps pour comprendre pourquoi ce type de zalgo fonctionnait, je ne pouvais pas laisser une telle connaissance se perdre. Le prochain gars gagnera du temps.
Matas Vaitkevicius
7
@PraveenKumar la question n'indique pas de langue, et poster une nouvelle réponse sur une ancienne question est tout à fait approprié si les anciennes réponses étaient déficientes d'une manière ou d'une autre. Malheureusement, je n'ai pas assez d'expérience avec ce problème, sinon il obtiendrait un vote favorable de ma part.
Mark Ransom