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 | * 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
|
|||
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;
![]() |
|||
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
|
|||
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
|
|||
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;
![]() |
|||
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. ![]() |
|||
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. ![]() |
|||
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
|
|||
192 | |||
193 | $tag = array_pop(explode(":", $name)); |
||
0 ignored issues
–
show
|
|||
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
|
|||
271 | |||
272 | $tag = array_pop(explode(":", $name)); |
||
0 ignored issues
–
show
|
|||
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
|
|||
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
|
|||
330 | $this->_p("ending: #" . $prefix . "#"); |
||
331 | } |
||
332 | |||
333 | function cdata($parser, $data) { |
||
0 ignored issues
–
show
|
|||
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
|
|||
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 ![]() |
|||
389 | { |
||
390 | return str_replace(array('&','"',"'",'<','>'), |
||
391 | array('&','"',''','<','>'), |
||
392 | $string ); |
||
393 | } |
||
394 | } |
||
395 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: