Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 170
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Jorg3000 »

Hi!
Heute habe ich keine Fragestellung, sondern das Ergebnis meiner heutigen Bastelei: In Dateinamen unerlaubte Zeichen durch ähnliche Unicode-Zeichen ersetzen. (Nachtrag: nur für den puren Dateinamen ohne Pfadangabe.)
Vielleicht hat jemand Verwendung dafür.

Die Absicht hinter meiner Function war nicht, eine Benutzereingabe für einen Dateinamen heimlich durch ähnliche Zeichen ersetzen, sondern eine frühere Titel-Eingabe, die noch nicht für einen Dateinamen gedacht war, nun als Dateinamen in einem SaveDialog vorzuschlagen.
Dazu wollte ich nicht einfach alle nicht erlaubten Zeichen radikal rauslöschen, sondern dem Benutzer eine erlaubte und lesbare Alternative für einen Dateinamen anbieten.

Code: Alles auswählen

function replaceReservedCharactersByUnicode(const aTextForFileName: UnicodeString; aMaxChar16Len: Integer=255): UnicodeString;
var i: SizeInt;
    w, Replace: Word;
begin
  Result:=Trim(aTextForFileName);

  for i:=1 to Length(Result) do
    begin
     w:=Word(Result[i]);
     if Hi(w)<>0 then Continue;
     case AnsiChar(Lo(w)) of
       #0..#31: Replace:=32;  // see below: remove double spaces
       '<': Replace:=$FE64;
       '>': Replace:=$FE65;
       ':': Replace:=$02D0;
       '"': Replace:=$201C;  // or simply a single quote instead?
       '/': Replace:=$2044;
       '|': Replace:=$2F01;
       '?': Replace:=$FE56;
       '*': Replace:=$FE61;
       '\': Replace:=$2216;
       else Continue;
     end;
     Result[i]:=WideChar(Replace);
    end;

  Result:=UnicodeStringReplace(Result,'  ',' ',[rfReplaceAll]);  // remove double spaces

  if (aMaxChar16Len>0) and (Length(Result)>aMaxChar16Len) then
    begin
      w:=Word(Result[aMaxChar16Len]);
      if (w>=$D800) and (w<=$DBFF)   // a high surrogate starting a 32 bit codepoint
        then SetLength(Result,aMaxChar16Len-1)
        else SetLength(Result,aMaxChar16Len);
      Result:=TrimRight(Result);
    end;
end;
String-Länge:
Meine Default-Begrenzung auf 255 Zeichen entspricht dem Maximum unter Windows, wo bis zu 255 UTF-16-Zeichen erlaubt sind.
Man findet zu Windows auch die Angaben max. 260 oder 256 Zeichen, wenn jedoch lange Pfade verwendet werden, sollen effektiv doch nur 255 UTF-16-Zeichen möglich sein. Das reicht ja auch.
In der Realität wird es dem Benutzer besser gefallen, wenn man ihm maximal 30 oder 40 Zeichen als Vorschlag anbietet.

Wer die Function mal testen möchte, kann es mit zwei Edit-Feldern ausprobieren:

Code: Alles auswählen

procedure TForm1.Edit1Change(Sender: TObject);
begin
  Edit2.Text := Utf8Encode( replaceReservedCharactersByUnicode(Edit1.Text, 20) );
end; 
Grüße, Jörg
Zuletzt geändert von Jorg3000 am Di 18. Jul 2023, 13:41, insgesamt 3-mal geändert.

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von wp_xyz »

Ganz schön fies, wenn es im Order c:\daten eine Datei "tests\test.dat" gibt, wobei statt '\' das #2216 im Dateinamen steht, und man versucht verzweifelt, auf der Kommandozeile die Datei c:\daten\tests\test.dat zu löschen, wobei man immer ein '\' eintippt.

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 170
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Jorg3000 »

Moin!
Wenn man jedes Zeichen von Hand eintippen/abtippen muss, sind die Unicode-Zeichen tatsächlich ungeeignet, da gebe ich dir recht!
In die Kommandozeile gibt man üblicherweise den Namen von Programmdateien oder programmseitig festgelegten Namen ein, aber ich kann mich nicht mehr erinnern, wann ich zuletzt den Namen einer von einem Benutzer gespeicherten/benannten Datei manuell(!) in die Kommandozeile tippen musste. Liegt wahrscheinlich daran, dass ich Windows nutze.
Wenn man Sorge hat, es von Hand abtippen zu müssen, verwendet man die Funktion tatsächlich besser nicht. Oder wenn man programmseitige Aufrufe verwendet, die kein UTF8/UTF16 unterstützen.
Grüße, Jörg

PS: Zum Eintippen dürfen einem auch keine ausländischen Dateinamen unterkommen, z.B. mit polnischen Extra-Buchstaben, kyrillischem Alphabet, usw.

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von h-elsner »

Path delimiter (PathDelim) würde ich aussparen, denn es kann ja gewünscht sein, die Datei in ein Unterverzeichnis zu speichern. Dies vielleicht optional als Schalter.

