See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * TeX filter library functions. 19 * 20 * @package filter 21 * @subpackage tex 22 * @copyright 2004 Zbigniew Fiedorowicz fiedorow@math.ohio-state.edu 23 * Originally based on code provided by Bruno Vernier bruno@vsbeducation.ca 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 function filter_tex_get_executable($debug=false) { 30 global $CFG; 31 32 if ((PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows")) { 33 return "$CFG->dirroot/filter/tex/mimetex.exe"; 34 } 35 36 if ($pathmimetex = get_config('filter_tex', 'pathmimetex')) { 37 if (is_executable($pathmimetex)) { 38 return $pathmimetex; 39 } else { 40 print_error('mimetexnotexecutable', 'error'); 41 } 42 } 43 44 $custom_commandpath = "$CFG->dirroot/filter/tex/mimetex"; 45 if (file_exists($custom_commandpath)) { 46 if (is_executable($custom_commandpath)) { 47 return $custom_commandpath; 48 } else { 49 print_error('mimetexnotexecutable', 'error'); 50 } 51 } 52 53 switch (PHP_OS) { 54 case "Linux": return "$CFG->dirroot/filter/tex/mimetex.linux"; 55 case "Darwin": return "$CFG->dirroot/filter/tex/mimetex.darwin"; 56 case "FreeBSD": return "$CFG->dirroot/filter/tex/mimetex.freebsd"; 57 } 58 59 print_error('mimetexisnotexist', 'error'); 60 } 61 62 function filter_tex_sanitize_formula($texexp) { 63 /// Check $texexp against blacklist (whitelisting could be more complete but also harder to maintain) 64 $denylist = [ 65 'include','command','loop','repeat','open','toks','output', 66 'input','catcode','name','^^', 67 '\def','\edef','\gdef','\xdef', 68 '\every','\errhelp','\errorstopmode','\scrollmode','\nonstopmode', 69 '\batchmode','\read','\write','csname','\newhelp','\uppercase', 70 '\lowercase','\relax','\aftergroup', 71 '\afterassignment','\expandafter','\noexpand','\special', 72 '\let', '\futurelet','\else','\fi','\chardef','\makeatletter','\afterground', 73 '\noexpand','\line','\mathcode','\item','\section','\mbox','\declarerobustcommand', 74 '\ExplSyntaxOn', 75 ]; 76 77 $allowlist = ['inputenc']; 78 79 // Prepare the denylist for regular expression. 80 $denylist = array_map(function($value){ 81 return '/' . preg_quote($value, '/') . '/i'; 82 }, $denylist); 83 84 // Prepare the allowlist for regular expression. 85 $allowlist = array_map(function($value){ 86 return '/\bforbiddenkeyword_(' . preg_quote($value, '/') . ')\b/i'; 87 }, $allowlist); 88 89 // First, mangle all denied words. 90 $texexp = preg_replace_callback($denylist, 91 function($matches) { 92 return 'forbiddenkeyword_' . $matches[0]; 93 }, 94 $texexp 95 ); 96 97 // Then, change back the allowed words. 98 $texexp = preg_replace_callback($allowlist, 99 function($matches) { 100 return $matches[1]; 101 }, 102 $texexp 103 ); 104 105 return $texexp; 106 } 107 108 function filter_tex_get_cmd($pathname, $texexp) { 109 $texexp = filter_tex_sanitize_formula($texexp); 110 $texexp = escapeshellarg($texexp); 111 $executable = filter_tex_get_executable(false); 112 113 if ((PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows")) { 114 $executable = str_replace(' ', '^ ', $executable); 115 return "$executable ++ -e \"$pathname\" -- $texexp"; 116 117 } else { 118 return "\"$executable\" -e \"$pathname\" -- $texexp"; 119 } 120 } 121 122 /** 123 * Purge all caches when settings changed. 124 */ 125 function filter_tex_updatedcallback($name) { 126 global $CFG, $DB; 127 reset_text_filters_cache(); 128 129 if (file_exists("$CFG->dataroot/filter/tex")) { 130 remove_dir("$CFG->dataroot/filter/tex"); 131 } 132 if (file_exists("$CFG->dataroot/filter/algebra")) { 133 remove_dir("$CFG->dataroot/filter/algebra"); 134 } 135 if (file_exists("$CFG->tempdir/latex")) { 136 remove_dir("$CFG->tempdir/latex"); 137 } 138 139 $DB->delete_records('cache_filters', array('filter'=>'tex')); 140 $DB->delete_records('cache_filters', array('filter'=>'algebra')); 141 142 $pathlatex = get_config('filter_tex', 'pathlatex'); 143 if ($pathlatex === false) { 144 // detailed settings not present yet 145 return; 146 } 147 148 $pathlatex = trim($pathlatex, " '\""); 149 $pathdvips = trim(get_config('filter_tex', 'pathdvips'), " '\""); 150 $pathconvert = trim(get_config('filter_tex', 'pathconvert'), " '\""); 151 $pathdvisvgm = trim(get_config('filter_tex', 'pathdvisvgm'), " '\""); 152 153 $supportedformats = array('gif'); 154 if ((is_file($pathlatex) && is_executable($pathlatex)) && 155 (is_file($pathdvips) && is_executable($pathdvips))) { 156 if (is_file($pathconvert) && is_executable($pathconvert)) { 157 $supportedformats[] = 'png'; 158 } 159 if (is_file($pathdvisvgm) && is_executable($pathdvisvgm)) { 160 $supportedformats[] = 'svg'; 161 } 162 } 163 if (!in_array(get_config('filter_tex', 'convertformat'), $supportedformats)) { 164 set_config('convertformat', array_pop($supportedformats), 'filter_tex'); 165 } 166 167 } 168
title
Description
Body
title
Description
Body
title
Description
Body
title
Body