| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |

08-05-2010, 23:45
|
|
s02
Registrierter Benutzer
|
|
Registriert seit: Jan 2004
Beiträge: 69
|
|
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
Geändert von s02 (10-05-2010 um 01:21 Uhr)
Grund: Weiterer Fehler im Regex und Formatierung
|

09-05-2010, 00:19
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
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
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt? 
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke! 
|

09-05-2010, 00:44
|
|
s02
Registrierter Benutzer
|
|
Registriert seit: Jan 2004
Beiträge: 69
|
|
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($path, ENT_QUOTES)
. '</span>"<br />';
}
echo '</pre>';
?>
Gruß
Olli
Geändert von s02 (10-05-2010 um 01:20 Uhr)
|

09-05-2010, 19:30
|
 |
fireweasel
Registrierter Benutzer
|
|
Registriert seit: Sep 2008
Ort: At home
Beiträge: 680
|
|
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.
__________________
PHP-Code:
class Brick implements Throwable {
// ...
}
|

10-05-2010, 00:30
|
|
s02
Registrierter Benutzer
|
|
Registriert seit: Jan 2004
Beiträge: 69
|
|
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
Geändert von s02 (10-05-2010 um 01:19 Uhr)
|

10-05-2010, 13:43
|
 |
fireweasel
Registrierter Benutzer
|
|
Registriert seit: Sep 2008
Ort: At home
Beiträge: 680
|
|
Zitat:
Zitat von s02
... /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:
Zitat von s02
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.
Zitat:
|
...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);
__________________
PHP-Code:
class Brick implements Throwable {
// ...
}
Geändert von fireweasel (10-05-2010 um 13:49 Uhr)
|

10-05-2010, 14:23
|
|
s02
Registrierter Benutzer
|
|
Registriert seit: Jan 2004
Beiträge: 69
|
|
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
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|