Wozu ist denn das else Continue im case? Hat das eine Bedeutung?

Gruß HE

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 170
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Jorg3000 »

h-elsner hat geschrieben:
Mo 17. Jul 2023, 08:05
Path delimiter (PathDelim) würde ich aussparen, denn es kann ja gewünscht sein, die Datei in ein Unterverzeichnis zu speichern.
Die Funktion soll nur auf einen puren Dateinamen ohne Pfadangabe angewendet werden.
Eine Pfadangabe mit einzubeziehen macht keinen Sinn, dafür habe ich es auch nicht gedacht. Ich habe die Info jetzt im ersten Post ergänzt.
h-elsner hat geschrieben:
Mo 17. Jul 2023, 08:05
Wozu ist denn das else Continue im case? Hat das eine Bedeutung?
Ja klar, wenn an der Stringposition keines der aufgezählten ASCII-Zeichen auftaucht, ist die Variable Replace nicht definiert. Dann wird die Schleife fortgesetzt, ohne dass das Zeichen ersetzt wird.
Grüße, Jörg

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 170
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Jorg3000 »

Fehlerkorrektur im Code:
Es hatte sich ein Flüchtigkeitsfehler eingeschlichen, es sollte

Code: Alles auswählen

#0..#31: Replace:=32;
heißen, NICHT Replace:=$0032;

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von theo »

Ich finde die Idee zwar lustig, aber ich habe da ähnliche Vorbehalte wie wp.
Solche "Tricks" treten einen früher oder später in den Hintern. :wink:

Ich meide auch heute noch Sonderzeichen und Unicode in Dateinamen, v.A. wenn es ums Internet bzw. verschiedene Servertypen geht und man dabei z.T. mit der Shell/Konsole unterwegs ist.

Mathias
Beiträge: 6210
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Mathias »

Ich meide auch heute noch Sonderzeichen und Unicode in Dateinamen, v.A. wenn es ums Internet bzw. verschiedene Servertypen geht und man dabei z.T. mit der Shell/Konsole unterwegs ist.
Ich meide nach Möglichkeit auch das Leerzeichen und ersetzte diese mit underline.
Mit anderen Worten ich verwende nur Zeichen, welche man bei Bezeichner in FPC verwenden darf, ausgenommen Zahlen am Anfang in Dateinamen und das minus.
Wen ich das Dateisystem von Linux angucke, findet da man auch sehr selten Zeichenexoten, ausser bei selbst erstellen Dateien und Ordner.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von af0815 »

Mathias hat geschrieben:
Mo 17. Jul 2023, 19:08
Wen ich das Dateisystem von Linux angucke, findet da man auch sehr selten Zeichenexoten, ausser bei selbst erstellen Dateien und Ordner.
Dann hast du noch nie auf einen Linux Server geschaut, wo (Managment-) User mit Windows (oder Mac) ihre Dateien ablegen. Richtig krank was man da sieht. Da gibt es kein Bewusstsein zu richtigen Dateinamen, da wird scheinbar die Beschreibung als Dateinamen verwendet. Lange Zeilen, Umlaute, ... und dann wundern die sich die, wenn mal was nicht so geht. Oder man es nicht in weitere Unterverzeichnisse am Rechner verschieben kann. Dann braucht man schon Lösungen unter Windows10/11, wie die Längenbegrenzug ausschalten https://www.computerwissen.de/windows/w ... indows-10/ aber dann geht es am Serverlaufwerk weiter. Aus Sicht der Admin - abartig und nur noch bewusstlos.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Warf
Beiträge: 1913
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Warf »

Ich muss sagen das sieht mir nach Problemen aus die nur darauf warten dir irgendwann aufzukochen.

Die Offensichtlichen Probleme sind natürlich wenn man den Namen irgendwo abtippen muss, oder auch wenn man eine Software verwendet die kein Unicode kann, und dann eine Datei deren Namen nach wunderbarem ASCII aussieht plötzlich komische ? in der mitte hat.

Ein bisschen weniger offensichtlich ist aber auch das weitere ökosystem. So werden Unicode Ersetzungen z.B. für Homomorphe Angriffe verwendet, wo dokumente oder URLs so benannt werden das sie so aussehen wie andere Dokumente/URLs um den Nutzer dazu zu verleiten ausversehen das Falsche Dokument anzuklicken. Kann dir also schnell mal passieren das dir ein Virenschutzprogramm oder Spam-filter die Dateien abschießt.

