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 | $pomo = dirname( dirname( dirname( __FILE__ ) ) ) . '/src/wp-includes/pomo'; |
||
3 | require_once "$pomo/entry.php"; |
||
4 | require_once "$pomo/translations.php"; |
||
5 | |||
6 | /** |
||
7 | * Responsible for extracting translatable strings from PHP source files |
||
8 | * in the form of Translations instances |
||
9 | */ |
||
10 | class StringExtractor { |
||
11 | |||
12 | var $rules = array( |
||
13 | '__' => array( 'string' ), |
||
14 | '_e' => array( 'string' ), |
||
15 | '_n' => array( 'singular', 'plural' ), |
||
16 | ); |
||
17 | var $comment_prefix = 'translators:'; |
||
18 | |||
19 | function __construct( $rules = array() ) { |
||
20 | $this->rules = $rules; |
||
21 | } |
||
22 | |||
23 | function extract_from_directory( $dir, $excludes = array(), $includes = array(), $prefix = '' ) { |
||
24 | $old_cwd = getcwd(); |
||
25 | chdir( $dir ); |
||
26 | $translations = new Translations; |
||
27 | $file_names = (array) scandir( '.' ); |
||
28 | foreach ( $file_names as $file_name ) { |
||
29 | if ( '.' == $file_name || '..' == $file_name ) continue; |
||
30 | if ( preg_match( '/\.php$/', $file_name ) && $this->does_file_name_match( $prefix . $file_name, $excludes, $includes ) ) { |
||
31 | $extracted = $this->extract_from_file( $file_name, $prefix ); |
||
32 | $translations->merge_originals_with( $extracted ); |
||
33 | } |
||
34 | if ( is_dir( $file_name ) ) { |
||
35 | $extracted = $this->extract_from_directory( $file_name, $excludes, $includes, $prefix . $file_name . '/' ); |
||
36 | $translations->merge_originals_with( $extracted ); |
||
37 | } |
||
38 | } |
||
39 | chdir( $old_cwd ); |
||
40 | return $translations; |
||
41 | } |
||
42 | |||
43 | function extract_from_file( $file_name, $prefix ) { |
||
44 | $code = file_get_contents( $file_name ); |
||
45 | return $this->extract_from_code( $code, $prefix . $file_name ); |
||
46 | } |
||
47 | |||
48 | function does_file_name_match( $path, $excludes, $includes ) { |
||
49 | if ( $includes ) { |
||
50 | $matched_any_include = false; |
||
51 | foreach( $includes as $include ) { |
||
52 | if ( preg_match( '|^'.$include.'$|', $path ) ) { |
||
53 | $matched_any_include = true; |
||
54 | break; |
||
55 | } |
||
56 | } |
||
57 | if ( !$matched_any_include ) return false; |
||
58 | } |
||
59 | if ( $excludes ) { |
||
60 | foreach( $excludes as $exclude ) { |
||
61 | if ( preg_match( '|^'.$exclude.'$|', $path ) ) { |
||
62 | return false; |
||
63 | } |
||
64 | } |
||
65 | } |
||
66 | return true; |
||
67 | } |
||
68 | |||
69 | function entry_from_call( $call, $file_name ) { |
||
70 | $rule = isset( $this->rules[$call['name']] )? $this->rules[$call['name']] : null; |
||
71 | if ( !$rule ) return null; |
||
72 | $entry = new Translation_Entry; |
||
73 | $multiple = array(); |
||
74 | $complete = false; |
||
75 | for( $i = 0; $i < count( $rule ); ++$i ) { |
||
0 ignored issues
–
show
|
|||
76 | if ( $rule[$i] && ( !isset( $call['args'][$i] ) || !is_string( $call['args'][$i] ) || '' == $call['args'][$i] ) ) return false; |
||
77 | switch( $rule[$i] ) { |
||
78 | View Code Duplication | case 'string': |
|
79 | if ( $complete ) { |
||
80 | $multiple[] = $entry; |
||
81 | $entry = new Translation_Entry; |
||
82 | $complete = false; |
||
83 | } |
||
84 | $entry->singular = $call['args'][$i]; |
||
85 | $complete = true; |
||
86 | break; |
||
87 | View Code Duplication | case 'singular': |
|
88 | if ( $complete ) { |
||
89 | $multiple[] = $entry; |
||
90 | $entry = new Translation_Entry; |
||
91 | $complete = false; |
||
92 | } |
||
93 | $entry->singular = $call['args'][$i]; |
||
94 | $entry->is_plural = true; |
||
95 | break; |
||
96 | case 'plural': |
||
97 | $entry->plural = $call['args'][$i]; |
||
98 | $entry->is_plural = true; |
||
99 | $complete = true; |
||
100 | break; |
||
101 | case 'context': |
||
102 | $entry->context = $call['args'][$i]; |
||
103 | foreach( $multiple as &$single_entry ) { |
||
104 | $single_entry->context = $entry->context; |
||
105 | } |
||
106 | break; |
||
107 | } |
||
108 | } |
||
109 | if ( isset( $call['line'] ) && $call['line'] ) { |
||
110 | $references = array( $file_name . ':' . $call['line'] ); |
||
111 | $entry->references = $references; |
||
112 | foreach( $multiple as &$single_entry ) { |
||
113 | $single_entry->references = $references; |
||
114 | } |
||
115 | } |
||
116 | if ( isset( $call['comment'] ) && $call['comment'] ) { |
||
117 | $comments = rtrim( $call['comment'] ) . "\n"; |
||
118 | $entry->extracted_comments = $comments; |
||
119 | foreach( $multiple as &$single_entry ) { |
||
120 | $single_entry->extracted_comments = $comments; |
||
121 | } |
||
122 | } |
||
123 | if ( $multiple && $entry ) { |
||
0 ignored issues
–
show
The expression
$multiple of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
124 | $multiple[] = $entry; |
||
125 | return $multiple; |
||
126 | } |
||
127 | |||
128 | return $entry; |
||
129 | } |
||
130 | |||
131 | function extract_from_code( $code, $file_name ) { |
||
132 | $translations = new Translations; |
||
133 | $function_calls = $this->find_function_calls( array_keys( $this->rules ), $code ); |
||
134 | foreach( $function_calls as $call ) { |
||
135 | $entry = $this->entry_from_call( $call, $file_name ); |
||
136 | if ( is_array( $entry ) ) |
||
137 | foreach( $entry as $single_entry ) |
||
138 | $translations->add_entry_or_merge( $single_entry ); |
||
139 | elseif ( $entry) |
||
140 | $translations->add_entry_or_merge( $entry ); |
||
141 | } |
||
142 | return $translations; |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * Finds all function calls in $code and returns an array with an associative array for each function: |
||
147 | * - name - name of the function |
||
148 | * - args - array for the function arguments. Each string literal is represented by itself, other arguments are represented by null. |
||
149 | * - line - line number |
||
150 | */ |
||
151 | function find_function_calls( $function_names, $code ) { |
||
152 | $tokens = token_get_all( $code ); |
||
153 | $function_calls = array(); |
||
154 | $latest_comment = false; |
||
155 | $in_func = false; |
||
156 | foreach( $tokens as $token ) { |
||
157 | $id = $text = null; |
||
158 | if ( is_array( $token ) ) list( $id, $text, $line ) = $token; |
||
159 | if ( T_WHITESPACE == $id ) continue; |
||
160 | if ( T_STRING == $id && in_array( $text, $function_names ) && !$in_func ) { |
||
161 | $in_func = true; |
||
162 | $paren_level = -1; |
||
163 | $args = array(); |
||
164 | $func_name = $text; |
||
165 | $func_line = $line; |
||
0 ignored issues
–
show
The variable
$line does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
166 | $func_comment = $latest_comment? $latest_comment : ''; |
||
167 | |||
168 | $just_got_into_func = true; |
||
169 | $latest_comment = false; |
||
170 | continue; |
||
171 | } |
||
172 | if ( T_COMMENT == $id ) { |
||
173 | $text = preg_replace( '%^\s+\*\s%m', '', $text ); |
||
174 | $text = str_replace( array( "\r\n", "\n" ), ' ', $text );; |
||
175 | $text = trim( preg_replace( '%^(/\*|//)%', '', preg_replace( '%\*/$%', '', $text ) ) ); |
||
176 | if ( 0 === stripos( $text, $this->comment_prefix ) ) { |
||
177 | $latest_comment = $text; |
||
178 | } |
||
179 | } |
||
180 | if ( !$in_func ) continue; |
||
181 | View Code Duplication | if ( '(' == $token ) { |
|
182 | $paren_level++; |
||
0 ignored issues
–
show
The variable
$paren_level does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
183 | if ( 0 == $paren_level ) { // start of first argument |
||
184 | $just_got_into_func = false; |
||
185 | $current_argument = null; |
||
186 | $current_argument_is_just_literal = true; |
||
187 | } |
||
188 | continue; |
||
189 | } |
||
190 | if ( $just_got_into_func ) { |
||
0 ignored issues
–
show
The variable
$just_got_into_func does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
191 | // there wasn't a opening paren just after the function name -- this means it is not a function |
||
192 | $in_func = false; |
||
193 | $just_got_into_func = false; |
||
194 | } |
||
195 | if ( ')' == $token ) { |
||
196 | if ( 0 == $paren_level ) { |
||
197 | $in_func = false; |
||
198 | $args[] = $current_argument; |
||
0 ignored issues
–
show
The variable
$args does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() The variable
$current_argument does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
199 | $call = array( 'name' => $func_name, 'args' => $args, 'line' => $func_line ); |
||
0 ignored issues
–
show
The variable
$func_name does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() The variable
$func_line does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
200 | if ( $func_comment ) $call['comment'] = $func_comment; |
||
0 ignored issues
–
show
The variable
$func_comment does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
201 | $function_calls[] = $call; |
||
202 | } |
||
203 | $paren_level--; |
||
204 | continue; |
||
205 | } |
||
206 | View Code Duplication | if ( ',' == $token && 0 == $paren_level ) { |
|
207 | $args[] = $current_argument; |
||
208 | $current_argument = null; |
||
209 | $current_argument_is_just_literal = true; |
||
210 | continue; |
||
211 | } |
||
212 | if ( T_CONSTANT_ENCAPSED_STRING == $id && $current_argument_is_just_literal ) { |
||
0 ignored issues
–
show
The variable
$current_argument_is_just_literal does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
213 | // we can use eval safely, because we are sure $text is just a string literal |
||
214 | eval('$current_argument = '.$text.';' ); |
||
0 ignored issues
–
show
It is generally not recommended to use
eval unless absolutely required.
On one hand, ![]() |
|||
215 | continue; |
||
216 | } |
||
217 | $current_argument_is_just_literal = false; |
||
218 | $current_argument = null; |
||
219 | } |
||
220 | return $function_calls; |
||
221 | } |
||
222 | } |
||
223 |
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: