r82829 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r82828‎ | r82829 | r82830 >
Date:02:41, 26 February 2011
Author:emufarmers
Status:reverted (Comments)
Tags:
Comment:
Committing the SearchLog extension by User:Nad.
Modified paths:
  • /trunk/extensions/SearchLog (added) (history)
  • /trunk/extensions/SearchLog/SearchLog.php (added) (history)

Diff [purge]

Index: trunk/extensions/SearchLog/SearchLog.php
@@ -0,0 +1,140 @@
 2+<?php
 3+# Extension:SearchLog{{php}}{{Category:Extensions|SearchLog}}
 4+# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
 5+# - Author: [http://www.organicdesign.co.nz/nad User:Nad]
 6+# - Started: 2007-05-16
 7+
 8+if (!defined('MEDIAWIKI')) die('Not an entry point.');
 9+
 10+define('SEARCHLOG_VERSION','1.0.8, 2008-2-08');
 11+
 12+$wgSearchLogPath = dirname(__FILE__);
 13+$wgSearchLogFile = "$wgSearchLogPath/logs/".ereg_replace('^www.','',$_SERVER['SERVER_NAME']);
 14+$wgSearchLogEntireLog = 'Entire log'; # Should be a message
 15+$wgSearchLogDateFormat = '%b %Y';
 16+$wgSearchLogReportHeading = "Search keywords used over '''\$1''' period"; # Should be a message
 17+$wgSearchLogGroup = ''; # restrict viewing to a particular group by setting this
 18+$wgExtensionFunctions[] = 'wfSetupSearchLog';
 19+
 20+$wgExtensionCredits['specialpage'][] = array(
 21+ 'name' => 'Special:SearchLog',
 22+ 'author' => '[http://www.organicdesign.co.nz/nad User:Nad]',
 23+ 'description' => 'Logs usage of the search box and allows reporting of keyword totals during given time periods',
 24+ 'url' => 'http://www.mediawiki.org/wiki/Extension:SearchLog',
 25+ 'version' => SEARCHLOG_VERSION
 26+ );
 27+
 28+require_once "$IP/includes/SpecialPage.php";
 29+
 30+class SpecialSearchLog extends SpecialPage {
 31+
 32+ # Constructor
 33+ function SpecialSearchLog() {
 34+ global $wgSearchLogGroup;
 35+ SpecialPage::SpecialPage('SearchLog',$wgSearchLogGroup);
 36+ }
 37+
 38+ # Override SpecialPage::execute()
 39+ function execute() {
 40+ global $wgOut,$wgSearchLogFile,$wgSearchLogEntireLog,$wgSearchLogReportHeading,$wgSearchLogDateFormat,$wgRequest;
 41+ $this->setHeaders();
 42+ $title = Title::makeTitle(NS_SPECIAL,'SearchLog');
 43+ $period = isset($_REQUEST['period']) ? $_REQUEST['period'] : false;
 44+ $error = '';
 45+
 46+ # Get the dates of the first and last entries for the dropdown list range
 47+ if ($fh = fopen($wgSearchLogFile,'r')) {
 48+ if (ereg('^([0-9]{4})([0-9]{2})[0-9]{2},',fread($fh,16),$match)) list(,$y1,$m1) = $match;
 49+ $len = fstat($fh);
 50+ $len = $len['size'] % 1024;
 51+ fseek($fh,-$len,SEEK_END);
 52+ $end = explode("\n",fread($fh,$len));
 53+ $end = $end[count($end)-2];
 54+ if (ereg('^([0-9]{4})([0-9]{2})[0-9]{2},',$end,$match)) list(,$y2,$m2) = $match;
 55+ fclose($fh);
 56+ }
 57+
 58+ # Construct a list of months if first and last successfully obtained
 59+ $months = '';
 60+ if ($y1 && $y2) while (($y1*100+$m1) <= ($y2*100+$m2)) {
 61+ $p = strftime($wgSearchLogDateFormat,mktime(0,0,0,$m1,1,$y1));
 62+ $selected = $p == $period ? ' selected' : '';
 63+ $months .= "<option$selected>$p</option>\n";
 64+ if ($m1 == 12) { $m1 = 1; $y1++; } else $m1++;
 65+ }
 66+
 67+ # Render the months as a dropdown-list
 68+ $wgOut->addHTML(
 69+ "<fieldset><legend>Select time period: </legend>"
 70+ . wfElement('form',array('action' => $title->getLocalURL('action=submit'),'method' => 'POST'),null)
 71+ . "<select name=\"period\"><option>$wgSearchLogEntireLog</option>$months</select>"
 72+ . wfElement('input',array('type' => 'submit'))
 73+ . "<br /><br />"
 74+ . wfCheckLabel("Display raw Unicode","wpEscapeChars", "wpEscapeChars", $checked = true)
 75+ . '</form></fieldset>'
 76+ );
 77+
 78+ # Generate a report if a period was specified
 79+ if ($period === false) $period = $wgSearchLogEntireLog;
 80+ if ($period) {
 81+ $heading = str_replace('$1',$period,$wgSearchLogReportHeading);
 82+ $wgOut->addWikiText("== $heading ==",true);
 83+ if ($fh = fopen($wgSearchLogFile,'r')) {
 84+
 85+ # Scan the file and sum the search phrases over the period
 86+ $total = array();
 87+ while (!feof($fh)) {
 88+ if (preg_match('/^([0-9]{4})([0-9]{2})([0-9]{2}),(.+?),(.+?),(.+?),(.+)$/',fgets($fh),$match)) {
 89+ list(,$y,$m,$d,$time,$user,$type,$phrase) = $match;
 90+ $p = strftime($wgSearchLogDateFormat,mktime(0,0,0,$m,1,$y));
 91+ $i = strtolower(trim($phrase));
 92+ if ($period == $wgSearchLogEntireLog || $period == $p) $total[$i] = isset($total[$i]) ? ++$total[$i] : 1;
 93+ }
 94+ }
 95+ fclose($fh);
 96+
 97+ # Render the totals in a table
 98+ $table = "\n<table class=\"sortable\" id=\"searchlog\">\n";
 99+ $table .= "<tr><th>Search phrase</th><th>Number of occurences during period</th></tr>";
 100+ foreach ($total as $k => $v) {
 101+ if($wgRequest->getBool('wpEscapeChars')) {
 102+ $k = preg_replace("/&/", "&#38;", $k);
 103+ }
 104+ $table .= "<tr><td>[[$k]]</td><td>$v</td></tr>\n";
 105+ }
 106+ $table .= "</table>\n";
 107+
 108+ } else $error = "Couldn't open log file <tt>$wgSearchLogFile</tt>";
 109+ if ($error) $wgOut->addWikiText($error,true);
 110+ else $wgOut->addWikiText($table,true);
 111+ }
 112+ }
 113+
 114+ }
 115+
 116+# Called from $wgExtensionFunctions array when initialising extensions
 117+function wfSetupSearchLog() {
 118+ global $wgLanguageCode,$wgMessageCache,$wgSearchLogFile,$wgUser;
 119+
 120+ # If a search has been posted, log the info
 121+ if (isset($_REQUEST['search'])) {
 122+ $search = $_REQUEST['search'];
 123+ if (isset($_REQUEST['fulltext'])) $type = 'fulltext';
 124+ elseif (isset($_REQUEST['go'])) $type = 'go';
 125+ else $type = 'other';
 126+
 127+ # Append the data to the file
 128+ if (empty($search)) $search = $_REQUEST[$type];
 129+ if ($fh = fopen($wgSearchLogFile,'a')) {
 130+ $text = date('Ymd,H:i:s,').$wgUser->getName().",$type,$search";
 131+ fwrite($fh,"$text\n");
 132+ fclose($fh);
 133+ }
 134+ }
 135+
 136+ # Add the messages used by the specialpage
 137+ $wgMessageCache->addMessages(array('searchlog' => 'Search Log'));
 138+
 139+ # Add the specialpage to the environment
 140+ SpecialPage::addPage(new SpecialSearchLog());
 141+ }

Follow-up revisions

RevisionCommit summaryAuthorDate
r82831Follow-up to r82829: durr.emufarmers02:50, 26 February 2011
r82838svn:eol-style native for r82829reedy09:31, 26 February 2011
r82841Fixes for r82838:...demon12:00, 26 February 2011
r96602Deleting SearchLog per concerns on r82829 that neither the author or committe...demon19:30, 8 September 2011

Comments

#Comment by 😂 (talk | contribs)   02:43, 26 February 2011
  • eol-style needs fixing
  • Uses absolutely ancient (and awful) SpecialPage::addPage() interface
  • Doesn't need message cache addMessages() calls
  • Uses old SpecialPage() constructor rather than __construct().

Basically this is really really old and needs updating :)

#Comment by 😂 (talk | contribs)   02:45, 26 February 2011

Not to mention the direct playing with $_REQUEST and such, which is almost never correct.

#Comment by 😂 (talk | contribs)   10:24, 26 February 2011

Looking at this further...this won't even *run* on trunk. wfElement() and friends were deprecated :p

#Comment by 😂 (talk | contribs)   12:07, 26 February 2011

I resolved *most* of these issues in r82841. Still using $_REQUEST directly though, which is kind of icky (is there no hook for this??)

I didn't actually install this locally, but from reading the code, it looks like this is a nice big XSS attack. The search queries are stored in a file, then pulled and put directly into double brackets in HTML. There is an option to escape &, but that's hardly sufficient. Rather than just putting it in double brackets and hoping it links, why not try to construct a title, and if it's a valid title, link to it, otherwise, output it plain (but escaped!)

#Comment by MZMcBride (talk | contribs)   16:56, 31 August 2011

Given the security issues (and general code quality), I suggest deleting this extension from SVN and marking this revision as reverted, unless Emufarmers (or someone else) wants to clean this up very soon. It's been sitting around as "fixme" since February. Time to shit or get off the pot.

#Comment by 😂 (talk | contribs)   17:00, 31 August 2011

I'm fine with that.

Status & tagging log