r50901 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r50900‎ | r50901 | r50902 >
Date:17:39, 22 May 2009
Author:sergeychernyshev
Status:deferred
Tags:
Comment:
Release 0.8.6 - some important security fixes by Tim Starling.
Modified paths:
  • /tags/extensions/Widgets/REL_0_8_6 (added) (history)
  • /tags/extensions/Widgets/REL_0_8_6/Widgets.php (replaced) (history)

Diff [purge]

Index: tags/extensions/Widgets/REL_0_8_6/smarty_plugins/modifier.validate.php
@@ -0,0 +1,31 @@
 2+<?php
 3+/*
 4+ * Smarty plugin
 5+ * -------------------------------------------------------------
 6+ * File: modifier.validate.php
 7+ * Type: modifier
 8+ * Name: validate
 9+ * Purpose: Validates parameter format ('url' by default).
 10+ * Useful when you need to validate but not escape.
 11+ * -------------------------------------------------------------
 12+ */
 13+function smarty_modifier_validate($string, $type='url')
 14+{
 15+ // mapping for PHP filters (http://us2.php.net/manual/en/filter.constants.php)
 16+ $filters = array(
 17+ 'url' => FILTER_VALIDATE_URL,
 18+ 'int' => FILTER_VALIDATE_INT,
 19+ 'boolean' => FILTER_VALIDATE_BOOLEAN,
 20+ 'float' => FILTER_VALIDATE_FLOAT,
 21+ 'email' => FILTER_VALIDATE_EMAIL,
 22+ 'ip' => FILTER_VALIDATE_IP
 23+ );
 24+
 25+ if (array_key_exists($type, $filters) && filter_var($string, $filters[$type]))
 26+ {
 27+ return $string;
 28+ }
 29+
 30+ // unless it matched some validation rule, it's not valid
 31+ return '';
 32+}
Property changes on: tags/extensions/Widgets/REL_0_8_6/smarty_plugins/modifier.validate.php
___________________________________________________________________
Name: svn:eol-style
133 + native
Index: tags/extensions/Widgets/REL_0_8_6/compiled_templates/.htaccess
@@ -0,0 +1,3 @@
 2+<Files *.php>
 3+ deny from all
 4+</Files>
Property changes on: tags/extensions/Widgets/REL_0_8_6/compiled_templates/.htaccess
___________________________________________________________________
Name: svn:eol-style
15 + native
Index: tags/extensions/Widgets/REL_0_8_6/Widgets.php
@@ -0,0 +1,248 @@
 2+<?php
 3+/**
 4+ *
 5+ * {{#widget:<WidgetName>|<name1>=<value1>|<name2>=<value2>}}
 6+ *
 7+ * @author Sergey Chernyshev
 8+ * @version $Id: Widgets.php 15 2008-06-25 21:22:40Z sergey.chernyshev $
 9+ */
 10+
 11+if ( !defined( 'MEDIAWIKI' ) ) {
 12+ echo "This file is not a valid entry point.";
 13+ exit( 1 );
 14+}
 15+
 16+$wgExtensionCredits['parserhook'][] = array(
 17+ 'path' => __FILE__,
 18+ 'name' => 'Widgets',
 19+ 'description' => 'Allows wiki administrators to add free-form widgets to wiki by just editing pages within Widget namespace. Originally developed for [http://www.ardorado.com Ardorado.com]',
 20+ 'version' => '0.8.6',
 21+ 'author' => '[http://www.sergeychernyshev.com Sergey Chernyshev] (for [http://www.semanticcommunities.com Semantic Communities LLC.])',
 22+ 'url' => 'http://www.mediawiki.org/wiki/Extension:Widgets'
 23+);
 24+
 25+/**
 26+ * Set this to the index of the Widget namespace
 27+ */
 28+if ( !defined( 'NS_WIDGET' ) ) {
 29+ define( 'NS_WIDGET', 274 );
 30+}
 31+if ( !defined( 'NS_WIDGET_TALK' ) ) {
 32+ define( 'NS_WIDGET_TALK', NS_WIDGET + 1 );
 33+} elseif ( NS_WIDGET_TALK != NS_WIDGET + 1 ) {
 34+ throw new MWException( 'Configuration error. Do not define NS_WIDGET_TALK, it is automatically set based on NS_WIDGET.' );
 35+}
 36+
 37+// Initialize Smarty
 38+require dirname(__FILE__)."/smarty/Smarty.class.php";
 39+
 40+// Parser function registration
 41+$wgExtensionFunctions[] = 'widgetNamespacesInit';
 42+$wgHooks['LanguageGetMagic'][] = 'widgetLanguageGetMagic';
 43+$wgHooks['ParserFirstCallInit'][] = 'widgetParserFunctions';
 44+
 45+function widgetParserFunctions( &$parser )
 46+{
 47+ $parser->setFunctionHook('widget', 'renderWidget');
 48+
 49+ return true;
 50+}
 51+
 52+function widgetLanguageGetMagic( &$magicWords, $langCode = "en" )
 53+{
 54+ switch ( $langCode ) {
 55+ default:
 56+ $magicWords['widget'] = array ( 0, 'widget' );
 57+ }
 58+ return true;
 59+}
 60+
 61+function renderWidget (&$parser, $widgetName)
 62+{
 63+ global $IP;
 64+
 65+ $smarty = new Smarty;
 66+ $smarty->left_delimiter = '<!--{';
 67+ $smarty->right_delimiter = '}-->';
 68+ $smarty->compile_dir = "$IP/extensions/Widgets/compiled_templates/";
 69+
 70+ // registering custom Smarty plugins
 71+ $smarty->plugins_dir[] = "$IP/extensions/Widgets/smarty_plugins/";
 72+
 73+ $smarty->security = true;
 74+ $smarty->security_settings = array(
 75+ 'IF_FUNCS' => array(
 76+ 'is_array',
 77+ 'isset',
 78+ 'array',
 79+ 'list',
 80+ 'count',
 81+ 'sizeof',
 82+ 'in_array',
 83+ 'true',
 84+ 'false',
 85+ 'null'
 86+ ),
 87+ 'MODIFIER_FUNCS' => array('validate')
 88+ );
 89+
 90+ // register the resource name "db"
 91+ $smarty->register_resource("wiki", array("wiki_get_template",
 92+ "wiki_get_timestamp",
 93+ "wiki_get_secure",
 94+ "wiki_get_trusted"));
 95+
 96+ $params = func_get_args();
 97+ array_shift($params); # first one is parser - we don't need it
 98+ array_shift($params); # second one is widget name
 99+
 100+ $params_tree = array();
 101+
 102+ foreach ($params as $param)
 103+ {
 104+ $pair = explode('=', $param, 2);
 105+
 106+ if (count($pair) == 2)
 107+ {
 108+ $key = trim($pair[0]);
 109+ $val = trim($pair[1]);
 110+ }
 111+ else
 112+ {
 113+ $key = $param;
 114+ $val = true;
 115+ }
 116+
 117+ if ($val == 'false')
 118+ {
 119+ $val = false;
 120+ }
 121+
 122+ /* If the name of the parameter has object notation
 123+
 124+ a.b.c.d
 125+
 126+ then we assign stuff to hash of hashes, not scalar
 127+
 128+ */
 129+ $keys = explode('.', $key);
 130+
 131+ // $subtree will be moved from top to the bottom and at the end will point to the last level
 132+ $subtree =& $params_tree;
 133+
 134+ // go throught all the keys but last one
 135+ $last_key = array_pop($keys);
 136+
 137+ foreach ($keys as $subkey)
 138+ {
 139+ // if next level of subtree doesn't exist yet, create an empty one
 140+ if (!array_key_exists($subkey, $subtree))
 141+ {
 142+ $subtree[$subkey] = array();
 143+ }
 144+
 145+ // move to the lower level
 146+ $subtree =& $subtree[$subkey];
 147+ }
 148+
 149+ // last portion of the key points to itself
 150+ if (isset($subtree[$last_key]))
 151+ {
 152+ // if already an array, push into it, otherwise, convert into array first
 153+ if (!is_array($subtree[$last_key]))
 154+ {
 155+ $subtree[$last_key] = array($subtree[$last_key]);
 156+ }
 157+
 158+ $subtree[$last_key][] = $val;
 159+ }
 160+ else
 161+ {
 162+ // doesn't exist yet, just setting a value
 163+ $subtree[$last_key] = $val;
 164+ }
 165+ }
 166+
 167+ $smarty->assign($params_tree);
 168+
 169+ try
 170+ {
 171+ $output = $smarty->fetch("wiki:$widgetName");
 172+ }
 173+ catch (Exception $e)
 174+ {
 175+ return "<div class=\"error\">Error in [[Widget:$widgetName]]</div>";
 176+ }
 177+
 178+ return $parser->insertStripItem( $output, $parser->mStripState );
 179+}
 180+
 181+function widgetNamespacesInit() {
 182+ global $wgExtraNamespaces, $wgNamespacesWithSubpages,
 183+ $wgGroupPermissions, $wgNamespaceProtection;
 184+
 185+ // Register namespace identifiers
 186+ if (!is_array($wgExtraNamespaces)) { $wgExtraNamespaces=array(); }
 187+ $wgExtraNamespaces = $wgExtraNamespaces + array(NS_WIDGET => 'Widget', NS_WIDGET_TALK => 'Widget_talk');
 188+
 189+ // Support subpages only for talk pages by default
 190+ $wgNamespacesWithSubpages = $wgNamespacesWithSubpages + array(
 191+ NS_WIDGET_TALK => true
 192+ );
 193+
 194+ // Assign editing to 3idgeteditor group only (widgets can be dangerous so we do it here, not in LocalSettings)
 195+ $wgGroupPermissions['*']['editwidgets'] = false;
 196+ $wgGroupPermissions['widgeteditor']['editwidgets'] = true;
 197+
 198+ // Setting required namespace permission rights
 199+ $wgNamespaceProtection[NS_WIDGET] = array( 'editwidgets' );
 200+}
 201+
 202+// put these function somewhere in your application
 203+function wiki_get_template ($widgetName, &$widgetCode, &$smarty_obj)
 204+{
 205+ $widgetTitle = Title::newFromText($widgetName, NS_WIDGET);
 206+ if ($widgetTitle && $widgetTitle->exists())
 207+ {
 208+ $widgetArticle = new Article($widgetTitle, 0);
 209+ $widgetCode = $widgetArticle->getContent();
 210+
 211+ // Remove <noinclude> sections and <includeonly> tags from form definition
 212+ $widgetCode = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $widgetCode);
 213+ $widgetCode = strtr($widgetCode, array('<includeonly>' => '', '</includeonly>' => ''));
 214+
 215+ return true;
 216+ }
 217+ else
 218+ {
 219+ return false;
 220+ }
 221+}
 222+
 223+function wiki_get_timestamp($widgetName, &$widgetTimestamp, &$smarty_obj)
 224+{
 225+ $widgetTitle = Title::newFromText($widgetName, NS_WIDGET);
 226+ if ($widgetTitle && $widgetTitle->exists())
 227+ {
 228+ $widgetArticle = new Article($widgetTitle, 0);
 229+ $widgetTimestamp = $widgetArticle->getTouched();
 230+
 231+ return true;
 232+ }
 233+ else
 234+ {
 235+ return false;
 236+ }
 237+}
 238+
 239+function wiki_get_secure($tpl_name, &$smarty_obj)
 240+{
 241+ // assume all templates are secure
 242+ return true;
 243+}
 244+
 245+function wiki_get_trusted($tpl_name, &$smarty_obj)
 246+{
 247+ // not used for templates
 248+}
 249+
