Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
            throw new \moodle_exception('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
            throw new \moodle_exception('mimetexnotexecutable', 'error');
50
        }
51
    }
52
 
53
    switch (PHP_OS) {
54
        case "Darwin":  return "$CFG->dirroot/filter/tex/mimetex.darwin";
55
        case "FreeBSD": return "$CFG->dirroot/filter/tex/mimetex.freebsd";
56
        case "Linux":
57
            if (php_uname('m') == 'aarch64') {
58
                return "$CFG->dirroot/filter/tex/mimetex.linux.aarch64";
59
            }
60
 
61
            return "$CFG->dirroot/filter/tex/mimetex.linux";
62
    }
63
 
64
    throw new \moodle_exception('mimetexisnotexist', 'error');
65
}
66
 
67
/**
68
 * Check the formula expression against the list of denied keywords.
69
 *
70
 * List of allowed could be more complete but also harder to maintain.
71
 *
72
 * @param string $texexp Formula expression to check.
73
 * @return string Formula expression with denied keywords replaced with 'forbiddenkeyword'.
74
 */
75
function filter_tex_sanitize_formula(string $texexp): string {
76
 
77
    $denylist = [
78
        'include', 'command', 'loop', 'repeat', 'open', 'toks', 'output',
79
        'input', 'catcode', 'name', '^^',
80
        '\def', '\edef', '\gdef', '\xdef',
81
        '\every', '\errhelp', '\errorstopmode', '\scrollmode', '\nonstopmode',
82
        '\batchmode', '\read', '\write', 'csname', '\newhelp', '\uppercase',
83
        '\lowercase', '\relax', '\aftergroup',
84
        '\afterassignment', '\expandafter', '\noexpand', '\special',
85
        '\let', '\futurelet', '\else', '\fi', '\chardef', '\makeatletter', '\afterground',
86
        '\noexpand', '\line', '\mathcode', '\item', '\section', '\mbox', '\declarerobustcommand',
11 efrain 87
        '\ExplSyntaxOn', '\pdffiledump',
1 efrain 88
    ];
89
 
90
    $allowlist = ['inputenc'];
91
 
92
    // Prepare the denylist for regular expression.
93
    $denylist = array_map(function($value){
94
        return '/' . preg_quote($value, '/') . '/i';
95
    }, $denylist);
96
 
97
    // Prepare the allowlist for regular expression.
98
    $allowlist = array_map(function($value){
99
        return '/\bforbiddenkeyword_(' . preg_quote($value, '/') . ')\b/i';
100
    }, $allowlist);
101
 
102
    // First, mangle all denied words.
103
    $texexp = preg_replace_callback($denylist,
104
        function($matches) {
105
            return 'forbiddenkeyword_' . $matches[0];
106
        },
107
        $texexp
108
    );
109
 
110
    // Then, change back the allowed words.
111
    $texexp = preg_replace_callback($allowlist,
112
        function($matches) {
113
            return $matches[1];
114
        },
115
        $texexp
116
    );
117
 
118
    return $texexp;
119
}
120
 
121
function filter_tex_get_cmd($pathname, $texexp) {
122
    $texexp = filter_tex_sanitize_formula($texexp);
123
    $texexp = escapeshellarg($texexp);
124
    $executable = filter_tex_get_executable(false);
125
 
126
    if ((PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows")) {
127
        $executable = str_replace(' ', '^ ', $executable);
128
        return "$executable ++ -e  \"$pathname\" -- $texexp";
129
 
130
    } else {
131
        return "\"$executable\" -e \"$pathname\" -- $texexp";
132
    }
133
}
134
 
135
/**
136
 * Purge all caches when settings changed.
137
 */
138
function filter_tex_updatedcallback($name) {
139
    global $CFG, $DB;
140
    reset_text_filters_cache();
141
 
142
    if (file_exists("$CFG->dataroot/filter/tex")) {
143
        remove_dir("$CFG->dataroot/filter/tex");
144
    }
145
    if (file_exists("$CFG->dataroot/filter/algebra")) {
146
        remove_dir("$CFG->dataroot/filter/algebra");
147
    }
148
    if (file_exists("$CFG->tempdir/latex")) {
149
        remove_dir("$CFG->tempdir/latex");
150
    }
151
 
152
    $DB->delete_records('cache_filters', array('filter'=>'tex'));
153
    $DB->delete_records('cache_filters', array('filter'=>'algebra'));
154
 
155
    $pathlatex = get_config('filter_tex', 'pathlatex');
156
    if ($pathlatex === false) {
157
        // detailed settings not present yet
158
        return;
159
    }
160
 
161
    $pathlatex = trim($pathlatex, " '\"");
162
    $pathdvips = trim(get_config('filter_tex', 'pathdvips'), " '\"");
163
    $pathconvert = trim(get_config('filter_tex', 'pathconvert'), " '\"");
164
    $pathdvisvgm = trim(get_config('filter_tex', 'pathdvisvgm'), " '\"");
165
 
166
    $supportedformats = array('gif');
167
    if ((is_file($pathlatex) && is_executable($pathlatex)) &&
168
            (is_file($pathdvips) && is_executable($pathdvips))) {
169
        if (is_file($pathconvert) && is_executable($pathconvert)) {
170
             $supportedformats[] = 'png';
171
        }
172
        if (is_file($pathdvisvgm) && is_executable($pathdvisvgm)) {
173
             $supportedformats[] = 'svg';
174
        }
175
    }
176
    if (!in_array(get_config('filter_tex', 'convertformat'), $supportedformats)) {
177
        set_config('convertformat', array_pop($supportedformats), 'filter_tex');
178
    }
179
 
180
}
181