2010-01-23 20 views
2

J'ai un script PHP qui doit exécuter des programmes qui fonctionneront sur les fichiers qui ont des espaces dans les noms. La plupart des fonctions PHP pour l'exécution de commandes externes (par exemple exec()) prennent un argument de 1 chaîne pour la ligne de commande à exécuter. Cependant, vous devez faire des choses comme escapeshellarg() pour sécuriser vos entrées.Exécuter une commande externe en passant un tableau, avec des espaces dans les noms de fichiers

Existe-t-il un moyen d'exécuter une commande externe en PHP avec un tableau. Ainsi, plutôt que:

exec("ls -l ".escapeshellarg($filename)); 

Je peux aller:

exec(array("ls", "-l", $filename)); 

Cela signifie que je n'ai pas à vous soucier d'échapper aux arguments. Je veux éviter d'utiliser escapeshellarg(), puisque la version que j'utilise a un bug qui supprime les caractères non-ASCII.

Java a cette fonctionnalité http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#exec%28java.lang.String[]%29

+1

Je sais que c'est évident, mais pour toute autre personne qui vient: JAMAIS exécuter des commandes externes basées sur l'entrée de l'utilisateur. Si le script ne se trouve sur aucun serveur Web, mais vérifiez le contraire, assurez-vous de vérifier, revérifier et vérifier 5 fois de plus que personne ne peut utiliser ce script pour exécuter une commande à laquelle il n'est pas supposé. – Matchu

Répondre

2

Cela ne semble pas possible avec les fonctions intégrées de PHP.

+0

Vous pouvez toujours utiliser la combinaison des fonctions pcntl_fork/pcntl_exec. Afin d'obtenir la sortie d'un programme, vous devez traiter des fichiers temporaires, car (ressemble à) il n'y a pas de fonction pipe (2) :) – alvelcom

1
function myExec (command, arguments) 
{ 
    exec(command + ' ' + implode(' ', array_map(escapeshellarg, arguments))); 
} 
+0

Bonne suggestion, mais je veux éviter d'utiliser escapeshellarg() (j'ai mis à jour la question en conséquence). La version que j'utilise a un bug qui supprime les caractères non-ASCII. – Rory

+0

N'hésitez pas à remplacer cette fonction par toute autre fonction (en définir une vous-même par exemple) qui filtre les caractères correctement. Je voulais juste vous donner une idée de comment le faire :) – poke

+0

Pourquoi le downvote btw? – poke

-1

réponse de Poke est bon - cependant, combien de commandes ont-ils besoin d'exécuter? Je pense à la mise en place d'une liste blanche de commandes et d'arguments - de cette façon, vous pouvez être sacrément sûr qu'ils ne sont pas des intrusions malveillantes. Quelque chose comme:

$whitelistCommandArray = array('ls' => 'ls', ...); 
if (isset($whitelistCommandArray[$userSuppliedCommand]]) 
{ 
    //ok its a valid command, lets parse the args next 
    ... 
} 
else echo "Unsupported command"; 

Mise à jour/edit:

Est-ce une liste blanche des arguments réalisables? Que faire si OP a besoin d'éditer une multitude de fichiers ? - Matchu

heh Je ne sais pas - il pourrait être - dépend totalement de vos besoins.

$whitelistArray = array('ls' => array('a', 'l', 'h'), ...); 

Quelque chose comme ça fonctionne - avec à la fois la commande et un tableau d'arguments pour cela.

+0

Une liste blanche d'arguments est-elle réalisable? Que faire si OP a besoin d'éditer une multitude de fichiers? – Matchu

+0

Oui, j'ai besoin de ce script pour fonctionner sur des milliers de fichiers qui pourraient être nommés quelque chose et auront certainement des espaces dans leurs noms. – Rory