Property changes on: tags/extensions/Widgets/REL_0_8_6/Widgets.php
___________________________________________________________________
Name: svn:eol-style
1250 + native
Index: tags/extensions/Widgets/REL_0_8_6/Makefile
@@ -0,0 +1,25 @@
 2+all:
 3+
 4+rel: release
 5+release:
 6+ifndef v
 7+ # Must specify version as 'v' param
 8+ #
 9+ # make rel v=1.1.1
 10+ #
 11+else
 12+ #
 13+ # Tagging it with release tag
 14+ #
 15+ svn copy . svn+ssh://sergeychernyshev@svn.wikimedia.org/svnroot/mediawiki/tags/extensions/Widgets/REL_${subst .,_,${v}}/
 16+ #
 17+ # Creating release tarball and zip
 18+ #
 19+ svn export . Widgets
 20+ svn export smarty Widgets/smarty
 21+ # Not including Makefile into the package since it's not doing anything but release packaging
 22+ rm Widgets/Makefile
 23+ tar -c Widgets |gzip > Widgets_${v}.tgz
 24+ zip -r Widgets_${v}.zip Widgets
 25+ rm -rf Widgets
 26+endif
Property changes on: tags/extensions/Widgets/REL_0_8_6/Makefile
___________________________________________________________________
Name: svn:eol-style
127 + native
Property changes on: tags/extensions/Widgets/REL_0_8_6
___________________________________________________________________
Name: svn:externals
228 + smarty http://smarty-php.googlecode.com/svn/tags/Smarty_2_6_18/libs/

Status & tagging log