r39090 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r39089‎ | r39090 | r39091 >
Date:21:08, 10 August 2008
Author:krimpet
Status:old
Tags:
Comment:
Converted to
Modified paths:
  • /trunk/extensions/Lua/Lua.hooks.php (added) (history)
  • /trunk/extensions/Lua/Lua.php (modified) (history)
  • /trunk/extensions/Lua/Lua.wrapper.php (added) (history)
  • /trunk/extensions/Lua/Lua.wrapper.php (added) (history)
  • /trunk/extensions/Lua/Lua_body.php (deleted) (history)

Diff [purge]

Index: trunk/extensions/Lua/Lua_body.php
@@ -1,221 +0,0 @@
2 -<?php
3 -/**
4 - * Lua parser extensions for MediaWiki - Body
5 - *
6 - * @author Fran Rogers
7 - * @package MediaWiki
8 - * @addtogroup Extensions
9 - * @license See 'COPYING'
10 - * @file
11 - */
12 -
13 -function efLua_ParserInit() {
14 - global $wgParser;
15 - $wgParser->setHook( 'lua', 'efLua_Render' );
16 - return true;
17 -}
18 -
19 -function efLua_FunctionSetup() {
20 - global $wgParser;
21 - $wgParser->setFunctionHook('luaexpr', 'efLua_RenderExpr');
22 -}
23 -
24 -function efLua_Magic(&$magicWords, $langCode) {
25 - $magicWords['luaexpr'] = array(0, 'luaexpr');
26 - return true;
27 -}
28 -
29 -function efLua_BeforeTidy(&$parser, &$text) {
30 - if (!isset($wgLua)) {
31 - efLua_Cleanup();
32 - }
33 - return TRUE;
34 -}
35 -
36 -function efLua_Render($input, $args, &$parser) {
37 - $arglist = '';
38 - foreach ($args as $key => $value)
39 - $arglist .= (preg_replace('/\W/', '', $key) . '=\'' .
40 - addslashes($parser->recursiveTagParse($value)) .
41 - '\';');
42 - if ($arglist) {
43 - try {
44 - efLua_Eval($arglist);
45 - } catch (LuaError $e) {
46 - return $e->getMessage();
47 - }
48 - }
49 -
50 - try {
51 - return $parser->recursiveTagParse(efLua_Eval($input));
52 - } catch (LuaError $e) {
53 - return $e->getMessage();
54 - }
55 - }
56 -
57 -function efLua_RenderExpr(&$parser, $param1 = FALSE) {
58 - if ($param1 == FALSE)
59 - return '';
60 - try {
61 - return efLua_Eval("io.write($param1)");
62 - } catch (LuaError $e) {
63 - return $e->getMessage();
64 - }
65 -}
66 -
67 -
68 -/**
69 - * @todo Nearly all of these evaluate() calls should be replaced, as bugs
70 - * in the Lua PECL extension are fixed.
71 - */
72 -function efLua_Eval($input) {
73 - global $wgLuaExternalInterpreter, $wgLuaDefunct,
74 - $wgLua, $wgLuaSandbox, $wgLuaWrapperFile,
75 - $wgLuaMaxLines, $wgLuaMaxCalls;
76 - if (isset($wgLuaDefunct) && $wgLuaDefunct) {
77 - return '';
78 - } else if ($wgLuaExternalInterpreter != FALSE) {
79 - return efLua_EvalExternal($input);
80 - } else if (!class_exists('lua')) {
81 - $wgLuaDefunct = true;
82 - throw new LuaError('extension_notfound');
83 - }
84 -
85 - if (!isset($wgLua)) {
86 - $wgLua = new lua;
87 - try {
88 - $wgLua->evaluatefile($wgLuaWrapperFile);
89 - $wgLua->evaluate("sandbox = make_sandbox()");
90 - $wgLua->evaluate("function _die(reason)".
91 - " _G._DEAD = reason; end");
92 - $wgLua->evaluate("hook = make_hook($wgLuaMaxLines, ".
93 - "$wgLuaMaxCalls, _die)");
94 - // @todo Especially these ones. :/
95 - } catch (Exception $e) {
96 - throw new LuaError('error_internal');
97 - }
98 - }
99 -
100 - $wgLua->input = $input;
101 - $wgLua->evaluate('chunk, err = loadstring(input)');
102 - if ($err = $wgLua->err) {
103 - $err = preg_replace('/^\[.+?\]:(.+?):/', '$1:', $err);
104 - throw new LuaError('error', $err);
105 - }
106 - $wgLua->res = $wgLua->err = NULL;
107 -
108 - $wgLua->evaluate('res, err = wrap(chunk, sandbox, hook)');
109 -
110 - if (($err = $wgLua->_DEAD) || ($err = $wgLua->err)) {
111 - if ($err == 'RECURSION_LIMIT') {
112 - efLua_CleanupExternal();
113 - throw new LuaError('overflow_recursion');
114 - } else if ($err == 'LOC_LIMIT') {
115 - efLua_CleanupExternal();
116 - throw new LuaError('overflow_loc');
117 - } else {
118 - $err = preg_replace('/^\[.+?\]:(.+?):/', '$1:', $err);
119 - throw new LuaError('error', $err);
120 - }
121 - }
122 -
123 - $wgLua->evaluate('_OUTPUT = sandbox._OUTPUT'); // ugh, please fix!
124 - $out = $wgLua->_OUTPUT;
125 - return (trim($out) != '') ? $out : '';
126 -}
127 -
128 -function efLua_Cleanup() {
129 - global $wgLuaExternalInterpreter, $wgLuaDefunct, $wgLua;
130 - if (isset($wgLuaDefunct) && $wgLuaDefunct) {
131 - return FALSE;
132 - } else if (isset($wgLuaExternalInterpreter)) {
133 - return efLua_CleanupExternal();
134 - } else if (isset($wgLua)) {
135 - $wgLuaDefunct = TRUE;
136 - $wgLua = FALSE;
137 - return TRUE;
138 - }
139 -}
140 -
141 -function efLua_EvalExternal($input) {
142 - global $wgLuaExternalInterpreter, $wgLuaProc, $wgLuaPipes,
143 - $wgLuaWrapperFile, $wgLuaMaxLines, $wgLuaMaxCalls,
144 - $wgLuaMaxTime;
145 - if (!isset($wgLuaProc)) {
146 - $wgLua = TRUE;
147 - $luacmd = "$wgLuaExternalInterpreter $wgLuaWrapperFile $wgLuaMaxLines $wgLuaMaxCalls";
148 - $wgLuaProc = proc_open($luacmd,
149 - array(0 => array('pipe', 'r'),
150 - 1 => array('pipe', 'w')),
151 - $wgLuaPipes, NULL, NULL);
152 - if (!is_resource($wgLuaProc)) {
153 - $wgLuaDefunct = true;
154 - throw new LuaError('interp_notfound');
155 - }
156 - stream_set_blocking($wgLuaPipes[0], 0);
157 - stream_set_blocking($wgLuaPipes[1], 0);
158 - stream_set_write_buffer($wgLuaPipes[0], 0);
159 - stream_set_write_buffer($wgLuaPipes[1], 0);
160 - }
161 -
162 - $input = trim(preg_replace('/(?<=\n|^)\.(?=\n|$)/', '. --', $input));
163 - fwrite($wgLuaPipes[0], "$input\n.\n");
164 - fflush($wgLuaPipes[0]);
165 -
166 - $res = '';
167 - $read = array($wgLuaPipes[1]);
168 - $write = NULL;
169 - $except = NULL;
170 - while (!feof($wgLuaPipes[1])) {
171 - if (false === ($num_changed_streams =
172 - @stream_select($read, $write, $except,
173 - $wgLuaMaxTime))) {
174 - efLua_CleanupExternal();
175 - throw new LuaError('overflow_time');
176 - }
177 - $line = fgets($wgLuaPipes[1]);
178 - if ($line == ".\n")
179 - break;
180 - $res .= $line;
181 - }
182 -
183 - if (preg_match('/^\'(.*)\', (true|false)$/s', trim($res), $match) != 1) {
184 - efLua_CleanupExternal();
185 - throw new LuaError('error_internal');
186 - }
187 -
188 - $out = $match[1];
189 - if ($match[2] == 'true') {
190 - return (trim($out) != '') ? $out : '';
191 - } else {
192 - if ($out == 'RECURSION_LIMIT') {
193 - efLua_CleanupExternal();
194 - throw new LuaError('overflow_recursion');
195 - } else if ($out == 'LOC_LIMIT') {
196 - efLua_CleanupExternal();
197 - throw new LuaError('overflow_loc');
198 - } else {
199 - $out = preg_replace('/^\[.+?\]:(.+?):/', '$1:', $out);
200 - throw new LuaError('error', $out);
201 - }
202 - }
203 -}
204 -
205 -function efLua_CleanupExternal() {
206 - global $wgLuaExternalInterpreter, $wgLuaDefunct,
207 - $wgLuaProc, $wgLuaPipes;
208 - if (isset($wgLuaProc)) {
209 - fclose($wgLuaPipes[0]);
210 - fclose($wgLuaPipes[1]);
211 - proc_close($wgLuaProc);
212 - }
213 - $wgLuaDefunct = TRUE;
214 - return TRUE;
215 -}
216 -
217 -class LuaError extends Exception {
218 - public function __construct($msg, $parameter = ''){
219 - wfLoadExtensionMessages( 'Lua' );
220 - $this->message = '<strong class="error">' . wfMsgForContent( "lua_$msg", htmlspecialchars( $parameter ) ) . '</strong>';
221 - }
222 -}
Index: trunk/extensions/Lua/Lua.wrapper.php
@@ -0,0 +1,173 @@
 2+<?php
 3+/**
 4+ * Lua parser extensions for MediaWiki - Wrapper classes
 5+ *
 6+ * @author Fran Rogers
 7+ * @package MediaWiki
 8+ * @addtogroup Extensions
 9+ * @license See 'COPYING'
 10+ * @file
 11+ */
 12+
 13+class LuaError extends Exception {
 14+ public function __construct($msg, $parameter = ''){
 15+ wfLoadExtensionMessages( 'Lua' );
 16+ $this->message = '<strong class="error">' . wfMsgForContent( "lua_$msg", htmlspecialchars( $parameter ) ) . '</strong>';
 17+ }
 18+}
 19+
 20+class LuaWrapper {
 21+ protected $defunct;
 22+
 23+ static function create() {
 24+ global $wgLuaExternalInterpreter;
 25+ return $wgLuaExternalInterpreter ?
 26+ new LuaWrapperExternal :
 27+ new LuaWrapper;
 28+ }
 29+
 30+ private $lua;
 31+
 32+ protected function __construct() {
 33+ global $wgLuaWrapperFile, $wgLuaMaxLines, $wgLuaMaxCalls;
 34+ if (!class_exists('lua')) {
 35+ $this->defunct = TRUE;
 36+ throw new LuaError('extension_notfound');
 37+ }
 38+ $this->lua = new lua;
 39+ try {
 40+ $this->lua->evaluatefile($wgLuaWrapperFile);
 41+ $this->lua->evaluate("sandbox = make_sandbox()");
 42+ $this->lua->evaluate("function _die(reason) _G._DEAD = reason; end");
 43+ $this->lua->evaluate("hook = make_hook($wgLuaMaxLines, $wgLuaMaxCalls, _die)");
 44+ $this->defunct = FALSE;
 45+ } catch (Exception $e) {
 46+ $this->kill();
 47+ throw new LuaError('error_internal');
 48+ }
 49+ }
 50+
 51+ public function run($input) {
 52+ if ($this->defunct)
 53+ return '';
 54+
 55+ $this->lua->input = $input;
 56+ $this->lua->evaluate('chunk, err = loadstring(input)');
 57+ if ($err = $this->lua->err) {
 58+ $err = preg_replace('/^\[.+?\]:(.+?):/', '$1:', $err);
 59+ throw new LuaError('error', $err);
 60+ }
 61+ $this->lua->res = $this->lua->err = NULL;
 62+
 63+ $this->lua->evaluate('res, err = wrap(chunk, sandbox, hook)');
 64+
 65+ if (($err = $this->lua->_DEAD) || ($err = $this->lua->err)) {
 66+ if ($err == 'RECURSION_LIMIT') {
 67+ $this->kill();
 68+ throw new LuaError('overflow_recursion');
 69+ } else if ($err == 'LOC_LIMIT') {
 70+ $this->kill();
 71+ throw new LuaError('overflow_loc');
 72+ } else {
 73+ $err = preg_replace('/^\[.+?\]:(.+?):/', '$1:', $err);
 74+ throw new LuaError('error', $err);
 75+ }
 76+ }
 77+
 78+ $this->lua->evaluate('_OUTPUT = sandbox._OUTPUT'); // ugh, please fix!
 79+ $out = $this->lua->_OUTPUT;
 80+ return (trim($out) != '') ? $out : '';
 81+ }
 82+
 83+ public function kill() {
 84+ if ($this->defunct)
 85+ return FALSE;
 86+ $this->lua = NULL;
 87+ $this->defunct = TRUE;
 88+ return TRUE;
 89+ }
 90+}
 91+
 92+class LuaWrapperExternal extends LuaWrapper {
 93+ private $proc, $pipes;
 94+ protected function __construct() {
 95+ global $wgLuaExternalInterpreter, $wgLuaWrapperFile,
 96+ $wgLuaMaxLines, $wgLuaMaxCalls;
 97+ $luacmd = "$wgLuaExternalInterpreter $wgLuaWrapperFile $wgLuaMaxLines $wgLuaMaxCalls";
 98+ $this->proc = proc_open($luacmd,
 99+ array(0 => array('pipe', 'r'),
 100+ 1 => array('pipe', 'w')),
 101+ $this->pipes, NULL, NULL);
 102+ if (!is_resource($this->proc)) {
 103+ $this->defunct = TRUE;
 104+ throw new LuaError('interp_notfound');
 105+ }
 106+ stream_set_blocking($this->pipes[0], 0);
 107+ stream_set_blocking($this->pipes[1], 0);
 108+ stream_set_write_buffer($this->pipes[0], 0);
 109+ stream_set_write_buffer($this->pipes[1], 0);
 110+ $this->defunct = FALSE;
 111+ }
 112+
 113+ public function run($input) {
 114+ global $wgLuaMaxTime;
 115+ if ($this->defunct)
 116+ return '';
 117+
 118+ $input = trim(preg_replace('/(?<=\n|^)\.(?=\n|$)/', '. --', $input));
 119+ fwrite($this->pipes[0], "$input\n.\n");
 120+ fflush($this->pipes[0]);
 121+
 122+ $res = '';
 123+ $read = array($this->pipes[1]);
 124+ $write = NULL;
 125+ $except = NULL;
 126+ while (!feof($this->pipes[1])) {
 127+ if (false === ($num_changed_streams =
 128+ @stream_select($read, $write, $except,
 129+ $wgLuaMaxTime))) {
 130+ efLua_CleanupExternal();
 131+ throw new LuaError('overflow_time');
 132+ }
 133+ $line = fgets($this->pipes[1]);
 134+ if ($line == ".\n")
 135+ break;
 136+ $res .= $line;
 137+ }
 138+
 139+ if (preg_match('/^\'(.*)\', (true|false)$/s', trim($res), $match) != 1) {
 140+ $this->kill();
 141+ throw new LuaError('error_internal');
 142+ }
 143+
 144+ $out = $match[1];
 145+ if ($match[2] == 'true') {
 146+ return (trim($out) != '') ? $out : '';
 147+ } else {
 148+ if ($out == 'RECURSION_LIMIT') {
 149+ $this->kill();
 150+ throw new LuaError('overflow_recursion');
 151+ } else if ($out == 'LOC_LIMIT') {
 152+ $this->kill();
 153+ throw new LuaError('overflow_loc');
 154+ } else {
 155+ $out = preg_replace('/^\[.+?\]:(.+?):/', '$1:', $out);
 156+ throw new LuaError('error', $out);
 157+ }
 158+ }
 159+ }
 160+
 161+ public function kill() {
 162+ if ($this->defunct)
 163+ return FALSE;
 164+
 165+ if (isset($this->proc)) {
 166+ fclose($this->pipes[0]);
 167+ fclose($this->pipes[1]);
 168+ proc_close($this->proc);
 169+ }
 170+ $this->defunct = TRUE;
 171+ return TRUE;
 172+ }
 173+}
 174+
Property changes on: trunk/extensions/Lua/Lua.wrapper.php
___________________________________________________________________
Added: svn:mergeinfo
Added: svn:eol-style
1175 + native
Index: trunk/extensions/Lua/Lua.php
@@ -15,14 +15,17 @@
1616 'svn-date' => '$LastChangedDate$',
1717 'svn-revision' => '$LastChangedRevision$',
1818 'url' => 'http://www.mediawiki.org/wiki/Extension:Lua',
19 - 'description' => 'Extends the parser with support for embedded blocks ofLua code',
 19+ 'description' => 'Extends the parser with support for embedded blocks of Lua code',
2020 'descriptionmsg' => 'lua_desc',
2121 );
2222
2323 $dir = dirname(__FILE__) . '/';
2424 $wgExtensionMessagesFiles['Lua'] = $dir . 'Lua.i18n.php';
2525 // convert me to $wgAutoloadClasses
26 -require_once( $dir . 'Lua_body.php');
 26+$wgAutoloadClasses['LuaHooks'] = $dir . 'Lua.hooks.php';
 27+$wgAutoloadClasses['LuaError'] = $dir . 'Lua.wrapper.php';
 28+$wgAutoloadClasses['LuaWrapper'] = $dir . 'Lua.wrapper.php';
 29+$wgAutoloadClasses['LuaWrapperExternal'] = $dir . 'Lua.wrapper.php';
2730 $wgLuaWrapperFile = $dir . 'LuaWrapper.lua';
2831
2932 if (!isset($wgLuaExternalInterpreter))
@@ -38,12 +41,10 @@
3942
4043 # Avoid unstubbing $wgParser on setHook() too early on modern (1.12+) MW versions, as per r35980
4144 if (defined('MW_SUPPORTS_PARSERFIRSTCALLINIT')) {
42 - $wgHooks['ParserFirstCallInit'][] = 'efLua_ParserInit';
 45+ $wgHooks['ParserFirstCallInit'][] = 'LuaHooks::parserInit';
4346 } else { // Otherwise do things the old fashioned way
44 - $wgExtensionFunctions[] = 'efLua_ParserInit';
 47+ $wgExtensionFunctions[] = 'LuaHooks::parserInit';
4548 }
46 -# Define a setup function
47 -$wgExtensionFunctions[] = 'efLua_FunctionSetup';
4849 # Add a hook to initialise the magic word
49 -$wgHooks['LanguageGetMagic'][] = 'efLua_Magic';
50 -$wgHooks['ParserBeforeTidy'][] = 'efLua_BeforeTidy';
 50+$wgHooks['LanguageGetMagic'][] = 'LuaHooks::magic';
 51+$wgHooks['ParserBeforeTidy'][] = 'LuaHooks::beforeTidy';
Index: trunk/extensions/Lua/Lua.hooks.php
@@ -0,0 +1,71 @@
 2+<?php
 3+/**
 4+ * Lua parser extensions for MediaWiki - Hooks
 5+ *
 6+ * @author Fran Rogers
 7+ * @package MediaWiki
 8+ * @addtogroup Extensions
 9+ * @license See 'COPYING'
 10+ * @file
 11+ */
 12+
 13+class LuaHooks {
 14+ public static function parserInit() {
 15+ global $wgParser;
 16+ $wgParser->setHook( 'lua', 'LuaHooks::renderTag' );
 17+ $wgParser->setFunctionHook('luaexpr', 'LuaHooks::renderExpr');
 18+ return true;
 19+ }
 20+
 21+ public static function magic(&$magicWords, $langCode) {
 22+ $magicWords['luaexpr'] = array(0, 'luaexpr');
 23+ return true;
 24+ }
 25+
 26+ public static function beforeTidy(&$parser, &$text) {
 27+ global $wgLua;
 28+ if (isset($wgLua)) {
 29+ $wgLua->kill();
 30+ }
 31+ return TRUE;
 32+ }
 33+
 34+ public static function renderTag($input, $args, &$parser) {
 35+ global $wgLua;
 36+ if (!isset($wgLua))
 37+ $wgLua = LuaWrapper::create();
 38+
 39+ $arglist = '';
 40+ foreach ($args as $key => $value)
 41+ $arglist .= (preg_replace('/\W/', '', $key) . '=\'' .
 42+ addslashes($parser->recursiveTagParse($value)) .
 43+ '\';');
 44+ if ($arglist) {
 45+ try {
 46+ $wgLua->run($arglist);
 47+ } catch (LuaError $e) {
 48+ return $e->getMessage();
 49+ }
 50+ }
 51+
 52+ try {
 53+ return $parser->recursiveTagParse($wgLua->run($input));
 54+ } catch (LuaError $e) {
 55+ return $e->getMessage();
 56+ }
 57+ }
 58+
 59+ public static function renderExpr(&$parser, $param1 = FALSE) {
 60+ global $wgLua;
 61+ if (!isset($wgLua))
 62+ $wgLua = LuaWrapper::create();
 63+
 64+ if ($param1 == FALSE)
 65+ return '';
 66+ try {
 67+ return $wgLua->run("io.write($param1)");
 68+ } catch (LuaError $e) {
 69+ return $e->getMessage();
 70+ }
 71+ }
 72+}
Property changes on: trunk/extensions/Lua/Lua.hooks.php
___________________________________________________________________
Added: svn:eol-style
173 + native

Status & tagging log