Issues (40)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/LanguageHandler.php (3 issues)

1
<?php
2
3
namespace XoopsModules\Xlanguage;
4
5
/**
6
 * xLanguage module (eXtensible Language Management For XOOPS)
7
 *
8
 * You may not change or alter any portion of this comment or credits
9
 * of supporting developers from this source code or any supporting source code
10
 * which is considered copyrighted (c) material of the original comment or credit authors.
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 *
15
 * @copyright    XOOPS Project (https://xoops.org)
16
 * @license      {@link https://www.gnu.org/licenses/gpl-2.0.html GNU Public License}
17
 * @package      xlanguage
18
 * @since        2.0
19
 * @author       D.J.(phppp) [email protected]
20
 **/
21
22
use XoopsLists;
23
use XoopsModules\Xlanguage;
24
use XoopsObjectHandler;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
43
 * Class LanguageHandler
44
 */
45
class LanguageHandler extends XoopsObjectHandler
46
{
47
    public $cachedConfig;
48
49
    public function loadConfig()
50
    {
51
        $this->cachedConfig = $this->loadFileConfig();
52
    }
53
54
    /**
55
     * @param int  $id
56
     * @param bool $isBase
57
     *
58
     * @return Blanguage|Language|null
59
     */
60
    public function get($id, $isBase = true)
61
    {
62
        $array = [];
63
        $lang  = null;
64
        $id    = (int)$id;
65
        if (!$id) {
66
            return $lang;
67
        }
68
        $prefix = $isBase ? 'xlanguage_base' : 'xlanguage_ext';
69
        if (isset($this->cachedConfig[$prefix][$id])) {
70
            $array = $this->cachedConfig[$prefix][$id];
71
        } else {
72
            $sql = 'SELECT * FROM ' . $this->db->prefix($prefix) . ' WHERE lang_id=' . $id;
73
            /** @var \mysqli_result|false $result */
74
            $result = $this->db->query($sql);
75
            if ($result) {
76
                $array = $this->db->fetchArray($result);
77
            }
78
        }
79
        if (!\is_array($array) || 0 == \count($array)) {
80
            return $lang;
81
        }
82
        $lang = $this->create(false, $isBase);
83
        $lang->assignVars($array);
84
        if ($isBase) {
85
            $lang->isBase = true;
86
        }
87
88
        return $lang;
89
    }
90
91
    /**
92
     * @param string $name
93
     * @param bool   $isBase
94
     *
95
     * @return Blanguage|Language|null
96
     */
97
    public function getByName($name, $isBase = false)
98
    {
99
        $array = [];
100
        $lang  = null;
101
        if (empty($name) || \preg_match('/[^a-zA-Z0-9\_\-]/', $name)) {
102
            return $lang;
103
        }
104
105
        if (isset($this->cachedConfig['xlanguage_base'][$name])) {
106
            $array  = $this->cachedConfig['xlanguage_base'][$name];
107
            $isBase = true;
108
        } elseif (isset($this->cachedConfig['xlanguage_ext'][$name])) {
109
            $array = $this->cachedConfig['xlanguage_ext'][$name];
110
        } elseif (!isset($this->cachedConfig)) {
111
            $sql    = 'SELECT * FROM ' . $this->db->prefix('xlanguage_base') . ' WHERE lang_name=\'' . $name . '\'';
112
            $result = $this->db->query($sql);
113
            $array  = $this->db->fetchArray($result);
114
            if (!\is_array($array) || 0 == \count($array)) {
115
                $sql    = 'SELECT * FROM ' . $this->db->prefix('xlanguage_ext') . ' WHERE lang_name=\'' . $name . '\'';
116
                $result = $this->db->query($sql);
117
                $array  = $this->db->fetchArray($result);
118
                if (!\is_array($array) || 0 == \count($array)) {
119
                    return $lang;
120
                }
121
            } else {
122
                $isBase = true;
123
            }
124
        }
125
        if (empty($array)) {
126
            return $lang;
127
        }
128
        $lang = $this->create(false, $isBase);
129
        $lang->assignVars($array);
130
        if (!isset($array['lang_base'])) {
131
            $lang->isBase = true;
132
        }
133
134
        return $lang;
135
    }
136
137
    /**
138
     * @param bool $isBase
139
     *
140
     * @return array|false
141
     */
142
    public function getAll($isBase = true)
143
    {
144
        $prefix = $isBase ? 'xlanguage_base' : 'xlanguage_ext';
145
        $ret    = [];
146
        if (isset($this->cachedConfig[$prefix])) {
147
            $array = $this->cachedConfig[$prefix];
148
            foreach ($array as $lang_name => $myrow) {
149
                $lang = $this->create(false, $isBase);
150
                $lang->assignVars($myrow);
151
                $ret[$myrow['lang_name']] = &$lang;
152
                unset($lang);
153
            }
154
        } elseif (!isset($this->cachedConfig)) {
155
            //        } elseif (false === $this->cachedConfig) {
156
            $sql = 'SELECT * FROM ' . $this->db->prefix($prefix);
157
            /** @var \mysqli_result|false $result */
158
            $result = $this->db->query($sql);
159
            if (!$result) {
160
                return false;
161
            }
162
            while (false !== ($myrow = $this->db->fetchArray($result))) {
163
                $lang = $this->create(false, $isBase);
164
                $lang->assignVars($myrow);
165
                $ret[$myrow['lang_name']] = &$lang;
166
                unset($lang);
167
            }
168
        }
169
170
        return $ret;
171
    }
172
173
    /**
174
     * @return array
175
     */
176
    public function getAllList()
177
    {
178
        $baseArray = $this->getAll();
179
180
        $extArray = $this->getAll(false);
181
        $ret      = [];
182
        if ($baseArray && \is_array($baseArray)) {
183
            foreach ($baseArray as $base) {
184
                $ret[$base->getVar('lang_name')]['base'] = $base;
185
                unset($base);
186
            }
187
        }
188
        if ($extArray && \is_array($extArray)) {
189
            foreach ($extArray as $ext) {
190
                $ret[$ext->getVar('lang_base')]['ext'][] = $ext;
191
                unset($ext);
192
            }
193
        }
194
195
        return $ret;
196
    }
197
198
    /**
199
     * @param bool $isNew
200
     * @param bool $isBase
201
     *
202
     * @return Blanguage|Language
203
     */
204
    public function create($isNew = true, $isBase = true)
205
    {
206
        if ($isBase) {
207
            $lang = new Xlanguage\Blanguage($isBase);
208
        } else {
209
            $lang = new Xlanguage\Language();
210
        }
211
        if ($isNew) {
212
            $lang->setNew();
213
        }
214
215
        return $lang;
216
    }
217
218
    /**
219
     * @param \XoopsObject|Blanguage|Language $lang
220
     * @return bool|string|array
221
     * @internal param object $lang
222
     */
223
    public function insert($lang)
224
    {
225
        $val_array = [];
226
        if (!$lang->isDirty()) {
227
            return true;
228
        }
229
        if (!$lang->cleanVars()) {
230
            return false;
231
        }
232
        $lang->prepareVars();
0 ignored issues
show
The method prepareVars() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Xlanguage\Blanguage. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

232
        $lang->/** @scrutinizer ignore-call */ 
233
               prepareVars();
Loading history...
233
        foreach ($lang->cleanVars as $k => $v) {
234
            ${$k} = $v;
235
        }
236
237
        if ($lang->isNew()) {
238
            $var_array = [
239
                'lang_id',
240
                'weight',
241
                'lang_name',
242
                'lang_desc',
243
                'lang_code',
244
                'lang_charset',
245
                'lang_image',
246
                'lang_base',
247
            ];
248
            if ($lang->isBase) {
249
                $var_array = [
250
                    'lang_id',
251
                    'weight',
252
                    'lang_name',
253
                    'lang_desc',
254
                    'lang_code',
255
                    'lang_charset',
256
                    'lang_image',
257
                ];
258
            }
259
            $lang_id = $this->db->genId($lang->table . '_lang_id_seq');
260
            foreach ($var_array as $var) {
261
                $val_array[] = ${$var};
262
            }
263
            $sql = 'INSERT INTO ' . $lang->table . ' (' . \implode(',', $var_array) . ') VALUES (' . \implode(',', $val_array) . ')';
264
            if (!$result = $this->db->queryF($sql)) {
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
265
                \xoops_error('Insert language error:' . $sql);
266
267
                return false;
268
            }
269
            if (0 == $lang_id) {
270
                $lang_id = $this->db->getInsertId();
271
            }
272
            $lang->setVar('lang_id', $lang_id);
273
        } else {
274
            $var_array = [
275
                'weight',
276
                'lang_name',
277
                'lang_desc',
278
                'lang_code',
279
                'lang_charset',
280
                'lang_image',
281
                'lang_base',
282
            ];
283
            if ($lang->isBase) {
284
                $var_array = ['weight', 'lang_name', 'lang_desc', 'lang_code', 'lang_charset', 'lang_image'];
285
            }
286
            $set_array = [];
287
            foreach ($var_array as $var) {
288
                $set_array[] = "$var = " . ${$var};
289
            }
290
            $set_string = \implode(',', $set_array);
291
            $sql        = 'UPDATE ' . $lang->table . ' SET ' . $set_string . ' WHERE lang_id = ' . $lang->getVar('lang_id');
292
            if (!$result = $this->db->queryF($sql)) {
293
                \xoops_error('update language error:' . $sql);
294
295
                return false;
296
            }
297
        }
298
        $this->createConfig();
299
300
        return $lang->getVar('lang_id');
301
    }
302
303
    /**
304
     * @param \XoopsObject|Blanguage|Language $lang
305
     * @return bool
306
     * @internal param object $lang
307
     */
308
    public function delete($lang)//delete(&$lang)
309
    {
310
        if (!\is_object($lang) || !$lang->getVar('lang_id')) {
311
            return true;
312
        }
313
        $sql = 'DELETE FROM ' . $lang->table . ' WHERE lang_id= ' . $lang->getVar('lang_id');
314
        if (!$result = $this->db->query($sql)) {
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
315
            return false;
316
        }
317
        $this->createConfig();
318
319
        return true;
320
    }
321
322
    /**
323
     * @return array
324
     */
325
    public function getXoopsLangList()
326
    {
327
        return XoopsLists::getLangList();
328
    }
329
330
    /**
331
     * @return bool
332
     */
333
    public function createConfig()
334
    {
335
        $file_config = \XLANGUAGE_CONFIG_FILE;
336
        if (\is_file($file_config)) {
337
            \unlink($file_config);
338
        }
339
        if (!$fp = \fopen($file_config, 'wb')) {
340
            echo '<br> the config file can not be created: ' . $file_config;
341
342
            return false;
343
        }
344
345
        $file_content = '<?php';
346
        unset($this->cachedConfig);
347
        $baseArray = $this->getAll();
348
        if ($baseArray && \is_array($baseArray)) {
349
            $file_content .= "\n    \$" . \XLANGUAGE_CONFIG_VAR . "['xlanguage_base'] = array(";
350
            foreach ($baseArray as $lang) {
351
                $file_content .= "\n        \"" . $lang->getVar('lang_name') . '"=>array(';
352
                $file_content .= "\n            \"lang_id\"=>" . $lang->getVar('lang_id') . ',';
353
                $file_content .= "\n            \"weight\"=>" . $lang->getVar('weight') . ',';
354
                $file_content .= "\n            \"lang_name\"=>\"" . $lang->getVar('lang_name') . '",';
355
                $file_content .= "\n            \"lang_desc\"=>\"" . $lang->getVar('lang_desc') . '",';
356
                $file_content .= "\n            \"lang_code\"=>\"" . $lang->getVar('lang_code') . '",';
357
                $file_content .= "\n            \"lang_charset\"=>\"" . $lang->getVar('lang_charset') . '",';
358
                $file_content .= "\n            \"lang_image\"=>\"" . $lang->getVar('lang_image') . '"';
359
                $file_content .= "\n        ),";
360
            }
361
            $file_content .= "\n    );";
362
        }
363
364
        $extArray = $this->getAll(false);
365
        if ($extArray && \is_array($extArray)) {
366
            $file_content .= "\n    \$" . \XLANGUAGE_CONFIG_VAR . "['xlanguage_ext'] = array(";
367
            foreach ($extArray as $lang) {
368
                $file_content .= "\n        \"" . $lang->getVar('lang_name') . '"=>array(';
369
                $file_content .= "\n            \"lang_id\"=>" . $lang->getVar('lang_id') . ',';
370
                $file_content .= "\n            \"weight\"=>" . $lang->getVar('weight') . ',';
371
                $file_content .= "\n            \"lang_name\"=>\"" . $lang->getVar('lang_name') . '",';
372
                $file_content .= "\n            \"lang_desc\"=>\"" . $lang->getVar('lang_desc') . '",';
373
                $file_content .= "\n            \"lang_code\"=>\"" . $lang->getVar('lang_code') . '",';
374
                $file_content .= "\n            \"lang_charset\"=>\"" . $lang->getVar('lang_charset') . '",';
375
                $file_content .= "\n            \"lang_image\"=>\"" . $lang->getVar('lang_image') . '",';
376
                $file_content .= "\n            \"lang_base\"=>\"" . $lang->getVar('lang_base') . '"';
377
                $file_content .= "\n        ),";
378
            }
379
            $file_content .= "\n    );";
380
        }
381
382
        $file_content .= "\n?>";
383
        \fwrite($fp, $file_content);
384
        \fclose($fp);
385
386
        return true;
387
    }
388
389
    /**
390
     * @return bool|null
391
     */
392
    public function loadFileConfig()
393
    {
394
        $file_config = \XLANGUAGE_CONFIG_FILE;
395
        if (!\is_file($file_config)) {
396
            $this->createConfig();
397
        }
398
        if (!\is_readable($file_config)) {
399
            $config = null;
400
401
            return $config;
402
        }
403
        require $file_config;
404
        return ${\XLANGUAGE_CONFIG_VAR} ?? false;
405
    }
406
}
407