Issues (4967)

Security Analysis    not enabled

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

  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.
  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.
  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.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  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.
  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.
  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.
  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.
  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.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  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.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
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.

src/wp-includes/atomlib.php (18 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Atom Syndication Format PHP Library
4
 *
5
 * @package AtomLib
6
 * @link http://code.google.com/p/phpatomlib/
7
 *
8
 * @author Elias Torres <[email protected]>
9
 * @version 0.4
10
 * @since 2.3.0
11
 */
12
13
/**
14
 * Structure that store common Atom Feed Properties
15
 *
16
 * @package AtomLib
17
 */
18
class AtomFeed {
19
	/**
20
	 * Stores Links
21
	 * @var array
22
	 * @access public
23
	 */
24
    var $links = array();
25
    /**
26
     * Stores Categories
27
     * @var array
28
     * @access public
29
     */
30
    var $categories = array();
31
	/**
32
	 * Stores Entries
33
	 *
34
	 * @var array
35
	 * @access public
36
	 */
37
    var $entries = array();
38
}
39
40
/**
41
 * Structure that store Atom Entry Properties
42
 *
43
 * @package AtomLib
44
 */
45
class AtomEntry {
46
	/**
47
	 * Stores Links
48
	 * @var array
49
	 * @access public
50
	 */
51
    var $links = array();
52
    /**
53
     * Stores Categories
54
     * @var array
55
	 * @access public
56
     */
57
    var $categories = array();
58
}
59
60
/**
61
 * AtomLib Atom Parser API
62
 *
63
 * @package AtomLib
64
 */
65
class AtomParser {
66
67
    var $NS = 'http://www.w3.org/2005/Atom';
68
    var $ATOM_CONTENT_ELEMENTS = array('content','summary','title','subtitle','rights');
69
    var $ATOM_SIMPLE_ELEMENTS = array('id','updated','published','draft');
70
71
    var $debug = false;
72
73
    var $depth = 0;
74
    var $indent = 2;
75
    var $in_content;
76
    var $ns_contexts = array();
77
    var $ns_decls = array();
78
    var $content_ns_decls = array();
79
    var $content_ns_contexts = array();
80
    var $is_xhtml = false;
81
    var $is_html = false;
82
    var $is_text = true;
83
    var $skipped_div = false;
84
85
    var $FILE = "php://input";
86
87
    var $feed;
88
    var $current;
89
90
	/**
91
	 * PHP5 constructor.
92
	 */
93
    function __construct() {
94
95
        $this->feed = new AtomFeed();
96
        $this->current = null;
97
        $this->map_attrs_func = array( __CLASS__, 'map_attrs' );
0 ignored issues
show
The property map_attrs_func 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;
Loading history...
98
        $this->map_xmlns_func = array( __CLASS__, 'map_xmlns' );
0 ignored issues
show
The property map_xmlns_func 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;
Loading history...
99
    }
100
101
	/**
102
	 * PHP4 constructor.
103
	 */
104
	public function AtomParser() {
105
		self::__construct();
106
	}
107
108
	/**
109
	 * Map attributes to key="val"
110
	 *
111
	 * @param string $k Key
112
	 * @param string $v Value
113
	 * @return string
114
	 */
115
	public static function map_attrs($k, $v) {
116
		return "$k=\"$v\"";
117
	}
118
119
	/**
120
	 * Map XML namespace to string.
121
	 *
122
	 * @param indexish $p XML Namespace element index
123
	 * @param array $n Two-element array pair. [ 0 => {namespace}, 1 => {url} ]
124
	 * @return string 'xmlns="{url}"' or 'xmlns:{namespace}="{url}"'
125
	 */
126
	public static function map_xmlns($p, $n) {
127
		$xd = "xmlns";
128
		if( 0 < strlen($n[0]) ) {
129
			$xd .= ":{$n[0]}";
130
		}
131
		return "{$xd}=\"{$n[1]}\"";
132
	}
133
134
    function _p($msg) {
0 ignored issues
show
This method's name is shorter than the configured minimum length of 3 characters.

Even though PHP does not care about the name of your methods, it is generally a good practice to choose method names which can be easily understood by other human readers.

Loading history...
135
        if($this->debug) {
136
            print str_repeat(" ", $this->depth * $this->indent) . $msg ."\n";
137
        }
138
    }
139
140
    function error_handler($log_level, $log_text, $error_file, $error_line) {
0 ignored issues
show
The parameter $error_file is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $error_line is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
141
        $this->error = $log_text;
0 ignored issues
show
The property error 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;
Loading history...
142
    }
143
144
    function parse() {
145
146
        set_error_handler(array(&$this, 'error_handler'));
147
148
        array_unshift($this->ns_contexts, array());
149
150
        if ( ! function_exists( 'xml_parser_create_ns' ) ) {
151
        	trigger_error( __( "PHP's XML extension is not available. Please contact your hosting provider to enable PHP's XML extension." ) );
152
        	return false;
153
        }
154
155
        $parser = xml_parser_create_ns();
156
        xml_set_object($parser, $this);
157
        xml_set_element_handler($parser, "start_element", "end_element");
158
        xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
159
        xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
160
        xml_set_character_data_handler($parser, "cdata");
161
        xml_set_default_handler($parser, "_default");
162
        xml_set_start_namespace_decl_handler($parser, "start_ns");
163
        xml_set_end_namespace_decl_handler($parser, "end_ns");
164
165
        $this->content = '';
0 ignored issues
show
The property content does not seem to exist. Did you mean ATOM_CONTENT_ELEMENTS?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
166
167
        $ret = true;
168
169
        $fp = fopen($this->FILE, "r");
170
        while ($data = fread($fp, 4096)) {
171
            if($this->debug) $this->content .= $data;
0 ignored issues
show
The property content does not seem to exist. Did you mean ATOM_CONTENT_ELEMENTS?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
172
173
            if(!xml_parse($parser, $data, feof($fp))) {
174
                /* translators: 1: error message, 2: line number */
175
                trigger_error(sprintf(__('XML Error: %1$s at line %2$s')."\n",
176
                    xml_error_string(xml_get_error_code($parser)),
177
                    xml_get_current_line_number($parser)));
178
                $ret = false;
179
                break;
180
            }
181
        }
182
        fclose($fp);
183
184
        xml_parser_free($parser);
185
186
        restore_error_handler();
187
188
        return $ret;
189
    }
190
191
    function start_element($parser, $name, $attrs) {
0 ignored issues
show
The parameter $parser is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
192
193
        $tag = array_pop(explode(":", $name));
0 ignored issues
show
explode(':', $name) cannot be passed to array_pop() as the parameter $array expects a reference.
Loading history...
194
195
        switch($name) {
196
            case $this->NS . ':feed':
197
                $this->current = $this->feed;
198
                break;
199
            case $this->NS . ':entry':
200
                $this->current = new AtomEntry();
201
                break;
202
        };
203
204
        $this->_p("start_element('$name')");
205
        #$this->_p(print_r($this->ns_contexts,true));
206
        #$this->_p('current(' . $this->current . ')');
207
208
        array_unshift($this->ns_contexts, $this->ns_decls);
209
210
        $this->depth++;
211
212
        if(!empty($this->in_content)) {
213
214
            $this->content_ns_decls = array();
215
216
            if($this->is_html || $this->is_text)
217
                trigger_error("Invalid content in element found. Content must not be of type text or html if it contains markup.");
218
219
            $attrs_prefix = array();
220
221
            // resolve prefixes for attributes
222
            foreach($attrs as $key => $value) {
223
                $with_prefix = $this->ns_to_prefix($key, true);
224
                $attrs_prefix[$with_prefix[1]] = $this->xml_escape($value);
225
            }
226
227
            $attrs_str = join(' ', array_map($this->map_attrs_func, array_keys($attrs_prefix), array_values($attrs_prefix)));
228
            if(strlen($attrs_str) > 0) {
229
                $attrs_str = " " . $attrs_str;
230
            }
231
232
            $with_prefix = $this->ns_to_prefix($name);
233
234
            if(!$this->is_declared_content_ns($with_prefix[0])) {
235
                array_push($this->content_ns_decls, $with_prefix[0]);
236
            }
237
238
            $xmlns_str = '';
239
            if(count($this->content_ns_decls) > 0) {
240
                array_unshift($this->content_ns_contexts, $this->content_ns_decls);
241
                $xmlns_str .= join(' ', array_map($this->map_xmlns_func, array_keys($this->content_ns_contexts[0]), array_values($this->content_ns_contexts[0])));
242
                if(strlen($xmlns_str) > 0) {
243
                    $xmlns_str = " " . $xmlns_str;
244
                }
245
            }
246
247
            array_push($this->in_content, array($tag, $this->depth, "<". $with_prefix[1] ."{$xmlns_str}{$attrs_str}" . ">"));
248
249
        } else if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS) || in_array($tag, $this->ATOM_SIMPLE_ELEMENTS)) {
250
            $this->in_content = array();
251
            $this->is_xhtml = $attrs['type'] == 'xhtml';
252
            $this->is_html = $attrs['type'] == 'html' || $attrs['type'] == 'text/html';
253
            $this->is_text = !in_array('type',array_keys($attrs)) || $attrs['type'] == 'text';
254
            $type = $this->is_xhtml ? 'XHTML' : ($this->is_html ? 'HTML' : ($this->is_text ? 'TEXT' : $attrs['type']));
255
256
            if(in_array('src',array_keys($attrs))) {
257
                $this->current->$tag = $attrs;
258
            } else {
259
                array_push($this->in_content, array($tag,$this->depth, $type));
260
            }
261
        } else if($tag == 'link') {
262
            array_push($this->current->links, $attrs);
263
        } else if($tag == 'category') {
264
            array_push($this->current->categories, $attrs);
265
        }
266
267
        $this->ns_decls = array();
268
    }
269
270
    function end_element($parser, $name) {
0 ignored issues
show
The parameter $parser is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
271
272
        $tag = array_pop(explode(":", $name));
0 ignored issues
show
explode(':', $name) cannot be passed to array_pop() as the parameter $array expects a reference.
Loading history...
273
274
        $ccount = count($this->in_content);
275
276
        # if we are *in* content, then let's proceed to serialize it
277
        if(!empty($this->in_content)) {
278
            # if we are ending the original content element
279
            # then let's finalize the content
280
            if($this->in_content[0][0] == $tag &&
281
                $this->in_content[0][1] == $this->depth) {
282
                $origtype = $this->in_content[0][2];
283
                array_shift($this->in_content);
284
                $newcontent = array();
285
                foreach($this->in_content as $c) {
286
                    if(count($c) == 3) {
287
                        array_push($newcontent, $c[2]);
288
                    } else {
289
                        if($this->is_xhtml || $this->is_text) {
290
                            array_push($newcontent, $this->xml_escape($c));
291
                        } else {
292
                            array_push($newcontent, $c);
293
                        }
294
                    }
295
                }
296
                if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS)) {
297
                    $this->current->$tag = array($origtype, join('',$newcontent));
298
                } else {
299
                    $this->current->$tag = join('',$newcontent);
300
                }
301
                $this->in_content = array();
302
            } else if($this->in_content[$ccount-1][0] == $tag &&
303
                $this->in_content[$ccount-1][1] == $this->depth) {
304
                $this->in_content[$ccount-1][2] = substr($this->in_content[$ccount-1][2],0,-1) . "/>";
305
            } else {
306
                # else, just finalize the current element's content
307
                $endtag = $this->ns_to_prefix($name);
308
                array_push($this->in_content, array($tag, $this->depth, "</$endtag[1]>"));
309
            }
310
        }
311
312
        array_shift($this->ns_contexts);
313
314
        $this->depth--;
315
316
        if($name == ($this->NS . ':entry')) {
317
            array_push($this->feed->entries, $this->current);
318
            $this->current = null;
319
        }
320
321
        $this->_p("end_element('$name')");
322
    }
323
324
    function start_ns($parser, $prefix, $uri) {
0 ignored issues
show
The parameter $parser is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
325
        $this->_p("starting: " . $prefix . ":" . $uri);
326
        array_push($this->ns_decls, array($prefix,$uri));
327
    }
328
329
    function end_ns($parser, $prefix) {
0 ignored issues
show
The parameter $parser is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
330
        $this->_p("ending: #" . $prefix . "#");
331
    }
332
333
    function cdata($parser, $data) {
0 ignored issues
show
The parameter $parser is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
334
        $this->_p("data: #" . str_replace(array("\n"), array("\\n"), trim($data)) . "#");
335
        if(!empty($this->in_content)) {
336
            array_push($this->in_content, $data);
337
        }
338
    }
339
340
    function _default($parser, $data) {
0 ignored issues
show
The parameter $parser is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
341
        # when does this gets called?
342
    }
343
344
345
    function ns_to_prefix($qname, $attr=false) {
346
        # split 'http://www.w3.org/1999/xhtml:div' into ('http','//www.w3.org/1999/xhtml','div')
347
        $components = explode(":", $qname);
348
349
        # grab the last one (e.g 'div')
350
        $name = array_pop($components);
351
352
        if(!empty($components)) {
353
            # re-join back the namespace component
354
            $ns = join(":",$components);
355
            foreach($this->ns_contexts as $context) {
356
                foreach($context as $mapping) {
357
                    if($mapping[1] == $ns && strlen($mapping[0]) > 0) {
358
                        return array($mapping, "$mapping[0]:$name");
359
                    }
360
                }
361
            }
362
        }
363
364
        if($attr) {
365
            return array(null, $name);
366
        } else {
367
            foreach($this->ns_contexts as $context) {
368
                foreach($context as $mapping) {
369
                    if(strlen($mapping[0]) == 0) {
370
                        return array($mapping, $name);
371
                    }
372
                }
373
            }
374
        }
375
    }
376
377
    function is_declared_content_ns($new_mapping) {
378
        foreach($this->content_ns_contexts as $context) {
379
            foreach($context as $mapping) {
380
                if($new_mapping == $mapping) {
381
                    return true;
382
                }
383
            }
384
        }
385
        return false;
386
    }
387
388
    function xml_escape($string)
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
389
    {
390
             return str_replace(array('&','"',"'",'<','>'),
391
                array('&amp;','&quot;','&apos;','&lt;','&gt;'),
392
                $string );
393
    }
394
}
395