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 | * This file is part of Peachy MediaWiki Bot API |
||
5 | * |
||
6 | * Peachy is free software: you can redistribute it and/or modify |
||
7 | * it under the terms of the GNU General Public License as published by |
||
8 | * the Free Software Foundation, either version 3 of the License, or |
||
9 | * (at your option) any later version. |
||
10 | * |
||
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. See the |
||
14 | * GNU General Public License for more details. |
||
15 | * |
||
16 | * You should have received a copy of the GNU General Public License |
||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
18 | */ |
||
19 | |||
20 | class IRC { |
||
21 | |||
22 | /** |
||
23 | * IRC Socket connection |
||
24 | * |
||
25 | * @var object |
||
26 | * @access public |
||
27 | */ |
||
28 | public $f; |
||
29 | |||
30 | /** |
||
31 | * Channel(s) |
||
32 | * |
||
33 | * @var string|array |
||
34 | * @access private |
||
35 | */ |
||
36 | private $chan; |
||
37 | |||
38 | /** |
||
39 | * Construct function, front-end for fsockopen. |
||
40 | * @param string $User Username to send to IRC |
||
41 | * @param string $Nick Nick to use |
||
42 | * @param string $Pass Password to send |
||
43 | * @param string $Server Server to connect to |
||
44 | * @param string $pgPort Port to use |
||
45 | * @param string $Gecos AKA Real Name, Information field, etc. |
||
46 | * @param string|array Channel (s) to connect to |
||
47 | */ |
||
48 | function __construct( $User, $Nick, $Pass, $Server, $pgPort, $Gecos, $Channel ) { |
||
49 | $this->f = fsockopen( $Server, $pgPort, $errno, $errstr, 30 ); |
||
0 ignored issues
–
show
|
|||
50 | |||
51 | if( !$this->f ) { |
||
52 | die( $errstr . ' (' . $errno . ")\n" ); |
||
0 ignored issues
–
show
The method
__construct() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
53 | } |
||
54 | |||
55 | pecho( "Logging into IRC as $User into $Server:$pgPort\n\n", PECHO_NOTICE ); |
||
56 | |||
57 | $this->sendToIrc( 'USER ' . $User . ' "' . $Server . '" "localhost" :' . $Gecos . "\n" ); |
||
58 | $this->sendToIrc( 'PASS ' . $Pass . "\n" ); |
||
59 | $this->sendToIrc( 'NICK ' . $Nick . "\n" ); |
||
60 | |||
61 | if( !is_array( $Channel ) ) { |
||
62 | $this->chan = array( $Channel ); |
||
63 | } else { |
||
64 | $this->chan = $Channel; |
||
65 | } |
||
66 | $this->joinChan( $Channel ); |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Destruct function, quits from IRC |
||
71 | * @return void |
||
72 | */ |
||
73 | public function quit() { |
||
74 | fwrite( $this->f, 'QUIT ' . "\n" ); |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Sends a raw message to IRC |
||
79 | * @param string $msg Message to send |
||
80 | * @return void |
||
81 | */ |
||
82 | public function sendToIrc( $msg ) { |
||
83 | fwrite( $this->f, $msg ); |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * Send a message to a channel, formatted in PRIVMSG format |
||
88 | * @param string $msg Message to send |
||
89 | * @param string $chan Channel to send to |
||
90 | * @return void |
||
91 | */ |
||
92 | public function sendPrivmsg( $msg, $chan ) { |
||
93 | pecho( "Sending $msg to $chan...\n\n", PECHO_VERBOSE ); |
||
94 | fwrite( $this->f, "PRIVMSG " . $chan . " :$msg\n" ); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * Return the pingpong game |
||
99 | * @param string $payload Data from the PING message |
||
100 | * @return void |
||
101 | */ |
||
102 | public function sendPong( $payload ) { |
||
103 | fwrite( $this->f, "PONG " . $payload . "\r\n" ); |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * Joins a channel, or the locally stored channel(s) |
||
108 | * @param string $chan Channel to join. Default null. |
||
109 | * @return void |
||
110 | */ |
||
111 | public function joinChan( $chan = null ) { |
||
112 | if( !is_null( $chan ) && !is_array( $chan ) ) { |
||
113 | pecho( "Joining $chan...\n", PECHO_VERBOSE ); |
||
114 | fwrite( $this->f, 'JOIN ' . $chan . "\n" ); |
||
115 | usleep( 5000 ); |
||
116 | } elseif( !is_null( $chan ) ) { |
||
117 | foreach( $chan as $channel ){ |
||
118 | pecho( "Joining $channel...\n", PECHO_VERBOSE ); |
||
119 | fwrite( $this->f, 'JOIN ' . $channel . "\n" ); |
||
120 | usleep( 5000 ); |
||
121 | } |
||
122 | } |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Leaves a channel, or the locally stored channel(s) |
||
127 | * @param string $chan Channel to part. Default null |
||
128 | * @return void |
||
129 | */ |
||
130 | public function partChan( $chan = null ) { |
||
131 | if( !is_null( $chan ) ) { |
||
132 | pecho( "Parting $chan...\n", PECHO_VERBOSE ); |
||
133 | fwrite( $this->f, 'PART ' . $chan . "\n" ); |
||
134 | usleep( 5000 ); |
||
135 | } else { |
||
136 | foreach( $this->chan as $chan ){ |
||
137 | pecho( "Parting $chan...\n", PECHO_VERBOSE ); |
||
138 | fwrite( $this->f, 'PART ' . $chan . "\n" ); |
||
139 | usleep( 5000 ); |
||
140 | } |
||
141 | } |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * Splits apart the various parts of an IRC line into usable sections, e.g. !commands, cloaks, etc. |
||
146 | * @param string $line Line that IRC sent |
||
147 | * @param array $trigger Trigger character for !commands (e.g. !, ., @, etc) |
||
148 | * @param bool $feed Whether or not the IRC server is a MediaWiki RC channel |
||
149 | * @return array Parsed line |
||
150 | * @static |
||
151 | */ |
||
152 | public static function parseLine( $line, $trigger, $feed = false ) { |
||
153 | $return = array(); |
||
154 | $return['trueraw'] = $line; |
||
155 | $return['truerawmsg'] = explode( " ", $line ); |
||
156 | unset( $return['truerawmsg'][0], $return['truerawmsg'][1], $return['truerawmsg'][2] ); |
||
157 | $return['truerawmsg'] = substr( implode( ' ', $return['truerawmsg'] ), 1 ); |
||
158 | |||
159 | if( $feed ) { |
||
160 | $line = str_replace( array( "\n", "\r", "\002" ), '', $line ); |
||
161 | $line = preg_replace( '/\003(\d\d?(,\d\d?)?)?/', '', $line ); |
||
162 | } else { |
||
163 | $line = str_replace( array( "\n", "\r" ), '', $line ); |
||
164 | $line = preg_replace( '/' . chr( 3 ) . '.{2,}/i', '', $line ); |
||
165 | } |
||
166 | |||
167 | $return['raw'] = $line; |
||
168 | |||
169 | /* |
||
170 | Data for a privmsg: |
||
171 | $d[0] = Nick!User@Host format. |
||
172 | $d[1] = Action, e.g. "PRIVMSG", "MODE", etc. If it's a message from the server, it's the numerial code |
||
173 | $d[2] = The channel somethign was spoken in |
||
174 | $d[3] = The text that was spoken |
||
175 | */ |
||
176 | $d = $return['message'] = explode( ' ', $line ); |
||
177 | $return['n!u@h'] = $d[0]; |
||
178 | |||
179 | unset( $return['message'][0], $return['message'][1], $return['message'][2] ); |
||
180 | $return['message'] = substr( implode( ' ', $return['message'] ), 1 ); |
||
181 | |||
182 | $return['nick'] = substr( $d[0], 1 ); |
||
183 | $return['nick'] = explode( '!', $return['nick'] ); |
||
184 | $return['nick'] = $return['nick'][0]; |
||
185 | |||
186 | $return['cloak'] = explode( '@', $d[0] ); |
||
187 | $return['cloak'] = @$return['cloak'][1]; |
||
188 | |||
189 | $return['user'] = explode( '!', $d[0] ); |
||
190 | $return['user'] = explode( '@', $return['user'][1] ); |
||
191 | $return['user'] = $return['user'][0]; |
||
192 | |||
193 | $return['chan'] = strtolower( $d[2] ); |
||
194 | |||
195 | $return['type'] = $return['payload'] = $d[1]; |
||
196 | |||
197 | if( in_array( substr( $return['message'], 0, 1 ), $trigger ) ) { |
||
198 | $return['command'] = explode( ' ', substr( strtolower( $return['message'] ), 1 ) ); |
||
199 | $return['command'] = $return['command'][0]; |
||
200 | |||
201 | //Get the parameters |
||
202 | $return['param'] = explode( ' ', $return['message'] ); |
||
203 | unset( $return['param'][0] ); |
||
204 | $return['param'] = implode( ' ', $return['param'] ); |
||
205 | $return['param'] = trim( $return['param'] ); |
||
206 | } |
||
207 | |||
208 | /* |
||
209 | End result: |
||
210 | $return['raw'] = Raw data |
||
211 | $return['message'] = The text that appears in the channel |
||
212 | $return['n!u@h'] = The person who said the line, in N!U@H format |
||
213 | $return['nick'] = The nick who said the line |
||
214 | $return['cloak'] = The cloak of the person who said the line |
||
215 | $return['user'] = The username who said the line |
||
216 | $return['chan'] = The channel the line was said in |
||
217 | $return['type'] = The action that was done (eg PRIVMSG, MODE) |
||
218 | $return['payload'] = For pings, this is $d[1] |
||
219 | $return['command'] = The command that was said, eg !status (excuding !) |
||
220 | $return['param'] = Parameters of the command |
||
221 | */ |
||
222 | return $return; |
||
223 | } |
||
224 | |||
225 | /** |
||
226 | * Parses the title, user, etc from a MediaWiki RC feed |
||
227 | * @link http://www.mediawiki.org/wiki/Manual:IRC_RC_Bot |
||
228 | * @param string $msg Message from feed |
||
229 | * @return array Parsed line |
||
230 | * @static |
||
231 | */ |
||
232 | public static function parseRC( $msg ) { |
||
233 | if( preg_match( '/^\[\[((Talk|User|Wikipedia|Image|MediaWiki|Template|Help|Category|Portal|Special)(( |_)talk)?:)?([^\x5d]*)\]\] (\S*) (http:\/\/en\.wikipedia\.org\/w\/index\.php\?(oldid|diff)=(\d*)&(rcid|oldid)=(\d*).*|http:\/\/en\.wikipedia\.org\/wiki\/\S+)? \* ([^*]*) \* (\(([^)]*)\))? (.*)$/S', $msg, $m ) ) { |
||
234 | |||
235 | $return = array(); |
||
236 | |||
237 | //print_r($m); |
||
238 | |||
239 | $return['namespace'] = $m[2]; |
||
240 | $return['pagename'] = $m[5]; |
||
241 | $return['fullpagename'] = $m[1] . $m[5]; |
||
242 | $return['basepagename'] = explode( '/', $return['fullpagename'] ); |
||
243 | $return['basepagename'] = $return['basepagename'][0]; |
||
244 | $return['subpagename'] = str_replace( $return['basepagename'] . '/', '', $return['fullpagename'] ); |
||
245 | $return['flags'] = str_split( $m[6] ); |
||
246 | $return['action'] = $m[6]; |
||
247 | $return['url'] = $m[7]; |
||
248 | $return['revid'] = $m[9]; |
||
249 | $return['oldid'] = $m[11]; |
||
250 | $return['username'] = $m[12]; |
||
251 | $return['len'] = $m[14]; |
||
252 | $return['comment'] = $m[15]; |
||
253 | $return['timestamp'] = time(); |
||
254 | $return['is_new'] = false; |
||
255 | $return['is_minor'] = false; |
||
256 | $return['is_bot'] = false; |
||
257 | $return['is_delete'] = false; |
||
258 | $return['actionpage'] = null; |
||
259 | |||
260 | if( in_array( 'N', $return['flags'] ) ) { |
||
261 | $return['is_new'] = true; |
||
262 | } |
||
263 | |||
264 | if( in_array( 'M', $return['flags'] ) ) { |
||
265 | $return['is_minor'] = true; |
||
266 | } |
||
267 | |||
268 | if( in_array( 'B', $return['flags'] ) ) { |
||
269 | $return['is_bot'] = true; |
||
270 | } |
||
271 | |||
272 | if( $return['action'] == 'delete' ) { |
||
273 | $return['is_delete'] = true; |
||
274 | $tmp = explode( '[[', $return['comment'] ); |
||
275 | $tmp = explode( ']]', $tmp[1] ); |
||
276 | $return['actionpage'] = $tmp[0]; |
||
277 | $return['actionpageprefix'] = explode( '/', $return['actionpage'] ); |
||
278 | $return['actionpageprefix'] = $return['actionpageprefix'][0]; |
||
279 | } |
||
280 | |||
281 | return $return; |
||
282 | } |
||
283 | } |
||
284 | |||
285 | /** |
||
286 | * @param $errno |
||
287 | * @return bool|string |
||
288 | */ |
||
289 | public static function get_error($errno) |
||
290 | { |
||
291 | if ($errno != null) { |
||
292 | switch ($errno) { |
||
293 | case 401: |
||
294 | return "Nickname/Channel is currently unused"; |
||
295 | case 402: |
||
296 | return "Server not found"; |
||
297 | case 403: |
||
298 | return "Channel not found"; |
||
299 | case 404: |
||
300 | return "Cannot send to channel"; |
||
301 | case 405: |
||
302 | return "Too many channels joined"; |
||
303 | case 406: |
||
304 | return "There was no such nickname"; |
||
305 | } |
||
306 | } else { |
||
307 | return false; |
||
308 | } |
||
309 | } |
||
310 | } |
||
311 | |||
312 | class SimpleIRC { |
||
313 | |||
314 | private $server; |
||
315 | private $pgPort; |
||
316 | private $user; |
||
317 | private $pass; |
||
318 | private $nick; |
||
319 | private $channel; |
||
320 | private $callback; |
||
321 | |||
322 | function __construct( $server, $pgPort = 6667, $user, $pass, $nick, $channel, $callback = null ) { |
||
323 | global $pgIRCTrigger, $pgHooks; |
||
324 | |||
325 | if( func_num_args() > 6 ) { |
||
326 | $this->server = $server; |
||
327 | $this->port = $pgPort; |
||
0 ignored issues
–
show
The property
port does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
328 | $this->user = $user; |
||
329 | $this->pass = $pass; |
||
330 | $this->nick = $nick; |
||
331 | $this->channel = $channel; |
||
332 | $this->callback = $callback; |
||
333 | } else { |
||
334 | $this->server = $server; |
||
335 | $this->port = 6667; |
||
336 | $this->user = $pgPort; |
||
337 | $this->pass = $user; |
||
338 | $this->nick = $pass; |
||
339 | $this->channel = $nick; |
||
340 | $this->callback = $channel; |
||
341 | } |
||
342 | |||
343 | $pgHooks['SimpleIRCPrivMSG'][] = $callback; |
||
344 | |||
345 | $irc = new IRC( $this->user, $this->nick, $this->pass, $this->server, $this->port, "Peachy IRC Bot Version " . PEACHYVERSION, $this->channel ); |
||
346 | |||
347 | while( !feof( $irc->f ) ){ |
||
348 | |||
349 | $parsed = IRC::parseLine( fgets( $irc->f, 1024 ), $pgIRCTrigger, true ); |
||
350 | |||
351 | if( @$parsed['n!u@h'] == 'PING' ) { |
||
352 | $irc->sendPong( $parsed['payload'] ); |
||
353 | } |
||
354 | |||
355 | if( @$parsed['type'] == '376' || @$parser['type'] == '422' ) { |
||
0 ignored issues
–
show
|
|||
356 | $feed->joinChan(); |
||
0 ignored issues
–
show
|
|||
357 | sleep( 5 ); |
||
358 | } |
||
359 | |||
360 | if( @$parsed['type'] == 'PRIVMSG' ) { |
||
361 | Hooks::runHook( 'SimpleIRCPrivMSG', array( &$parsed, &$irc, &$this ) ); |
||
362 | } |
||
363 | } |
||
364 | } |
||
365 | |||
366 | } |
||
367 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..