Skip to content

Instantly share code, notes, and snippets.

@thedouglenz
Last active August 29, 2015 14:18
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save thedouglenz/193defdb711e0e54d68a to your computer and use it in GitHub Desktop.
Save thedouglenz/193defdb711e0e54d68a to your computer and use it in GitHub Desktop.
Wikipedia information from the command line
#!/usr/bin/env php
<?php
/*
* A program to grab a quick summary of some topic from Wikipedia.
* Usage: wiki <subject>
*
* subject can contain spaces if, for example, it is more than one word.
* Examples
* `wiki cherry bomb`
* `wiki Hercules`
*
* Douglas Lenz 2015
*
*/
// Verify the correct number of command line args have been given
$num_args = count($argv) - 1;
if($num_args == 0) {
echo "Usage: wiki <subject>\n";
exit(0);
}
// Get the command line args that constitute the search term
$args = [];
for($i=0; $i < $num_args; $i++) {
$args[] = $argv[$i+1];
}
// Where there are spaces, instead use _
$search_term = join("_", $args);
// Set up curl options
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://en.wikipedia.org/w/api.php?continue=&action=query&titles=$search_term&prop=extracts&exintro=&explaintext=&format=json&redirects");
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_USERAGENT, "WikiTerm/1.0");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// Run and close curl
$result = curl_exec($curl);
curl_close($curl);
// Parse the JSON response and locate the data we want
$data = json_decode($result, true);
$subdata = $data['query']['pages'];
$subsubdata = $subdata[array_keys($subdata)[0]];
// Display to screen
if(array_key_exists('missing', $subsubdata)) {
echo "No articles found.";
} else {
echo "\n" . $subsubdata['title'] . "\n\n";
exec("fold -s -w 80 <<EOF\n" . escapeshellarg($subsubdata['extract']) . "\nEOF", $lines, $_);
foreach($lines as $line) {
echo $line . "\n";
}
//echo $subsubdata['extract'];
}
echo "\n";
exit(0);
?>
@TrollWarlord
Copy link

You don't use https!

@thedouglenz
Copy link
Author

@TrollWarlord oh sheet you're right

@Lokaltog
Copy link

Lokaltog commented Apr 5, 2015

Your script is still vulnerable to an injection attack due to the way escapeshellarg works. Here's a demonstration: http://3v4l.org/T73Qg#v430

The code below is what would be executed by exec() in your script, given the input \nEOF\nls -al;\n (with \n being actual line feeds):

fold -s -w 80 <<EOF
'
EOF
ls -al;
'
EOF

@azihassan
Copy link

Why not use wordwrap() instead of calling the "fold" utility ? That ought to silence the r/programming haters.

@Lokaltog
Copy link

Lokaltog commented Apr 5, 2015

Haters, really? Security considerations has nothing to do with hating on a good idea with a poor execution. When you post it on a subreddit dedicated to programming it shouldn't come as a surprise that someone looks at the code. If OP didn't want people to tell him about security flaws in his script, he probably shouldn't have posted it in /r/programming to begin with.

@Scroph You should reconsider how you view constructive criticism. I could have said "you suck, and your script sucks". Or, you know, spent the time telling OP why his script sucks, and how he should improve on it, so it's something anyone can use without worrying about a serious security flaw with a simple workaround.

@azihassan
Copy link

When I said "haters", I meant haters towards PHP, a vibe that I got from your Reddit comment. But it's a hyperbole, a joke, no need to justify yourself, take it easy.

I agree about the fact that there is a vulnerability in OP's code, that's why I suggested using wordwrap() as a solution, thus avoiding the exec call altogether.

@Lokaltog
Copy link

Lokaltog commented Apr 6, 2015

Ah, I see. Sorry about the confusion and the resulting rant! Reading my comment again I guess I was a bit frustrated for no real reason when writing it, sorry about that.

In this particular case I do think PHP is the wrong tool for the job though, as PHP is designed specifically for making webpages and not much else, but I respect that some may disagree with that. If you have php and php-curl already installed it doesn't matter though, the different scripts posted all accomplish the exact same thing :)

Good solution with wordwrap, hopefully it will be included in op's script soon for anyone else downloading it in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment