From f7f0909ce57ccd17524700c220d42c55e0078f4e Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Sun, 13 Mar 2011 15:09:23 +0100 Subject: [PATCH] PULL-442 multiple TeX related fixes Prevent moodle_url error, cleanup entity encoding and decoding, disable tex source view when TeX and Algebra plugins disabled, localise TeX source popup and prevent phishing attempts, fix executable permission of Algebra pearl script, prevent image error in tex debug when Tex/Ghostscript not configured properly, fix copyright blocks and phpdocs, improve coding style, fix wrong source display link in Algebra filter. --- filter/algebra/algebra2tex.pl | 0 filter/algebra/filter.php | 18 ++--- filter/tex/db/upgrade.php | 42 ++++++++++ filter/tex/displaytex.php | 59 +++++++++++--- filter/tex/filter.php | 125 +++++++++++++++++------------- filter/tex/filtersettings.php | 23 ++++++ filter/tex/lang/en/filter_tex.php | 9 ++- filter/tex/lib.php | 24 ++++++ filter/tex/pix.php | 2 +- filter/tex/texdebug.php | 43 +++++++--- filter/tex/version.php | 2 +- 11 files changed, 251 insertions(+), 96 deletions(-) mode change 100644 => 100755 filter/algebra/algebra2tex.pl create mode 100644 filter/tex/db/upgrade.php diff --git a/filter/algebra/algebra2tex.pl b/filter/algebra/algebra2tex.pl old mode 100644 new mode 100755 diff --git a/filter/algebra/filter.php b/filter/algebra/filter.php index f5ff02809d7..a6fc6a28a3a 100644 --- a/filter/algebra/filter.php +++ b/filter/algebra/filter.php @@ -50,15 +50,11 @@ function filter_algebra_image($imagefile, $tex= "", $height="", $width="", $alig global $CFG, $OUTPUT; $output = ""; - $origtex = $tex; $style = 'style="border:0px; vertical-align:'.$align.';'; + $title = ''; if ($tex) { - $tex = str_replace('&','&',$tex); - $tex = str_replace('<','<',$tex); - $tex = str_replace('>','>',$tex); - $tex = str_replace('"','"',$tex); - $tex = str_replace("\'",''',$tex); - $title = "title=\"$tex\""; + $tex = html_entity_decode($tex, ENT_QUOTES, 'UTF-8'); + $title = 'title="'.s($tex).'"'; } if ($height) { $style .= " height:{$height}px;"; @@ -69,7 +65,7 @@ function filter_algebra_image($imagefile, $tex= "", $height="", $width="", $alig $style .= '"'; $anchorcontents = ''; if ($imagefile) { - $anchorcontents .= "\"".s($origtex)."\"slasharguments) { // Use this method if possible for better caching $anchorcontents .= "$CFG->wwwroot/filter/algebra/pix.php/$imagefile"; } else { @@ -77,12 +73,12 @@ function filter_algebra_image($imagefile, $tex= "", $height="", $width="", $alig } $anchorcontents .= "\" $style />"; - $link = $action = null; if (!file_exists("$CFG->dataroot/filter/algebra/$imagefile") && has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) { $link = '/filter/algebra/algebradebug.php'; + $action = null; } else { - $link = '/filter/algebra/displaytex.php?'.urlencode($tex); - $action = new popup_action('click', $link, 'popup', array('height'=>300,'width'=>240)); + $link = new moodle_url('/filter/tex/displaytex.php', array('texexp'=>$tex)); + $action = new popup_action('click', $link, 'popup', array('width'=>320,'height'=>240)); //TODO: the popups do not work when text caching is enabled!! } $output .= $OUTPUT->action_link($link, $anchorcontents, $action, array('title'=>'TeX')); diff --git a/filter/tex/db/upgrade.php b/filter/tex/db/upgrade.php new file mode 100644 index 00000000000..db046016414 --- /dev/null +++ b/filter/tex/db/upgrade.php @@ -0,0 +1,42 @@ +. + +/** + * TeX filter upgrade code. + * + * @package filter + * @subpackage tex + * @copyright 2011 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * @param int $oldversion the version we are upgrading from + * @return bool result + */ +function xmldb_filter_tex_upgrade($oldversion) { + global $CFG, $DB, $OUTPUT; + + if ($oldversion < 2011031301) { + // clear caches + require_once("$CFG->dirroot/filter/tex/lib.php"); + filter_tex_updatedcallback(null); + + upgrade_plugin_savepoint(true, 2011031301, 'filter', 'tex'); + } + + return true; +} diff --git a/filter/tex/displaytex.php b/filter/tex/displaytex.php index be70dc7b5bf..ddc6ee6fa82 100644 --- a/filter/tex/displaytex.php +++ b/filter/tex/displaytex.php @@ -1,20 +1,55 @@ . - require_once('../../config.php'); +/** + * This script displays tex source code, it is used also from the algebra filter. + * + * @package filter + * @subpackage tex + * @copyright 2004 Zbigniew Fiedorowicz fiedorow@math.ohio-state.edu + * Originally based on code provided by Bruno Vernier bruno@vsbeducation.ca + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +define('NO_MOODLE_COOKIES', true); // Because it interferes with caching + +require('../../config.php'); + +if (!filter_is_enabled('filter/tex') and !filter_is_enabled('filter/algebra')) { + print_error('filternotenabled'); +} + +$texexp = optional_param('texexp', '', PARAM_RAW); + +$title = get_string('source', 'filter_tex') - $texexp = urldecode($_SERVER['QUERY_STRING']); - // entities are usually encoded twice, first in HTML editor then in tex/filter.php - $texexp = html_entity_decode(html_entity_decode($texexp)); - // encode all entities (saves non-ISO) - $texexp = htmlentities($texexp,ENT_COMPAT,'utf-8'); ?> + - TeX Source - + <?php echo $title; ?> + - - + +
+
+
:
+
+
+
- \ No newline at end of file + diff --git a/filter/tex/filter.php b/filter/tex/filter.php index 78a831ec895..ddff02c2f10 100644 --- a/filter/tex/filter.php +++ b/filter/tex/filter.php @@ -1,5 +1,4 @@ ... tags to gif images using + * mimetex.cgi obtained from http: *www.forkosh.com/mimetex.html authored by + * John Forkosh john@forkosh.com. Several binaries of this areincluded with + * this distribution. + * Note that there may be patent restrictions on the production of gif images + * in Canada and some parts of Western Europe and Japan until July 2004. + * * @package filter * @subpackage tex * @copyright 2004 Zbigniew Fiedorowicz fiedorow@math.ohio-state.edu @@ -24,27 +32,24 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -//------------------------------------------------------------------------- -// NOTE: This Moodle text filter converts TeX expressions delimited -// by either $$...$$ or by ... tags to gif images using -// mimetex.cgi obtained from http://www.forkosh.com/mimetex.html authored by -// John Forkosh john@forkosh.com. Several binaries of this areincluded with -// this distribution. -// Note that there may be patent restrictions on the production of gif images -// in Canada and some parts of Western Europe and Japan until July 2004. -//------------------------------------------------------------------------- -///////////////////////////////////////////////////////////////////////////// -// To activate this filter, add a line like this to your // -// list of filters in your Filter configuration: // -// // -// filter/tex/filter.php // -///////////////////////////////////////////////////////////////////////////// +defined('MOODLE_INTERNAL') || die; -function filter_text_image($imagefile, $tex= "", $height="", $width="", $align="middle", $alt='') { +/** + * Create TeX image link. + * + * @param string $imagefile name of file + * @param string $tex TeX notation (html entities already decoded) + * @param int $height O means automatic + * @param int $width O means automatic + * @param string $align + * @param string $alt + * @return string HTML markup + */ +function filter_text_image($imagefile, $tex, $height, $width, $align, $alt) { global $CFG, $OUTPUT; - if ($alt==='') { - $alt = s($tex); + if (!$imagefile) { + throw new coding_exception('image file argument empty in filter_text_image()'); } // Work out any necessary inline style. @@ -65,47 +70,46 @@ function filter_text_image($imagefile, $tex= "", $height="", $width="", $align=" } // Prepare the title attribute. - if ($tex) { - $tex = str_replace('&','&',$tex); - $tex = str_replace('<','<',$tex); - $tex = str_replace('>','>',$tex); - $tex = str_replace('"','"',$tex); - $tex = str_replace("\'",''',$tex); - // Note that we retain the title tag as TeX format rather than using - // the alt text, even if supplied. The alt text is intended for blind - // users (to provide a text equivalent to the equation) while the title - // is there as a convenience for sighted users who want to see the TeX - // code. - $title = "title=\"$tex\""; + // Note that we retain the title tag as TeX format rather than using + // the alt text, even if supplied. The alt text is intended for blind + // users (to provide a text equivalent to the equation) while the title + // is there as a convenience for sighted users who want to see the TeX + // code. + $title = 'title="'.s($tex).'"'; + + if ($alt === '') { + $alt = s($tex); + } else { + $alt = s(html_entity_decode($tex, ENT_QUOTES, 'UTF-8')); } // Build the output. - $output = ""; - if ($imagefile) { - $anchorcontents = "\"$alt\"slasharguments) { // Use this method if possible for better caching - $anchorcontents .= "$CFG->wwwroot/filter/tex/pix.php/$imagefile"; - } else { - $anchorcontents .= "$CFG->wwwroot/filter/tex/pix.php?file=$imagefile"; - } - $anchorcontents .= "\" $style/>"; - - $link = $action = null; - if (!file_exists("$CFG->dataroot/filter/tex/$imagefile") && has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) { - $link = '/filter/tex/texdebug.php'; - } else { - $link = '/filter/tex/displaytex.php?'.urlencode($tex); - $action = new popup_action('click', $link, 'popup', array('height'=>300,'width'=>240)); - } - $output .= $OUTPUT->action_link($link, $anchorcontents, $action, array('title'=>'TeX')); + $anchorcontents = "\"$alt\"slasharguments) { // Use this method if possible for better caching + $anchorcontents .= "$CFG->wwwroot/filter/tex/pix.php/$imagefile"; } else { - $output .= "Error: must pass URL or course"; + $anchorcontents .= "$CFG->wwwroot/filter/tex/pix.php?file=$imagefile"; } + $anchorcontents .= "\" $style/>"; + + if (!file_exists("$CFG->dataroot/filter/tex/$imagefile") && has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) { + $link = '/filter/tex/texdebug.php'; + $action = null; + } else { + $link = new moodle_url('/filter/tex/displaytex.php', array('texexp'=>$tex)); + $action = new popup_action('click', $link, 'popup', array('width'=>320,'height'=>240)); + } + $output = $OUTPUT->action_link($link, $anchorcontents, $action, array('title'=>'TeX')); //TODO: the popups do not work when text caching is enabled!! + return $output; } + +/** + * TeX filtering class. + */ class filter_tex extends moodle_text_filter { - function filter ($text, array $options = array()) { + function filter($text, array $options = array()) { global $CFG, $DB; @@ -132,9 +136,9 @@ class filter_tex extends moodle_text_filter { # } $text .= ' '; preg_match_all('/\$(\$\$+?)([^\$])/s',$text,$matches); - for ($i=0;$i TeX expression @@ -159,8 +163,17 @@ class filter_tex extends moodle_text_filter { $align = "text-top"; $texexp = preg_replace('/^align=top /','',$texexp); } + + // decode entities encoded by editor, luckily there is very little chance of double decoding + $texexp = html_entity_decode($texexp, ENT_QUOTES, 'UTF-8'); + + if ($texexp === '') { + contninue; + } + $md5 = md5($texexp); - if (! $texcache = $DB->get_record("cache_filters", array("filter"=>"tex", "md5key"=>$md5))) { + if (!$DB->record_exists("cache_filters", array("filter"=>"tex", "md5key"=>$md5))) { + $texcache = new stdClass(); $texcache->filter = 'tex'; $texcache->version = 1; $texcache->md5key = $md5; @@ -169,7 +182,7 @@ class filter_tex extends moodle_text_filter { $DB->insert_record("cache_filters", $texcache, false); } $filename = $md5 . ".{$CFG->filter_tex_convertformat}"; - $text = str_replace( $matches[0][$i], filter_text_image($filename, $texexp, '', '', $align, $alt), $text); + $text = str_replace( $matches[0][$i], filter_text_image($filename, $texexp, 0, 0, $align, $alt), $text); } return $text; } diff --git a/filter/tex/filtersettings.php b/filter/tex/filtersettings.php index 29ca17d511e..c0244e88bb1 100644 --- a/filter/tex/filtersettings.php +++ b/filter/tex/filtersettings.php @@ -1,4 +1,27 @@ . + +/** + * TeX filter settings + * + * @package filter + * @subpackage tex + * @copyright 2007 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ defined('MOODLE_INTERNAL') || die; diff --git a/filter/tex/lang/en/filter_tex.php b/filter/tex/lang/en/filter_tex.php index f7166ed7773..8290d7b6cda 100644 --- a/filter/tex/lang/en/filter_tex.php +++ b/filter/tex/lang/en/filter_tex.php @@ -1,5 +1,4 @@ . + +/** + * TeX filter library functions. + * + * @package filter + * @subpackage tex + * @copyright 2004 Zbigniew Fiedorowicz fiedorow@math.ohio-state.edu + * Originally based on code provided by Bruno Vernier bruno@vsbeducation.ca + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ defined('MOODLE_INTERNAL') || die(); diff --git a/filter/tex/pix.php b/filter/tex/pix.php index 45b1b79b673..deb43d58938 100644 --- a/filter/tex/pix.php +++ b/filter/tex/pix.php @@ -42,7 +42,7 @@ define('NO_MOODLE_COOKIES', true); // Because it interferes with caching $latex = new latex(); $density = $CFG->filter_tex_density; $background = $CFG->filter_tex_latexbackground; - $texexp = html_entity_decode($texcache->rawtext); + $texexp = $texcache->rawtext; // the entities are now decoded before inserting to DB $latex_path = $latex->render($texexp, $md5, 12, $density, $background); if ($latex_path) { copy($latex_path, $pathname); diff --git a/filter/tex/texdebug.php b/filter/tex/texdebug.php index a53f2ee8822..35f1afb4642 100644 --- a/filter/tex/texdebug.php +++ b/filter/tex/texdebug.php @@ -1,7 +1,30 @@ . + +/** + * This function fetches math. images from the data directory + * If not, it obtains the corresponding TeX expression from the cache_tex db table + * and uses mimeTeX to create the image file + * + * @package filter + * @subpackage tex + * @copyright 2004 Zbigniew Fiedorowicz fiedorow@math.ohio-state.edu + * Originally based on code provided by Bruno Vernier bruno@vsbeducation.ca + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ require_once("../../config.php"); @@ -19,7 +42,6 @@ require_login(); require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM), $USER->id); /// Required cap to run this. MDL-18552 - $query = urldecode($_SERVER['QUERY_STRING']); $output = ''; // look up in cache if required @@ -99,10 +121,7 @@ header("Content-type: text/html; charset=utf-8"); echo "
\n";
         if ($texexp) {
-            $texexp = str_replace('<', '<', $texexp);
-            $texexp = str_replace('>', '>', $texexp);
-            $texexp = str_replace('"', '"', $texexp);
-            echo "$texexp\n\n";
+            echo s($texexp)."\n\n";
         } else {
             echo "No text output available\n\n";
         }
@@ -237,10 +256,12 @@
         $output .= execute($cmd);
 
         if (!$graphic) {
-            echo($output);
-        } else {
+            echo $output;
+        } else if (file_exists($img)){
             send_file($img, "$md5.{$CFG->filter_tex_convertformat}");
-         }
+        } else {
+            echo "Error creating image, see command execution output for more details.";
+        }
     }
 
     function execute($cmd) {
diff --git a/filter/tex/version.php b/filter/tex/version.php
index d7ceba5cdd0..9c5df143a09 100644
--- a/filter/tex/version.php
+++ b/filter/tex/version.php
@@ -26,4 +26,4 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2010073000;
+$plugin->version = 2011031301;