Dann versetz dich mal in die Lage eines Sicherheitsingeneurs bei einem Online Dienst, der in die Logs schaut und sieht das Leute Dateien hochladen nicht erlaubte charaktere zu haben scheint, bzw. im Fall von Path Delimitern, als ob man es geschafft hat unerlaubt im Dateisystem rumzuwühlen ("stell dir mal vor du siehst plötzlich das jemand die Datei "/passwd" schreiben kann). Da wird dann erstmal eine Sicherheitslücke vermutet, und vermutlich wird dann das gesammte Team wachgeklingelt, nur um zu merken das es Homomorphe Zeichen sind. Selbst wenn es direkt als Homomorphe Zeichen erkannt wird, kann das natürlich trozdem als Homomorpher Angriffsversuch ausgelegt werden. Würde mich nicht wundern wenn du damit auf diversen schwarzen listen landest und deine Accounts gesperrt bekommst.

Also alles in allem sehr nette Spielerei, aber ich würde es nicht riskieren.
Zuletzt geändert von Warf am Di 18. Jul 2023, 08:55, insgesamt 1-mal geändert.

Mathias
Beiträge: 6210
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Mathias »

Dann hast du noch nie auf einen Linux Server geschaut, wo (Managment-) User mit Windows (oder Mac) ihre Dateien ablegen.
Ich habe schon eher an eine normale Linux-Installation gedacht, welche nur mit der Paketverwaltung gepflegt wird.

Aber du hast schon recht, in selbst erstelltes Zeugs im Home-Ordner, das sieht man die verrücktesten Sachen. Die Office-User bringen die kurligsten Sachen hin. :mrgreen:
Da verwundert es einem, das die ihr Zeugs noch finden.
Solche Namen sehen auch kurlig aus: "Mein Brief.doc.xls.doc"
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Socke »

af0815 hat geschrieben:
Di 18. Jul 2023, 08:22
Mathias hat geschrieben:
Mo 17. Jul 2023, 19:08
Wen ich das Dateisystem von Linux angucke, findet da man auch sehr selten Zeichenexoten, ausser bei selbst erstellen Dateien und Ordner.
Dann hast du noch nie auf einen Linux Server geschaut, wo (Managment-) User mit Windows (oder Mac) ihre Dateien ablegen. Richtig krank was man da sieht. Da gibt es kein Bewusstsein zu richtigen Dateinamen, da wird scheinbar die Beschreibung als Dateinamen verwendet.
Als Anwender darf ich doch erwarten, dass Betriebssystem und Anwendungen die von diesen definierten Grenzen ausnutzen können.
Natürlich bereiten mir als Admin ungünstige Dateinamen auf der Shell Probleme. Hier finde ich aber auch die Shellprogrammierung einfach zu umständlich. Ich bin bei der Anlage von Dateien nicht gewillt, auf die Syntaxunterschiede verschiedener Shells Rücksicht zu nehmen, und will dies auch nicht von Anwendern erwarten. Muss ich für einen Dateinamen mit Leerzeichen jetzt $f, "$f", {$f} oder "{$f}" schreiben? Damit sind selbst viele Softwareentwickler überfordert.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 170
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Jorg3000 »

Wer Anwender-Dateinamen manuell in eine Shell tippen muss, braucht es ja nicht einzusetzen.

Mein eigener Anwendungsfall, wo ich die Funktion eingebunden habe, ist dass ein Anwender unter Windows eine PDF-Datei speichert, wofür er einen Namen in einem SaveDialog eingeben/ändern kann. Meine Funktion liefert nur einen Vorschlag auf Basis eines Textes.
Die so gespeicherten PDF-Dateien müssen sicherlich niemals von irgendwem in eine Shell getippt werden. Der Anwender guckt sich die Dateiliste im Windows File Explorer an und macht einen Doppelklick, um ein PDF im Viewer zu öffnen. That's all.

Ich habe testhalber Dateien mit den Ersatz-Unicode-Zeichen im Namen gespeichert. Sie ließen sich bei mir mit allen gängigen Anwendungen öffnen!
Auch per Mail habe ich mir eine solche Datei geschickt, und geöffnet und gespeichert, alles ohne Probleme.

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 170
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von Jorg3000 »

Was machen eigentlich Linux-Admins in China? Die kennen doch auch nicht jedes einzelne, seltene Schriftzeichen und wissen spontan, wie es an der Tastatur einzugeben ist.
Gibt es in der Linux-Konsole denn kein Copy&Paste? (kenne mich damit nicht aus)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Dateinamen: Unerlaubte Zeichen durch Unicode ersetzen

Beitrag von af0815 »

Jorg3000 hat geschrieben:
Di 18. Jul 2023, 13:23
Was machen eigentlich Linux-Admins in China? Die kennen doch auch nicht jedes einzelne, seltene Schriftzeichen und wissen spontan, wie es an der Tastatur einzugeben ist.
Gibt es in der Linux-Konsole denn kein Copy&Paste? (kenne mich damit nicht aus)
Nachdem meine alte Firma auch in Asien Zweigwerke hatte - Es ist im Unicode kein Unterschied :-) als Admin . An das gewöhnt man sich, nur nervig sind die Anwender dann, wenn ihre langen Dateinamen (mit Pfad) nicht mehr im Betriebssystem verarbeitet werden können und du deswegen laufend Call's hast. Normalerweise kümmern dich die Dateinamen nicht so wirklich. Es ist meist nur lustig, auf was für Ideen die Leute kommen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten