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 | * Serbian (Српски / Srpski) specific code. |
||
4 | * |
||
5 | * This program is free software; you can redistribute it and/or modify |
||
6 | * it under the terms of the GNU General Public License as published by |
||
7 | * the Free Software Foundation; either version 2 of the License, or |
||
8 | * (at your option) any later version. |
||
9 | * |
||
10 | * This program is distributed in the hope that it will be useful, |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | * GNU General Public License for more details. |
||
14 | * |
||
15 | * You should have received a copy of the GNU General Public License along |
||
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||
18 | * http://www.gnu.org/copyleft/gpl.html |
||
19 | * |
||
20 | * @file |
||
21 | * @ingroup Language |
||
22 | */ |
||
23 | |||
24 | /** |
||
25 | * There are two levels of conversion for Serbian: the script level |
||
26 | * (Cyrillics <-> Latin), and the variant level (ekavian |
||
27 | * <->iyekavian). The two are orthogonal. So we really only need two |
||
28 | * dictionaries: one for Cyrillics and Latin, and one for ekavian and |
||
29 | * iyekavian. |
||
30 | * |
||
31 | * @ingroup Language |
||
32 | */ |
||
33 | class SrConverter extends LanguageConverter { |
||
34 | public $mToLatin = [ |
||
35 | 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', |
||
36 | 'ђ' => 'đ', 'е' => 'e', 'ж' => 'ž', 'з' => 'z', 'и' => 'i', |
||
37 | 'ј' => 'j', 'к' => 'k', 'л' => 'l', 'љ' => 'lj', 'м' => 'm', |
||
38 | 'н' => 'n', 'њ' => 'nj', 'о' => 'o', 'п' => 'p', 'р' => 'r', |
||
39 | 'с' => 's', 'т' => 't', 'ћ' => 'ć', 'у' => 'u', 'ф' => 'f', |
||
40 | 'х' => 'h', 'ц' => 'c', 'ч' => 'č', 'џ' => 'dž', 'ш' => 'š', |
||
41 | |||
42 | 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', |
||
43 | 'Ђ' => 'Đ', 'Е' => 'E', 'Ж' => 'Ž', 'З' => 'Z', 'И' => 'I', |
||
44 | 'Ј' => 'J', 'К' => 'K', 'Л' => 'L', 'Љ' => 'Lj', 'М' => 'M', |
||
45 | 'Н' => 'N', 'Њ' => 'Nj', 'О' => 'O', 'П' => 'P', 'Р' => 'R', |
||
46 | 'С' => 'S', 'Т' => 'T', 'Ћ' => 'Ć', 'У' => 'U', 'Ф' => 'F', |
||
47 | 'Х' => 'H', 'Ц' => 'C', 'Ч' => 'Č', 'Џ' => 'Dž', 'Ш' => 'Š', |
||
48 | ]; |
||
49 | |||
50 | public $mToCyrillics = [ |
||
51 | 'a' => 'а', 'b' => 'б', 'c' => 'ц', 'č' => 'ч', 'ć' => 'ћ', |
||
52 | 'd' => 'д', 'dž' => 'џ', 'đ' => 'ђ', 'e' => 'е', 'f' => 'ф', |
||
53 | 'g' => 'г', 'h' => 'х', 'i' => 'и', 'j' => 'ј', 'k' => 'к', |
||
54 | 'l' => 'л', 'lj' => 'љ', 'm' => 'м', 'n' => 'н', 'nj' => 'њ', |
||
55 | 'o' => 'о', 'p' => 'п', 'r' => 'р', 's' => 'с', 'š' => 'ш', |
||
56 | 't' => 'т', 'u' => 'у', 'v' => 'в', 'z' => 'з', 'ž' => 'ж', |
||
57 | |||
58 | 'A' => 'А', 'B' => 'Б', 'C' => 'Ц', 'Č' => 'Ч', 'Ć' => 'Ћ', |
||
59 | 'D' => 'Д', 'Dž' => 'Џ', 'Đ' => 'Ђ', 'E' => 'Е', 'F' => 'Ф', |
||
60 | 'G' => 'Г', 'H' => 'Х', 'I' => 'И', 'J' => 'Ј', 'K' => 'К', |
||
61 | 'L' => 'Л', 'LJ' => 'Љ', 'M' => 'М', 'N' => 'Н', 'NJ' => 'Њ', |
||
62 | 'O' => 'О', 'P' => 'П', 'R' => 'Р', 'S' => 'С', 'Š' => 'Ш', |
||
63 | 'T' => 'Т', 'U' => 'У', 'V' => 'В', 'Z' => 'З', 'Ž' => 'Ж', |
||
64 | |||
65 | 'DŽ' => 'Џ', 'd!ž' => 'дж', 'D!ž' => 'Дж', 'D!Ž' => 'ДЖ', |
||
66 | 'Lj' => 'Љ', 'l!j' => 'лј', 'L!j' => 'Лј', 'L!J' => 'ЛЈ', |
||
67 | 'Nj' => 'Њ', 'n!j' => 'нј', 'N!j' => 'Нј', 'N!J' => 'НЈ' |
||
68 | ]; |
||
69 | |||
70 | function loadDefaultTables() { |
||
71 | $this->mTables = [ |
||
72 | 'sr-ec' => new ReplacementArray( $this->mToCyrillics ), |
||
73 | 'sr-el' => new ReplacementArray( $this->mToLatin ), |
||
74 | 'sr' => new ReplacementArray() |
||
75 | ]; |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * rules should be defined as -{ekavian | iyekavian-} -or- |
||
80 | * -{code:text | code:text | ...}- |
||
81 | * |
||
82 | * update: delete all rule parsing because it's not used |
||
83 | * currently, and just produces a couple of bugs |
||
84 | * |
||
85 | * @param string $rule |
||
86 | * @param array $flags |
||
87 | * @return array |
||
88 | */ |
||
89 | View Code Duplication | function parseManualRule( $rule, $flags = [] ) { |
|
90 | if ( in_array( 'T', $flags ) ) { |
||
91 | return parent::parseManualRule( $rule, $flags ); |
||
0 ignored issues
–
show
|
|||
92 | } |
||
93 | |||
94 | $carray = []; |
||
95 | // otherwise ignore all formatting |
||
96 | foreach ( $this->mVariants as $v ) { |
||
97 | $carray[$v] = $rule; |
||
98 | } |
||
99 | |||
100 | return $carray; |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * A function wrapper: |
||
105 | * - if there is no selected variant, leave the link |
||
106 | * names as they were |
||
107 | * - do not try to find variants for usernames |
||
108 | * |
||
109 | * @param string &$link |
||
110 | * @param Title &$nt |
||
111 | * @param bool $ignoreOtherCond |
||
112 | */ |
||
113 | View Code Duplication | function findVariantLink( &$link, &$nt, $ignoreOtherCond = false ) { |
|
114 | // check for user namespace |
||
115 | if ( is_object( $nt ) ) { |
||
116 | $ns = $nt->getNamespace(); |
||
117 | if ( $ns == NS_USER || $ns == NS_USER_TALK ) { |
||
118 | return; |
||
119 | } |
||
120 | } |
||
121 | |||
122 | $oldlink = $link; |
||
123 | parent::findVariantLink( $link, $nt, $ignoreOtherCond ); |
||
124 | if ( $this->getPreferredVariant() == $this->mMainLanguageCode ) { |
||
125 | $link = $oldlink; |
||
126 | } |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * It translates text into variant, specials: |
||
131 | * - ommiting roman numbers |
||
132 | * |
||
133 | * @param string $text |
||
134 | * @param string $toVariant |
||
135 | * |
||
136 | * @throws MWException |
||
137 | * @return string |
||
138 | */ |
||
139 | function translate( $text, $toVariant ) { |
||
140 | $breaks = '[^\w\x80-\xff]'; |
||
141 | |||
142 | // regexp for roman numbers |
||
143 | $roman = 'M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})'; |
||
144 | |||
145 | $reg = '/^' . $roman . '$|^' . $roman . $breaks . '|' . $breaks |
||
146 | . $roman . '$|' . $breaks . $roman . $breaks . '/'; |
||
147 | |||
148 | $matches = preg_split( $reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE ); |
||
149 | |||
150 | $m = array_shift( $matches ); |
||
151 | $this->loadTables(); |
||
152 | View Code Duplication | if ( !isset( $this->mTables[$toVariant] ) ) { |
|
153 | throw new MWException( "Broken variant table: " |
||
154 | . implode( ',', array_keys( $this->mTables ) ) ); |
||
155 | } |
||
156 | $ret = $this->mTables[$toVariant]->replace( $m[0] ); |
||
157 | $mstart = $m[1] + strlen( $m[0] ); |
||
158 | View Code Duplication | foreach ( $matches as $m ) { |
|
159 | $ret .= substr( $text, $mstart, $m[1] -$mstart ); |
||
160 | $ret .= parent::translate( $m[0], $toVariant ); |
||
161 | $mstart = $m[1] + strlen( $m[0] ); |
||
162 | } |
||
163 | |||
164 | return $ret; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Guess if a text is written in Cyrillic or Latin. |
||
169 | * Overrides LanguageConverter::guessVariant() |
||
170 | * |
||
171 | * @param string $text The text to be checked |
||
172 | * @param string $variant Language code of the variant to be checked for |
||
173 | * @return bool True if $text appears to be written in $variant |
||
174 | * |
||
175 | * @author Nikola Smolenski <[email protected]> |
||
176 | * @since 1.19 |
||
177 | */ |
||
178 | public function guessVariant( $text, $variant ) { |
||
179 | $numCyrillic = preg_match_all( "/[шђчћжШЂЧЋЖ]/u", $text, $dummy ); |
||
180 | $numLatin = preg_match_all( "/[šđč枊ĐČĆŽ]/u", $text, $dummy ); |
||
181 | |||
182 | if ( $variant == 'sr-ec' ) { |
||
183 | return $numCyrillic > $numLatin; |
||
184 | } elseif ( $variant == 'sr-el' ) { |
||
185 | return $numLatin > $numCyrillic; |
||
186 | } else { |
||
187 | return false; |
||
188 | } |
||
189 | } |
||
190 | |||
191 | } |
||
192 | |||
193 | /** |
||
194 | * Serbian (Српски / Srpski) |
||
195 | * |
||
196 | * @ingroup Language |
||
197 | */ |
||
198 | class LanguageSr extends Language { |
||
199 | function __construct() { |
||
200 | parent::__construct(); |
||
201 | |||
202 | $variants = [ 'sr', 'sr-ec', 'sr-el' ]; |
||
203 | $variantfallbacks = [ |
||
204 | 'sr' => 'sr-ec', |
||
205 | 'sr-ec' => 'sr', |
||
206 | 'sr-el' => 'sr', |
||
207 | ]; |
||
208 | |||
209 | $flags = [ |
||
210 | 'S' => 'S', 'писмо' => 'S', 'pismo' => 'S', |
||
211 | 'W' => 'W', 'реч' => 'W', 'reč' => 'W', 'ријеч' => 'W', 'riječ' => 'W' |
||
212 | ]; |
||
213 | $this->mConverter = new SrConverter( $this, 'sr', $variants, $variantfallbacks, $flags ); |
||
214 | } |
||
215 | } |
||
216 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: