Issues (23)

Security Analysis    no request data  

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/Http/MessageBody.php (3 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
 * Veto.
4
 * PHP Microframework.
5
 *
6
 * @author Damien Walsh <[email protected]>
7
 * @copyright Damien Walsh 2013-2014
8
 * @version 0.1
9
 * @package veto
10
 */
11
namespace Veto\Http;
12
13
use Psr\Http\Message\StreamInterface;
14
15
/**
16
 * A HTTP Message Body, according to PSR-7.
17
 *
18
 * @since 0.1
19
 */
20
class MessageBody implements StreamInterface
21
{
22
    /**
23
     * Modes in which a stream is readable
24
     *
25
     * @var array
26
     * @link http://php.net/manual/function.fopen.php
27
     */
28
    protected static $readableModes = array('r', 'r+', 'w+', 'a+', 'x+', 'c+');
29
30
    /**
31
     * Modes in which a stream is writable
32
     *
33
     * @var array
34
     * @link http://php.net/manual/function.fopen.php
35
     */
36
    protected static $writableModes = array('r+', 'w', 'w+', 'a', 'a+', 'x', 'x+', 'c', 'c+');
37
38
    /**
39
     * The stream underlying the message body
40
     *
41
     * @var resource
42
     */
43
    protected $stream;
44
45
    /**
46
     * The underlying stream's metadata
47
     *
48
     * @var null|array
49
     */
50
    protected $metadata;
51
52
    /**
53
     * Is the underlying stream readable?
54
     *
55
     * @var bool
56
     */
57
    protected $readable;
58
59
    /**
60
     * Is the underlying stream writable?
61
     *
62
     * @var bool
63
     */
64
    protected $writable;
65
66
    /**
67
     * Is the underlying stream seekable?
68
     *
69
     * @var bool
70
     */
71
    protected $seekable;
72
73
    /**
74
     * Create a new message body with the provided stream underlying it.
75
     *
76
     * @param resource $stream
77
     */
78
    public function __construct($stream)
79
    {
80
        if (!is_resource($stream)) {
81
            throw new \InvalidArgumentException(
82
                '\Veto\Http\Body::__construct() argument must be a PHP stream resource'
83
            );
84
        }
85
86
        $this->attach($stream);
87
    }
88
89
    /**
90
     * Attach a resource to this message body.
91
     *
92
     * @param resource $stream
93
     */
94
    public function attach($stream)
95
    {
96
        if (false === is_resource($stream)) {
97
            throw new \InvalidArgumentException(
98
                '\Veto\Http\Body::attach() argument must be a PHP stream resource'
99
            );
100
        }
101
102
        // If we are already attached, detach first
103
        if (true === $this->isAttached()) {
104
            $this->detach();
105
        }
106
107
        $this->stream = $stream;
108
        $this->setMetadata($stream);
109
    }
110
111
    /**
112
     * Separates any underlying resources from the stream.
113
     *
114
     * After the stream has been detached, the stream is in an unusable state.
115
     *
116
     * @return resource|null Underlying PHP stream, if any
117
     */
118
    public function detach()
119
    {
120
        $stream = $this->stream;
121
        $this->stream = null;
122
123
        return $stream;
124
    }
125
126
    /**
127
     * Check if a stream resource is already attached to this message body.
128
     *
129
     * @return bool
130
     */
131
    public function isAttached()
132
    {
133
        return is_resource($this->stream);
134
    }
135
136
    /**
137
     * Set the metadata state information on this object, sourced from the stream metadata.
138
     *
139
     * @param resource $stream
140
     */
141
    protected function setMetadata($stream)
142
    {
143
        $this->metadata = stream_get_meta_data($stream);
144
145
        // Check for readable modes
146
        $this->readable = false;
147
        foreach (self::$readableModes as $mode) {
148
            if (strpos($this->metadata['mode'], $mode) === 0) {
149
                $this->readable = true;
150
                break;
151
            }
152
        }
153
154
        // Check for writable modes
155
        $this->writable = false;
156
        foreach (self::$writableModes as $mode) {
157
            if (strpos($this->metadata['mode'], $mode) === 0) {
158
                $this->writable = true;
159
                break;
160
            }
161
        }
162
163
        // Is the underlying stream seekable?
164
        $this->seekable = $this->metadata['seekable'];
165
    }
166
167
    /**
168
     * Get the size of the stream if known
169
     *
170
     * @return int|null Returns the size in bytes if known, or null if unknown.
171
     */
172
    public function getSize()
173
    {
174
        if (true === $this->isAttached()) {
175
            $stats = fstat($this->stream);
176
            return isset($stats['size']) ? $stats['size'] : null;
177
        }
178
179
        return null;
180
    }
181
182
    /**
183
     * Returns the current position of the file read/write pointer
184
     *
185
     * @return int|bool Position of the file pointer or false on error.
186
     */
187
    public function tell()
188
    {
189
        return $this->isAttached() ? ftell($this->stream) : false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->isAttached() ? ft...$this->stream) : false; of type integer|false adds false to the return on line 189 which is incompatible with the return type declared by the interface Psr\Http\Message\StreamInterface::tell of type integer. It seems like you forgot to handle an error condition.
Loading history...
190
    }
191
192
    /**
193
     * Returns true if the stream is at the end of the stream.
194
     *
195
     * @return bool
196
     */
197
    public function eof()
198
    {
199
        return $this->isAttached() ? feof($this->stream) : true;
200
    }
201
202
    /**
203
     * Returns whether or not the stream is seekable.
204
     *
205
     * @return bool
206
     */
207
    public function isSeekable()
208
    {
209
        return $this->isAttached() && $this->seekable;
210
    }
211
212
    /**
213
     * Seek to a position in the stream.
214
     *
215
     * @link http://www.php.net/manual/en/function.fseek.php
216
     * @param int $offset Stream offset
217
     * @param int $whence Specifies how the cursor position will be calculated
218
     *     based on the seek offset. Valid values are identical to the built-in
219
     *     PHP $whence values for `fseek()`.  SEEK_SET: Set position equal to
220
     *     offset bytes SEEK_CUR: Set position to current location plus offset
221
     *     SEEK_END: Set position to end-of-stream plus offset.
222
     * @return bool Returns TRUE on success or FALSE on failure.
223
     */
224
    public function seek($offset, $whence = SEEK_SET)
225
    {
226
        return $this->isAttached() && $this->isSeekable() ?
227
            fseek($this->stream, $offset, $whence) :
228
            false;
229
    }
230
231
    /**
232
     * Seek to the beginning of the stream.
233
     *
234
     * If the stream is not seekable, this method will return FALSE, indicating
235
     * failure; otherwise, it will perform a seek(0), and return the status of
236
     * that operation.
237
     *
238
     * @see seek()
239
     * @link http://www.php.net/manual/en/function.fseek.php
240
     * @return bool Returns TRUE on success or FALSE on failure.
241
     */
242
    public function rewind()
243
    {
244
        return $this->isAttached() && $this->isSeekable() ? rewind($this->stream) : false;
245
    }
246
247
    /**
248
     * Returns whether or not the stream is writable.
249
     *
250
     * @return bool
251
     */
252
    public function isWritable()
253
    {
254
        return is_null($this->writable) ? false : $this->writable;
255
    }
256
257
    /**
258
     * Write data to the stream.
259
     *
260
     * @param string $string The string that is to be written.
261
     * @return int|bool Returns the number of bytes written to the stream on
262
     *     success or FALSE on failure.
263
     */
264
    public function write($string)
265
    {
266
        return $this->isAttached() && $this->isWritable() ? fwrite($this->stream, $string) : false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->isAttached() && $...ream, $string) : false; of type integer|false adds false to the return on line 266 which is incompatible with the return type declared by the interface Psr\Http\Message\StreamInterface::write of type integer. It seems like you forgot to handle an error condition.
Loading history...
267
    }
268
269
    /**
270
     * Returns whether or not the stream is readable.
271
     *
272
     * @return bool
273
     */
274
    public function isReadable()
275
    {
276
        return is_null($this->readable) ? false : $this->readable;
277
    }
278
279
    /**
280
     * Read data from the stream.
281
     *
282
     * @param int $length Read up to $length bytes from the object and return
283
     *     them. Fewer than $length bytes may be returned if underlying stream
284
     *     call returns fewer bytes.
285
     * @return string|false Returns the data read from the stream, false if
286
     *     unable to read or if an error occurs.
287
     */
288
    public function read($length)
289
    {
290
        return $this->isAttached() && $this->isReadable() ? fread($this->stream, $length) : false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->isAttached() && $...ream, $length) : false; of type string|false adds false to the return on line 290 which is incompatible with the return type declared by the interface Psr\Http\Message\StreamInterface::read of type string. It seems like you forgot to handle an error condition.
Loading history...
291
    }
292
293
    /**
294
     * Returns the remaining contents in a string
295
     *
296
     * @return string
297
     */
298
    public function getContents()
299
    {
300
        return $this->isAttached() && $this->isReadable() ? stream_get_contents($this->stream) : '';
301
    }
302
303
    /**
304
     * Get stream metadata as an associative array or retrieve a specific key.
305
     *
306
     * The keys returned are identical to the keys returned from PHP's
307
     * stream_get_meta_data() function.
308
     *
309
     * @link http://php.net/manual/en/function.stream-get-meta-data.php
310
     * @param string $key Specific metadata to retrieve.
311
     * @return array|mixed|null Returns an associative array if no key is
312
     *     provided. Returns a specific key value if a key is provided and the
313
     *     value is found, or null if the key is not found.
314
     */
315
    public function getMetadata($key = null)
316
    {
317
        if (true === is_null($key)) {
318
            return $this->metadata;
319
        }
320
321
        return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
322
    }
323
324
    /**
325
     * Closes the stream and any underlying resources.
326
     *
327
     * @return void
328
     */
329
    public function close()
330
    {
331
        fclose($this->stream);
332
    }
333
334
    /**
335
     * Read the entire contents of the message body into a PHP string.
336
     *
337
     * @return string
338
     */
339
    public function __toString()
340
    {
341
        return $this->isAttached() ? stream_get_contents($this->stream, -1, 0) : '';
342
    }
343
}
344