Neulich bat mich ein Kollege auf der Arbeit kurz um Hilfe. Ihm war ein komisches Phänomen aufgefallen. Er wollte ein SQL update Statement auf eine Integer Spalte einer SQL Datenbank ausführen. Doch SQL zeigte ihm nur eine seltsame Fehlermeldung. Den Integer hatte er zuvor mit Hilfe des in Windows eingebauten Taschenrechners berechnet.
mysql> UPDATE auth_token SET version = '1200' where id = 2;
ERROR 1265 (01000): Data truncated for column 'version' at row 1
Auffällig war auch, wurde die Zahl mit Hilfe von STRG-C aus dem Taschenrechner kopiert oder war die Zahl kleiner als 1000 funktionierte alles einwandfrei. Auch wenn man die Zahl von Hand eingab funktionierte es. Der Taschenrechner musste also irgend ein Zeichen an die Zahl hängen. Also ließen wir uns die Base64 Repräsentation der Zeichenkette anzeigen.
Aus dem Taschenrechner kopiert:
tecbauer@XELO:~$ echo -n "1200" | base64
MTIwMOKArg==
Von Hand eingegeben:
tecbauer@XELO:~$ echo -n "1200" | base64
MTIwMA==
Eindeutig. Die zwei Zeichenketten waren unterschiedlich. Um nun herauszufinden um welches Zeichen es sich handelte öffneten wir den Vim-Editor und stellten ihn auf :set list
um. Nun fügten wir die Zeichenkette ein. Und da war unser Sonderzeichen:
<202e>
… Doch was bedeutet dieses Zeichen und warum sollte es vom Windows Taschenrechner an das Ergebnis angefügt werden? Nach kurzer Recherche fanden wir heraus, dass das Zeichen ein Unicode Zeichen ist für den RIGHT-TO-LEFT OVERRIDE ist. Nachdem wir uns dann die Zahl im Taschenrechner noch einmal anschauten war uns die Sache klar.
Der Taschenrechner setzt Tausender Punkte. Um zu errechnen an welcher Stelle ein Punkt gesetzt werden muss, müsste er wenn er von Links nach Rechts schreibt (wie üblich), den Ersten Punkt nach dem 1. Zeichen setzen. Um dies zu wissen müsste man aber eine Modulo-Rechnung machen nur um festzustellen wo Punkte gesetzt werden sollen. Dies umgeht der Taschenrechner, in dem er die Zahl reverse schreibt. Dann kann nämlich nach jedem dritten Zeichen einfach ein Punkt gesetzt werden. Leider wurde vergessen am Ende das entsprechende Unicode-Zeichen dafür zu entfernen.