Hannesalm /
EventCalendar
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * Class responsible for generating HTMLPurifier_Language objects, managing |
||
| 5 | * caching and fallbacks. |
||
| 6 | * @note Thanks to MediaWiki for the general logic, although this version |
||
| 7 | * has been entirely rewritten |
||
| 8 | * @todo Serialized cache for languages |
||
| 9 | */ |
||
| 10 | class HTMLPurifier_LanguageFactory |
||
|
0 ignored issues
–
show
|
|||
| 11 | { |
||
| 12 | |||
| 13 | /** |
||
| 14 | * Cache of language code information used to load HTMLPurifier_Language objects. |
||
| 15 | * Structure is: $factory->cache[$language_code][$key] = $value |
||
| 16 | * @type array |
||
| 17 | */ |
||
| 18 | public $cache; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Valid keys in the HTMLPurifier_Language object. Designates which |
||
| 22 | * variables to slurp out of a message file. |
||
| 23 | * @type array |
||
| 24 | */ |
||
| 25 | public $keys = array('fallback', 'messages', 'errorNames'); |
||
| 26 | |||
| 27 | /** |
||
| 28 | * Instance to validate language codes. |
||
| 29 | * @type HTMLPurifier_AttrDef_Lang |
||
| 30 | * |
||
| 31 | */ |
||
| 32 | protected $validator; |
||
| 33 | |||
| 34 | /** |
||
| 35 | * Cached copy of dirname(__FILE__), directory of current file without |
||
| 36 | * trailing slash. |
||
| 37 | * @type string |
||
| 38 | */ |
||
| 39 | protected $dir; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Keys whose contents are a hash map and can be merged. |
||
| 43 | * @type array |
||
| 44 | */ |
||
| 45 | protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true); |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Keys whose contents are a list and can be merged. |
||
| 49 | * @value array lookup |
||
| 50 | */ |
||
| 51 | protected $mergeable_keys_list = array(); |
||
| 52 | |||
| 53 | /** |
||
| 54 | * Retrieve sole instance of the factory. |
||
| 55 | * @param HTMLPurifier_LanguageFactory $prototype Optional prototype to overload sole instance with, |
||
| 56 | * or bool true to reset to default factory. |
||
| 57 | * @return HTMLPurifier_LanguageFactory |
||
| 58 | */ |
||
| 59 | View Code Duplication | public static function instance($prototype = null) |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 60 | { |
||
| 61 | static $instance = null; |
||
| 62 | if ($prototype !== null) { |
||
| 63 | $instance = $prototype; |
||
| 64 | } elseif ($instance === null || $prototype == true) { |
||
| 65 | $instance = new HTMLPurifier_LanguageFactory(); |
||
| 66 | $instance->setup(); |
||
| 67 | } |
||
| 68 | return $instance; |
||
| 69 | } |
||
| 70 | |||
| 71 | /** |
||
| 72 | * Sets up the singleton, much like a constructor |
||
| 73 | * @note Prevents people from getting this outside of the singleton |
||
| 74 | */ |
||
| 75 | public function setup() |
||
| 76 | { |
||
| 77 | $this->validator = new HTMLPurifier_AttrDef_Lang(); |
||
| 78 | $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier'; |
||
| 79 | } |
||
| 80 | |||
| 81 | /** |
||
| 82 | * Creates a language object, handles class fallbacks |
||
| 83 | * @param HTMLPurifier_Config $config |
||
| 84 | * @param HTMLPurifier_Context $context |
||
| 85 | * @param bool|string $code Code to override configuration with. Private parameter. |
||
| 86 | * @return HTMLPurifier_Language |
||
| 87 | */ |
||
| 88 | public function create($config, $context, $code = false) |
||
| 89 | { |
||
| 90 | // validate language code |
||
| 91 | if ($code === false) { |
||
| 92 | $code = $this->validator->validate( |
||
| 93 | $config->get('Core.Language'), |
||
| 94 | $config, |
||
| 95 | $context |
||
| 96 | ); |
||
| 97 | } else { |
||
| 98 | $code = $this->validator->validate($code, $config, $context); |
||
|
0 ignored issues
–
show
It seems like
$code defined by $this->validator->valida...ode, $config, $context) on line 98 can also be of type boolean; however, HTMLPurifier_AttrDef_Lang::validate() does only seem to accept string, maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. Loading history...
|
|||
| 99 | } |
||
| 100 | if ($code === false) { |
||
| 101 | $code = 'en'; // malformed code becomes English |
||
| 102 | } |
||
| 103 | |||
| 104 | $pcode = str_replace('-', '_', $code); // make valid PHP classname |
||
| 105 | static $depth = 0; // recursion protection |
||
| 106 | |||
| 107 | if ($code == 'en') { |
||
| 108 | $lang = new HTMLPurifier_Language($config, $context); |
||
| 109 | } else { |
||
| 110 | $class = 'HTMLPurifier_Language_' . $pcode; |
||
| 111 | $file = $this->dir . '/Language/classes/' . $code . '.php'; |
||
| 112 | if (file_exists($file) || class_exists($class, false)) { |
||
| 113 | $lang = new $class($config, $context); |
||
| 114 | } else { |
||
| 115 | // Go fallback |
||
| 116 | $raw_fallback = $this->getFallbackFor($code); |
||
|
0 ignored issues
–
show
It seems like
$code can also be of type boolean; however, HTMLPurifier_LanguageFactory::getFallbackFor() does only seem to accept string, maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. Loading history...
|
|||
| 117 | $fallback = $raw_fallback ? $raw_fallback : 'en'; |
||
| 118 | $depth++; |
||
| 119 | $lang = $this->create($config, $context, $fallback); |
||
| 120 | if (!$raw_fallback) { |
||
| 121 | $lang->error = true; |
||
| 122 | } |
||
| 123 | $depth--; |
||
| 124 | } |
||
| 125 | } |
||
| 126 | $lang->code = $code; |
||
| 127 | return $lang; |
||
| 128 | } |
||
| 129 | |||
| 130 | /** |
||
| 131 | * Returns the fallback language for language |
||
| 132 | * @note Loads the original language into cache |
||
| 133 | * @param string $code language code |
||
| 134 | * @return string|bool |
||
| 135 | */ |
||
| 136 | public function getFallbackFor($code) |
||
| 137 | { |
||
| 138 | $this->loadLanguage($code); |
||
| 139 | return $this->cache[$code]['fallback']; |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * Loads language into the cache, handles message file and fallbacks |
||
| 144 | * @param string $code language code |
||
| 145 | */ |
||
| 146 | public function loadLanguage($code) |
||
| 147 | { |
||
| 148 | static $languages_seen = array(); // recursion guard |
||
| 149 | |||
| 150 | // abort if we've already loaded it |
||
| 151 | if (isset($this->cache[$code])) { |
||
| 152 | return; |
||
| 153 | } |
||
| 154 | |||
| 155 | // generate filename |
||
| 156 | $filename = $this->dir . '/Language/messages/' . $code . '.php'; |
||
| 157 | |||
| 158 | // default fallback : may be overwritten by the ensuing include |
||
| 159 | $fallback = ($code != 'en') ? 'en' : false; |
||
| 160 | |||
| 161 | // load primary localisation |
||
| 162 | if (!file_exists($filename)) { |
||
| 163 | // skip the include: will rely solely on fallback |
||
| 164 | $filename = $this->dir . '/Language/messages/en.php'; |
||
|
0 ignored issues
–
show
$filename is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the Loading history...
|
|||
| 165 | $cache = array(); |
||
| 166 | } else { |
||
| 167 | include $filename; |
||
| 168 | $cache = compact($this->keys); |
||
| 169 | } |
||
| 170 | |||
| 171 | // load fallback localisation |
||
| 172 | if (!empty($fallback)) { |
||
| 173 | |||
| 174 | // infinite recursion guard |
||
| 175 | if (isset($languages_seen[$code])) { |
||
| 176 | trigger_error( |
||
| 177 | 'Circular fallback reference in language ' . |
||
| 178 | $code, |
||
| 179 | E_USER_ERROR |
||
| 180 | ); |
||
| 181 | $fallback = 'en'; |
||
| 182 | } |
||
| 183 | $language_seen[$code] = true; |
||
|
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$language_seen was never initialized. Although not strictly required by PHP, it is generally a good practice to add $language_seen = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. Loading history...
|
|||
| 184 | |||
| 185 | // load the fallback recursively |
||
| 186 | $this->loadLanguage($fallback); |
||
| 187 | $fallback_cache = $this->cache[$fallback]; |
||
| 188 | |||
| 189 | // merge fallback with current language |
||
| 190 | foreach ($this->keys as $key) { |
||
| 191 | if (isset($cache[$key]) && isset($fallback_cache[$key])) { |
||
| 192 | if (isset($this->mergeable_keys_map[$key])) { |
||
| 193 | $cache[$key] = $cache[$key] + $fallback_cache[$key]; |
||
| 194 | } elseif (isset($this->mergeable_keys_list[$key])) { |
||
| 195 | $cache[$key] = array_merge($fallback_cache[$key], $cache[$key]); |
||
| 196 | } |
||
| 197 | } else { |
||
| 198 | $cache[$key] = $fallback_cache[$key]; |
||
| 199 | } |
||
| 200 | } |
||
| 201 | } |
||
| 202 | |||
| 203 | // save to cache for later retrieval |
||
| 204 | $this->cache[$code] = $cache; |
||
| 205 | return; |
||
| 206 | } |
||
| 207 | } |
||
| 208 | |||
| 209 | // vim: et sw=4 sts=4 |
||
| 210 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.