Re: [PECL-DEV] safe_shell_exec extension for consideration
[email protected] (Dave McMurtrie) Tue, 25 May 2010 20:34:46 -0400
| Newsgroups | php.pecl.dev |
|---|---|
| Message-ID | <[email protected]> |
Stig Bakken wrote: > Hehe, alright. I just have a thing about choosing descriptive names > that do not promise too much or little :-) I definitely lose on all counts then. While what I wrote is safer than involving a shell, it's not "safe" in that a caller could still use it to accomplish something dangerous. Further, it explicitly doesn't involve a shell and I stuck the word "shell" in there. somewhat_safer_non_shell_exec() may have been more accurate :) ...snipped... > Actually, system() and/or proc_open() would be better PHP functions to > mimic/overload, since there would be no shell involved here. If you have the time, check out the stuff I wrote. Notice I also allow an optional "flags" parameter that a caller can pass as either MERGE_STDERR or DISCARD_STDERR. This was to allow for existing code that was calling shell_exec() and depending on shell I/O redirection (2>&1 or 2>/dev/null, respectively). Would you want these options also added to proc_open() but only used with the code I add? If I overload proc_open(), would I make the array arguments only valid if bypass_shell were set, or would that remain a Windows-only option? > > I think it makes sense for you to write this code as an extension (to > make it available for everyone), but at the same make a patch for PHP's > built-in function(s). I'm embarrassed to admit that I don't know how this would work. Will nothing break if I patch PHP's built-in functions but also provide the same interface via an extension? > Using an array parameter is definitely the most > intuitive approach IMHO. > I'm glad you agree on this. It took me a while to come back around to this mindset, but having implemented and modified a bunch of existing code to work with it, it's much nicer. Also, I fixed a couple pre-existing bugs in the PHP code we're installing where they weren't properly escaping whitespace so filenames with spaces would break. My initial code that accepted a string and then parsed it to create an *argv[] was working for the code I had to run through it, but I could see it breaking if set loose in the wild. > The code would be a bunch of parameter conversions (to turn the string > array into va_arg()), a fork() and execv() call, some file descriptor > fiddling to create a php stream from the forked process's standard > output, and a waitpid() call collecting exit status. Again, take a look at what I already wrote. This is pretty much all there, with the exception of a few terminology differences that might just be typos on your part. execvp() takes an argument vector as its 2nd argument and doesn't use the va_args interface, so building this array was fairly simple. I have a statically allocated *char[] and I copy all of the char * address pointers from the array zval into my array which I pass to execvp(). The file descriptor fiddling is already in place, but it has no knowledge of a PHP stream. All I did was to open a pipe from the parent, close the write end in the parent, close the read end in the child and then dup2 stdout/stderr in the child to the write end of the pipe. This is where my MERGE_STDERR and DISCARD_STDERR flags can be used. The waitpid is there to prevent any zombie accumulation, but because I copied the notion of shell_exec() returning the command's output as a string, it has no way to provide the exit status to the caller and does nothing with it. Considering that I already have all of this implemented, it wouldn't be a ton of work for me to merge it into some existing function or extension. As you can tell from all of my questions, I'm going to need a little direction on exactly where you want it to go and how you want the interface to work. I suspect we'll need a bit more back and forth before we decide on the details. Thanks for your feedback and your willingness to assist with this. If we get too mired in details, you can take things off-list until we get something solid in place. I'll leave that up to you. Dave