[GELÖST] Auf gültigen Dateinamen prüfen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
petwey
Beiträge: 83
Registriert: Sa 24. Nov 2012, 19:00
OS, Lazarus, FPC: Windows10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit und 64Bit

[GELÖST] Auf gültigen Dateinamen prüfen

Beitrag von petwey »

Hallo zusammen,

ich bin gerade dabei eine Eingabe auf einen gültigen Dateinamen zu checken. Dabei habe ich im Internet verschiedene Ansätze gefunden.

- Einmal eine Blacklist mit allen Zeichen, die nicht enthalten sein dürfen z.B.: /*."/\[]:;|,<> ? (ohne Gewähr auf Vollständigkeit)
- Dasselbe mit einer Whitelist (alle Zeichen die darin enthalten sein dürfen)

Und dann gibt es noch eine Menge Ausnahmen und Erweiterungen, je nach Betriebs- und verwendetem Dateisystem....

Da hab ich mir gedacht: Erstelle doch einfach eine Datei mit der angegebenen Eingabe und schau ob ein Fehler auftritt. Wenn kein Fehler auftritt ist der Dateiname gültig. (Die Test-Datei wird danach wieder gelöscht).

Gesagt, getan. Den Test hab ich mit den sinnigen Dateiname :; durchgeführt, der ja oben in der Blacklist ist. Übrigens ich verwende hier Win10.
Interessanterweise trat kein Fehler auf. Danach hab ich die Datei im Explorer und mittels der Eingabeaufforderung gesucht und - Überraschung - nicht gefunden.

Danach habe ich in die Datei :; etwas reingeschrieben, Datei geschlossen, wieder geöffnet und da war tatsächlich der Text drin den ich vorher reingeschrieben habe.

Jetzt frag ich mich wie passt das alles zusammen? Kann das jemand erklären?

Hier der Code-Schnipsel mit dem ich das gemacht habe:

Code: Alles auswählen

procedure CheckInput(aStr: string);
Var
  sl : TStringList;
begin
    // Leerzeichen durch Underlines ersetzen
    aStr := StringReplace(aStr, ' ', '_', [rfReplaceAll]);
    // Mittels StringList eine Datei erzeugen.
    sl := TStringList.Create;
    sl.Text := 'test___FGH';
    sl.SaveToFile('D:\'+aStr);
    // StringList säubern und Inhalt darstellen, nur zum Check ob sie wirklich leer ist.
    sl.Clear;
    ShowMessage(sl.Text);
    // Datei wieder einlesen.
    sl.LoadFromFile('D:\'+aStr);
    // Inhalt der Datei anzeigen
    if FileExists('D:\'+aStr) then 
      ShowMessage('Done '+sl.Text) 
    else 
      ShowMessage('Fail '+aStr);
    sl.Free;
end;

begin
  CheckInput(':;');
end.
Der Ansatz eine Datei mit dem Eingabenamen zu erzeugen und auf einen Fehler zu reagieren finde ich immer noch reizvoll. Es sei denn es gibt eine plattformübergreifende fertige Funktion, die ich bis jetzt noch nicht gefunden habe.
Zuletzt geändert von petwey am Do 11. Mai 2023, 23:35, insgesamt 1-mal geändert.
MfG,
petwey

Windows 10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)

siro
Beiträge: 763
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Auf gültigen Dateinamen prüfen

Beitrag von siro »

Sorry, ich glaub ich das Problem falsch verstanden.... :roll:
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

petwey
Beiträge: 83
Registriert: Sa 24. Nov 2012, 19:00
OS, Lazarus, FPC: Windows10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit und 64Bit

Re: Auf gültigen Dateinamen prüfen

Beitrag von petwey »

Hallo siro,

vielleicht hab ich mich nicht klar genug ausgedrückt:
- Ich habe eine User-Eingabe, die ich in einen Dateinamen umsetzen will.
- Da ich mit dem größten Blödsinn rechnen muss verwende ich hier zum testen Doppelpunkt und Semikolon (:;).
- Das sollte nach allen gültigen Regeln unter Win kein gültiger Dateiname sein.
- Mittels Stringlist erzeuge ich diese Datei (:;).
- Die Datei :; kann man im Explorer und auch mittels CMD-Fenster (Dir-Befehl) nicht finden.
- Die weiteren Tests zeigen: Ich kann diese Datei aber trotzdem öffen und sie hat auch den korrekten Inhalt.
- Ich hätte eine Fehlermeldung erwartet, aber nicht das es funktioniert.

Ursprünglich habe ich nach einer plattformübergreifenden Funktion gesucht mit der ich testen kann ob ein Dateiname gültig ist. Nachdem ich nichts gefunden habe, bin ich auf die Idee verfallen einen Fehler zu provozieren um so herauszufinden ob der Dateiname gültig ist oder nicht. Damit wäre ich dann automatisch plattformunabhängig.
Aber ich muss feststellen, dass es möglich ist unter Windows eine Datei mit dem Dateinamen :; zu erstellen. Man sieht sie zwar nicht, aber es gibt sie.

Dafür suche ich nach einer Erklärung und noch besser nach einem Weg wie den oben beschriebenen Test durchführen kann. Nämlich kann ich den Dateinamen (und das ist eine User-Eingabe) verwenden oder nicht.
MfG,
petwey

Windows 10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)

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

Re: Auf gültigen Dateinamen prüfen

Beitrag von theo »

Die Frage ist, worum es dir genau geht.
Ich würde pragmatisch einfach die folgenden Zeichen Verbieten und gut.

Code: Alles auswählen

< > ? " : | \ / *
Das kann man für alle Plattformen so machen, ausser man nimmt es ganz genau, aber das musst du selber wissen.
S.a. https://de.wikipedia.org/wiki/Dateiname

Sicher kann man auch eine Wissenschaft daraus machen, wenn es eine ganz ernste und wichtige Angelegenheit ist.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6854
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: Auf gültigen Dateinamen prüfen

Beitrag von af0815 »

Da gibt es hier einen Hinweis hier https://forum.lazarus.freepascal.org/in ... ic=16862.0, das in den Quellen von Lazarus eine IsValidUnitName (packager\packagedefs.pas) aufgerufen wird, die ein paar Prüfungen durchführt. Vielleicht ist das ein Anfangspunkt für dein Problem.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

PascalDragon
Beiträge: 963
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Auf gültigen Dateinamen prüfen

Beitrag von PascalDragon »

petwey hat geschrieben: Do 11. Mai 2023, 19:18 Gesagt, getan. Den Test hab ich mit den sinnigen Dateiname :; durchgeführt, der ja oben in der Blacklist ist. Übrigens ich verwende hier Win10.
Interessanterweise trat kein Fehler auf. Danach hab ich die Datei im Explorer und mittels der Eingabeaufforderung gesucht und - Überraschung - nicht gefunden.

Danach habe ich in die Datei :; etwas reingeschrieben, Datei geschlossen, wieder geöffnet und da war tatsächlich der Text drin den ich vorher reingeschrieben habe.

Jetzt frag ich mich wie passt das alles zusammen? Kann das jemand erklären?
Da hast du jetzt genau das richtige Zeichen gewählt, um auf ein Feature von NTFS zu stoßen: Alternate Data Streams. Diese sind benannte Daten, die an eine existierende Datei oder ein existierendes Verzeichnis angehängt sind. Dabei ist der Name des ADS von dem der Datei mit einem Doppelpunkt abgetrennt (deswegen ist ein Doppelpunkt im Dateinamen auch verboten), zum Beispiel foo.bar:blubb.

Wenn du nun eine Datei :; anlegst, dann legst du letztlich einen ADS mit dem Namen ; für das aktuelle Verzeichnis an (für den Namen eines ADS gelten die Einschränkungen für die Dateinamen nicht). Du findest diesen dann, wenn du in einer Eingabeaufforderung (nicht PowerShell) in dem Verzeichnis dir /R machst. Den Inhalt bekommst du dann mittels more < ":;".
FPC Compiler Entwickler

petwey
Beiträge: 83
Registriert: Sa 24. Nov 2012, 19:00
OS, Lazarus, FPC: Windows10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit und 64Bit

Re: Auf gültigen Dateinamen prüfen

Beitrag von petwey »

Hallo theo,

was ich will habe ich bereits beschrieben und dein Lösungsweg ist gangbar, darum geht es mir mittlerweile gar nicht mehr. Aber was ich gefunden habe, erschreckt mich und sollte euch auch zum Nachdenken bringen.

In deinem Link lässt sich unter Windows ab Version 95 -> Problematische und unzulässige Zeichen oder Namen die von dir angeführte Liste
< > ? " : | \ / * finden. Wenn man weiterliest findet man noch mehr Verbote, nämlich ganze Dateinamen wie
CON, PRN, AUX, NUL
COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9

Ich wollte mir das Leben leicht machen und mich auf das Betriebssystem verlassen, da ich erwartet habe, dass es gar nicht zulässt Dateinamen mit verbotenen Lettern zu erzeugen.

Was ich statt dessen finde, ist dass es möglich ist Dateien zu erzeugen, die nur vom Erzeuger erstellt und gelesen werden können, denn man sieht sie ja gar nicht, wenn man nicht weiß, das es sie gibt. Das beunruhigt mich etwas. Es gibt genug Schadsoftware, aber ich denke die meisten Dateien kann man auch mit dem Explorer anzeigen und eventuell löschen. Dateien mit eigentlich verboten Dateinamen, wie von mir beschrieben, können sich auf allen Rechnern befinden. Was kann man damit wohl alles anfangen?

Ich geb mal einen anderen Vergleich: weißer Adler auf weißem Feld, den kann man auch nicht finden.
Oder Anweisungen die ein Programmierer in seinem Programm versteckt indem er die Text-Farbe eines Labels auf Transparent stellt.

Was ist das Verbot bestimmter Zeichen in Dateinamen wert, wenn sich offensichtlich das Betriebssystem nicht daran hält? Wird hier nicht Häckern ein weites Tor geöffnet?

Ich weiß nicht ob man das mit dem Begriff Wissenschaft abtun sollte.

Aber letztendlich, nochmals die konkrete Frage:
Gibt es eine Funktion, die plattformunabhängig eine Namen darauf prüft ob er die gültigen Lettern eines Dateinamens verwendet? Es können auch mehrere Funktionen sein für die jeweiligen Betriebs- / Filesysteme.
MfG,
petwey

Windows 10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)

petwey
Beiträge: 83
Registriert: Sa 24. Nov 2012, 19:00
OS, Lazarus, FPC: Windows10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit und 64Bit

Re: Auf gültigen Dateinamen prüfen

Beitrag von petwey »

Hallo PascalDragon,

das mit dem ADS wusste ich nicht. Die beiden Zeichen habe ich beliebig aus den verbotenen Zeichen gewählt, nicht ahnend, daß sie eine Sonderfunktion haben.

Hallo af0815,
ich werde deinen Hinweisen nachgehen.
MfG,
petwey

Windows 10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)

PascalDragon
Beiträge: 963
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Auf gültigen Dateinamen prüfen

Beitrag von PascalDragon »

petwey hat geschrieben: Do 11. Mai 2023, 22:56 Was ich statt dessen finde, ist dass es möglich ist Dateien zu erzeugen, die nur vom Erzeuger erstellt und gelesen werden können, denn man sieht sie ja gar nicht, wenn man nicht weiß, das es sie gibt. Das beunruhigt mich etwas. Es gibt genug Schadsoftware, aber ich denke die meisten Dateien kann man auch mit dem Explorer anzeigen und eventuell löschen. Dateien mit eigentlich verboten Dateinamen, wie von mir beschrieben, können sich auf allen Rechnern befinden. Was kann man damit wohl alles anfangen?
Vorwiegend kann man damit anfangen, dass der Internet Explorer bzw. Edge hinterlegt, dass die Datei aus dem Internet stammt, so dass Windows beim Start einer Anwendung einen entsprechenden Hinweis anzeigen kann. In meiner Arbeit nutzen wir ADS zum Beispiel dafür die pdb und map Dateien, die beim Kompilieren von C++ Code erzeugt werden mit an die Binary anzuhängen.

Ein Angreifer kann letztlich allerdings nur deine Platte zumüllen, da du zum Anlegen (und Ausführen) von ADS letztlich die gleichen Berechtigungen brauchst.
petwey hat geschrieben: Do 11. Mai 2023, 22:56 Was ist das Verbot bestimmter Zeichen in Dateinamen wert, wenn sich offensichtlich das Betriebssystem nicht daran hält? Wird hier nicht Häckern ein weites Tor geöffnet?
Das Betriebssystem hält sich daran. Ein Doppelpunkt ist in einem Dateinamen unter Windows nicht erlaubt, weil er eben eine spezielle Syntaxfunktion hat. Es funktioniert nur, weil Windows diese spezielle Funktion eben transparent behandelt. Probiere das Gleiche auf einem FAT und du wirst nen Fehler bekommen.
petwey hat geschrieben: Do 11. Mai 2023, 22:56 Gibt es eine Funktion, die plattformunabhängig eine Namen darauf prüft ob er die gültigen Lettern eines Dateinamens verwendet? Es können auch mehrere Funktionen sein für die jeweiligen Betriebs- / Filesysteme.
Nein, gibt es nicht.
petwey hat geschrieben: Do 11. Mai 2023, 23:03 das mit dem ADS wusste ich nicht. Die beiden Zeichen habe ich beliebig aus den verbotenen Zeichen gewählt, nicht ahnend, daß sie eine Sonderfunktion haben.
Es hat nur der Doppelpunkt eine spezielle Funktion, der Strichpunkt ist in diesem Fall ein normaler Name für den ADS ($ ist zum Beispiel auch erlaubt).
FPC Compiler Entwickler

petwey
Beiträge: 83
Registriert: Sa 24. Nov 2012, 19:00
OS, Lazarus, FPC: Windows10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit und 64Bit

Re: Auf gültigen Dateinamen prüfen

Beitrag von petwey »

Hallo PascalDragon,

leider haben sich einige Beiträge hier zeitlich überschnitten. Hätte ich das mit dem ADS eher gelesen, hätte ich anders geantwortet.
Danke für deine vielen Klarstellungen.

Hallo af0815,
dein Link hat mir geholfen. Dort wird beschreiben, wie die Unitnamen geprüft werden. Das sind strengere Anforderungen als für normale Dateinamen und sollte auch für alle Plattformen funktionieren.
IsDottedIdentifier (components\codetools\basiccodetools.pas) which checks that first char is in ['a'..'z','A'..'Z','_'] and the remainder in ['a'..'z','A'..'Z','_','0'..'9']. Dots are allowed but the char after dot has to be in ['a'..'z','A'..'Z','_']. Unit names are far more restrictive than the OS filename requirements.
Danke euch allen. Für mich ist das Problem gelöst.
MfG,
petwey

Windows 10 und Linux 32 und 64Bit (L 2.2.2 FPC 3.2.2)

Antworten