Hilfe bei/Test von RegeEx für Dateipfad-Validierung

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Hilfe bei/Test von RegeEx für Dateipfad-Validierung

    Hilfe bei/Test von RegeEx für Dateipfad-Validierung

    Hallo,

    ich stehe vor dem Problem einen Pfad auf Gültigigkeit prüfen zu müssen, und Gültig bedeutet in diesem Fall der Pfad darf:

    * nicht mit einem . oder einem / beginnen
    * keine Steuerzeichen, und keine der folgenden Zeichen enthalten: \:*?'"<>|
    * keine aufeinander folgenden Punkte enthalten
    * keine Dateien oder Verzeichnisse beinhalten die nur aus Punkten und/oder Leerzeichen bestehen
    * nicht mit einem Punkt oder einem Leerzeichen enden

    Meine bisherige Lösung sieht wie folgt aus:

    Code:
    /^
        (?![\\.\\s\/])                     # Kein Punkt, Leerzeichen oder Slash am Anfang
        (
            ([^\\x00-\\x1F\\\\:*?\"\'<>|]) # Verbot von Steuerzeichen, Backslash, Doppelpunkt,
                                           # Sternchen, Fragezeichen, doppelten und einfachen
                                           # Anführungszeichen, spitzen Klammern und senkrechten
                                           # Strichen
    
            (?!\\.\\.)                     # Keine aufeinander folgenden Punkte
    
            (?!\/(\\.|\\s+)\/)             # Keine Verzeichnisse die nur aus Punkten oder
                                           # Leerzeichen bestehen
        )*
        (?<![\\.\\s])                      # Kein Punkt oder Leerzeichen am Ende
    $/x
    Und das scheint soweit auch ganz gut zu funktionieren, aber es fühlt sich einfach noch etwas schwammig an, sprich ich bin noch etwas unsicher ob ich damit wirklich alles korrekt abgedeckt habe.

    Ich würde mich freuen wenn sich das mal jemand angucken könnte und seinen Senf dazu abgeben würde

    Gruß
    Olli
    Zuletzt geändert von s02; 10.05.2010, 01:21. Grund: Weiterer Fehler im Regex und Formatierung

  • #2
    Hallo,

    du kannst das doch anhand von Beispielen toll testen. Jeweils 10 gerade so gültige und gerade so ungültige sollten doch schon reichen.

    Gruß,

    Amica
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Schon klar, das tu' ich auch schon, aber ein Paar Augen mehr können nie schaden Einen Fehler habe ich auch bereits entdeckt, am Anfang habe ich auf den falschen Slash getestet, habe den Regex im ersten Beitrag entsprechend editiert.

      PHP-Code:
      <?php
      $pattern 
      '/^

          (?![\\.\\s\/])                           # Kein Punkt, Leerzeichen oder Slash am Anfang
          (
              ([^\\x00-\\x1F\\\\:*?\\x22\\x27<>|]) # Verbot von Steuerzeichen, Backslash, Doppelpunkt,
                                                   # Sternchen, Fragezeichen, doppelten und einfachen
                                                   # Anführungszeichen, spitzen Klammern und senkrechten
                                                   # Strichen

              (?!\\.\\.)                           # Keine aufeinander folgenden Punkte

              (?!\/(\\.|\\s+)\/)                   # Keine Verzeichnisse die nur aus Punkten oder
                                                   # Leerzeichen bestehen
          )*
          (?<![\\.\\s])                            # Kein Punkt oder Leerzeichen am Ende

      $/x'
      ;

      $paths = array
      (
          
      'folder',
          
      'folder/',
          
      'file.ext',
          
      'folder/file',
          
      'folder/file.ext',
          
      'fol$=()§$&§2479&%0z430ß²96d³er',
          
      'fol:der',
          
      'fol*der',
          
      'fol?der',
          
      'fol"der',
          
      'fol\'der',
          
      'fol>der',
          
      'fol<der',
          
      'fol|der',
          
      'fol    der',
          
      "fol\x0der",
          
      "fol\x1Fder",
          
      '.',
          
      ' ',
          
      '.folder',
          
      ' folder',
          
      '/folder',
          
      'folder/../file.ext',
          
      'folder/ /file.ext',
          
      'folder/ ',
          
      'folder/.',
          
      'folder/ . . . .   .',
      );

      echo 
      '<pre>';
      foreach(
      $paths as $path)
      {
          
      $result preg_match($pattern$path) > 0;
          
      $color  $result '#00aa00' '#ff0000';
          echo 
      '"<span style="color: #fff; background-color: ' $color '">'
              
      htmlentities($pathENT_QUOTES)
              . 
      '</span>"<br />';
      }
      echo 
      '</pre>';
      ?>
      Gruß
      Olli
      Zuletzt geändert von s02; 10.05.2010, 01:20.

      Kommentar


      • #4
        Darf man fragen, warum dir die Einhaltung ausgerechnet dieser Regeln wichtig ist?

        Mir fallen da bspw. für Windows-Dateisysteme noch einige Einschränkungen mehr ein (kein Punkt am Ende, Verbot bestimmter Namen usw.).

        Was deinen überlangen RegEx angeht: Ist dir die wundersame Wirkung des Modifiers /x bekannt? Mit dessen Hilfe kannst du den RegEx über mehrere Zeilen verteilen und mit erklärenden Kommentaren versehen.
        Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

        Kommentar


        • #5
          Es geht um Dateinamen aus ZIP Archiven, diese sollen auf Validität geprüft werden bevor überhaupt in Erwägung gezogen wird das Archiv zu entpacken, und ich war der Meinung mit diesen Regeln sowohl für das ZIP Format, als auch für Windows valide Dateinamen abzudecken, wenn ich mich da irren sollte würde ich mich freuen wenn du mich aufklären könntest.

          /x ist mir im übrigen durchaus bekannt, ja. Bei mir im Code ist es alles in einer Zeile, habe es nur aufgrund der hier herrschenden Beschränkungen umgebrochen, warum gerade auf diese Weise, keine Ahnung, nicht nachgedacht vermutlich. Oder was genau wolltest du mir damit sagen?

          edit: habe das ganze ein wenig umformatiert und kommentiert

          Gruß
          Olli
          Zuletzt geändert von s02; 10.05.2010, 01:19.

          Kommentar


          • #6
            Zitat von s02 Beitrag anzeigen
            ... /x ist mir im übrigen durchaus bekannt, ja. Bei mir im Code ist es alles in einer Zeile, habe es nur aufgrund der hier herrschenden Beschränkungen umgebrochen, warum gerade auf diese Weise, keine Ahnung, nicht nachgedacht vermutlich. Oder was genau wolltest du mir damit sagen?
            Ich wollte dir ganz gewiss nicht auf die Füße treten ... ;-)
            Da hier aber regelmäßig rumgemosert wird, man möge doch seinen Quelltext ordentlich umbrechen, weil die 80-Zeichen-pro-Zeile-sind-genug-Fraktion sonst Probleme mit der Darstellung der Web-Seiten bekommt, halte ich es für eine gute Idee, überlange RegExe mit /x schön formatiert auf mehrere Zeilen zu verteilen.

            Zitat von s02 Beitrag anzeigen
            Es geht um Dateinamen aus ZIP Archiven, diese sollen auf Validität geprüft werden bevor überhaupt in Erwägung gezogen wird das Archiv zu entpacken, ...
            Hmm, ich würde den Ansatz bevorzugen, einfach mal eine Datei mit passendem Pfad zu erzeugen, und dann nachzuschauen, ob es auch geklappt hat.

            Das hätte den Vorteil, dass im Normalfall die umständliche Prüfung entfallen würde.

            Außerdem ist es schwierig, wirklich alle Ausnahmen zu erfassen. Immerhin gelten auf unterschiedlichen Betriebssytemen ganz unterschiedliche Regeln, was Pfadangaben betrifft. Ob man die alle mit einem RegExp erschlagen kann, bezweifle ich. (Und ich bin als RegExp-Befürworter bekannt.)

            Selbst, wenn du nur die Windows-Eigenheiten abdecken möchtest, wird das schon sehr umfangreich, und kein Schwein weiß, ob Microsoft wirklich alle dokumentiert hat. Überlange Pfade wären z.B. auch so eine Sache. Da schwankt die Anzahl der erlaubten Zeichen je nach Quelle.

            Hinzu kommt noch das Kodierungsproblem bei Pfaden. PHP kann ohne Tricks derzeit nur mit 8-Bit-Kodierungen umgehen (irgendwelches Codepage-Geraffel oder auch nur ASCII). Du machst derzeit keine Einschränkungen bezüglicher erlaubter Buchstaben. Aber PHP oder auch ein schlecht programmiertes Unzip-Programm könnte Probleme bekommen, wenn ein Pfad im Archiv Zeichen enthält, die nicht gleichzeitig auf einer Codepage vorkommen.

            Möglicherweise gibts aber eine Betriebssystemfunktion (zumindest unter Windows), der man einen Pfad übergeben kann, und die dann sagt, ob er erlaubt ist oder nicht. Einige Dateisystemfunktionen sind über das "Scripting.FileSystemObject" ansprechbar. Das kann man von PHP aus über die COM-Schnittstelle aufrufen.

            ...und ich war der Meinung mit diesen Regeln sowohl für das ZIP Format, als auch für Windows valide Dateinamen abzudecken, wenn ich mich da irren sollte würde ich mich freuen wenn du mich aufklären könntest.
            Wieso ich? Frag doch Micro$oft ...

            Für einen Teil der "Spezifikation", den Basename (letzter Bestandteil eines Pfades zu einer Datei) hatte ich mir mal diesen Ausdruck gebastelt:

            PHP-Code:
            // check for invalid basenames under windoze
            preg_match(
            '/\A(?:(?:aux|con|nul|prn|com[1-9]|lpt[1-9])\.[^\.]*|.*[\/\x5c:?|*<>].*)\z/i',
            $basename); 
            Zuletzt geändert von fireweasel; 10.05.2010, 13:49.
            Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

            Kommentar


            • #7
              Den Artikel habe ich gesucht, danke

              Die Sache mit dem einfach mal testen behagt mir nicht so, da ich ja gerade versuche den Unfug zu vermeiden der mit manipulierten Pfaden getrieben werden kann, und da is mal so auf gut Glück testen eher kontraproduktiv

              Das ganze läuft nur auf Windows Systemen (2000, XP, Vista und 7), daher muss ich "nur" deren Eigenheiten abdecken, das meiste was MS in dem Artikel beschreibt deckt der RegEx ja ab, aber speziell mit den Kodierungen wird's wohl wie du sagtest schwierig werden...

              Ich werd mal gucken was die Windows API da so zu bieten hat, wenn's sein muss und es dort entsprechende Möglichkeiten gibt schreibe ich mir auch mit C++, Java oder .NET 'ne Anwendung die das prüft. Falls sich nichts findet werde ich vielleicht einfach einen Schritt weiter gehen, und alle erlaubten Zeichen definieren anstatt den nicht erlaubten, und den Nutzern dann diese Regeln aufzwingen, sprich alles was nicht passt als ungültig verwerfen, auch dann wenn es eventuell ein valider Pfad ist.

              Gruß
              Olli

              Kommentar

              Lädt...
              X