GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (1)

Security Analysis    no request data  

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

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

Labels
Severity
1
<?php declare(strict_types=1);
2
3
namespace ReactInspector\EventLoop;
4
5
use React\EventLoop\TimerInterface;
6
use ReactInspector\CollectorInterface;
7
use ReactInspector\Config;
8
use ReactInspector\Measurement;
9
use ReactInspector\Measurements;
10
use ReactInspector\Metric;
11
use ReactInspector\Tag;
12
use ReactInspector\Tags;
13
use Rx\Observable;
14
use function ApiClients\Tools\Rx\observableFromArray;
15
use function array_key_exists;
16
use function count;
17
use function spl_object_hash;
18
use const WyriHaximus\Constants\Boolean\TRUE_;
0 ignored issues
show
The constant WyriHaximus\Constants\Boolean\TRUE_ was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
19
20
final class LoopCollector implements CollectorInterface
21
{
22
    /** @var array<int, resource> */
23
    private array $streamsRead = [];
24
25
    /** @var array<int, resource> */
26
    private array $streamsWrite = [];
27
28
    /** @var array<int, resource> */
29
    private array $streamsDuplex = [];
30
31
    /** @var array<string, bool> */
32
    private array $timers = [];
33
34
    /** @var array<string, int> */
35
    private array $metrics = [
36
        'signals.ticks' => 0,
37
        'streams.read.ticks' => 0,
38
        'streams.duplex.ticks' => 0,
39
        'streams.write.ticks' => 0,
40
        'timers.periodic.ticks' => 0,
41
        'timers.once.ticks' => 0,
42
        'ticks.future.ticks' => 0,
43
        'ticks.future.total' => 0,
44
        'ticks.future.current' => 0,
45
        'signals.total' => 0,
46
        'signals.current' => 0,
47
        'streams.duplex.total' => 0,
48
        'streams.duplex.current' => 0,
49
        'streams.read.total' => 0,
50
        'streams.read.current' => 0,
51
        'streams.write.total' => 0,
52
        'streams.write.current' => 0,
53
        'timers.periodic.total' => 0,
54
        'timers.periodic.current' => 0,
55
        'timers.once.total' => 0,
56
        'timers.once.current' => 0,
57
    ];
58
59
    public function __construct(LoopDecorator $loop)
60
    {
61
        $this->setupTicks($loop);
62
        $this->setupTimers($loop);
63
        $this->setupStreams($loop);
64
        $this->setupSignals($loop);
65
    }
66
67
    private function setupTicks(LoopDecorator $loop): void
68
    {
69
        $loop->on('futureTick', function (): void {
70
            $this->metrics['ticks.future.current']++;
71
            $this->metrics['ticks.future.total']++;
72
        });
73
        $loop->on('futureTickTick', function (): void {
74
            $this->metrics['ticks.future.current']--;
75
            $this->metrics['ticks.future.ticks']++;
76
        });
77
    }
78
79
    private function setupTimers(LoopDecorator $loop): void
80
    {
81
        /** @psalm-suppress MissingClosureParamType */
82
        $loop->on('addTimer', function ($void, $null, $timer): void {
83
            $this->timers[spl_object_hash($timer)] = TRUE_;
84
            $this->metrics['timers.once.current']++;
85
            $this->metrics['timers.once.total']++;
86
        });
87
        /** @psalm-suppress MissingClosureParamType */
88
        $loop->on('timerTick', function ($void, $null, $timer): void {
89
            $this->metrics['timers.once.current']--;
90
            $this->metrics['timers.once.ticks']++;
91
92
            $hash = spl_object_hash($timer);
93
            if (! array_key_exists($hash, $this->timers)) {
94
                return;
95
            }
96
97
            unset($this->timers[$hash]);
98
        });
99
        /** @psalm-suppress MissingClosureParamType */
100
        $loop->on('addPeriodicTimer', function ($void, $null, $timer): void {
101
            $this->timers[spl_object_hash($timer)] = TRUE_;
102
            $this->metrics['timers.periodic.current']++;
103
            $this->metrics['timers.periodic.total']++;
104
        });
105
        $loop->on('periodicTimerTick', function (): void {
106
            $this->metrics['timers.periodic.ticks']++;
107
        });
108
        $loop->on('cancelTimer', function (TimerInterface $timer): void {
109
            $hash = spl_object_hash($timer);
110
            if (! array_key_exists($hash, $this->timers)) {
111
                return;
112
            }
113
114
            unset($this->timers[$hash]);
115
116
            if ($timer->isPeriodic()) {
117
                $this->metrics['timers.periodic.current']--;
118
119
                return;
120
            }
121
122
            $this->metrics['timers.once.current']--;
123
        });
124
    }
125
126
    private function setupStreams(LoopDecorator $loop): void
127
    {
128
        /** @psalm-suppress MissingClosureParamType */
129
        $loop->on('addReadStream', function ($stream): void {
130
            $key = (int) $stream;
131
132
            $this->streamsRead[$key]   = $stream;
133
            $this->streamsDuplex[$key] = $stream;
134
135
            $this->metrics['streams.read.current']   = count($this->streamsRead);
136
            $this->metrics['streams.duplex.current'] = count($this->streamsDuplex);
137
            $this->metrics['streams.read.total']++;
138
            if (array_key_exists($key, $this->streamsWrite)) {
139
                return;
140
            }
141
142
            $this->metrics['streams.duplex.total']++;
143
        });
144
        $loop->on('readStreamTick', function (): void {
145
            $this->metrics['streams.read.ticks']++;
146
            $this->metrics['streams.duplex.ticks']++;
147
        });
148
        /** @psalm-suppress MissingClosureParamType */
149
        $loop->on('removeReadStream', function ($stream): void {
150
            $key = (int) $stream;
151
152
            if (array_key_exists($key, $this->streamsRead)) {
153
                unset($this->streamsRead[$key]);
154
            }
155
156
            if (array_key_exists($key, $this->streamsRead) && ! array_key_exists($key, $this->streamsWrite)) {
157
                unset($this->streamsDuplex[$key]);
158
            }
159
160
            $this->metrics['streams.read.current']   = count($this->streamsRead);
161
            $this->metrics['streams.duplex.current'] = count($this->streamsDuplex);
162
        });
163
164
        /** @psalm-suppress MissingClosureParamType */
165
        $loop->on('addWriteStream', function ($stream): void {
166
            $key = (int) $stream;
167
168
            $this->streamsWrite[$key]  = $stream;
169
            $this->streamsDuplex[$key] = $stream;
170
171
            $this->metrics['streams.write.current']  = count($this->streamsWrite);
172
            $this->metrics['streams.duplex.current'] = count($this->streamsDuplex);
173
            $this->metrics['streams.write.total']++;
174
175
            if (array_key_exists($key, $this->streamsRead)) {
176
                return;
177
            }
178
179
            $this->metrics['streams.duplex.total']++;
180
        });
181
        $loop->on('writeStreamTick', function (): void {
182
            $this->metrics['streams.write.ticks']++;
183
            $this->metrics['streams.duplex.ticks']++;
184
        });
185
        /** @psalm-suppress MissingClosureParamType */
186
        $loop->on('removeWriteStream', function ($stream): void {
187
            $key = (int) $stream;
188
189
            if (array_key_exists($key, $this->streamsWrite)) {
190
                unset($this->streamsWrite[$key]);
191
            }
192
193
            if (array_key_exists($key, $this->streamsRead) && ! array_key_exists($key, $this->streamsRead)) {
194
                unset($this->streamsDuplex[$key]);
195
            }
196
197
            $this->metrics['streams.write.current']  = count($this->streamsWrite);
198
            $this->metrics['streams.duplex.current'] = count($this->streamsDuplex);
199
        });
200
    }
201
202
    private function setupSignals(LoopDecorator $loop): void
203
    {
204
        $loop->on('addSignal', function (): void {
205
            $this->metrics['signals.current']++;
206
            $this->metrics['signals.total']++;
207
        });
208
        $loop->on('signalTick', function (): void {
209
            $this->metrics['signals.ticks']++;
210
        });
211
        $loop->on('removeSignal', function (): void {
212
            $this->metrics['signals.current']--;
213
        });
214
    }
215
216
    public function collect(): Observable
217
    {
218
        return observableFromArray([
219
            Metric::create(
220
                new Config(
221
                    'reactphp_ticks',
222
                    'gauge',
223
                    ''
224
                ),
225
                new Tags(
226
                    new Tag('reactphp_component', 'event-loop'),
227
                ),
228
                new Measurements(
229
                    new Measurement($this->metrics['signals.ticks'], new Tags(new Tag('event_loop_component', 'signals'))),
230
                    new Measurement(
231
                        $this->metrics['streams.read.ticks'],
232
                        new Tags(
233
                            new Tag('event_loop_component', 'streams'),
234
                            new Tag('stream_kind', 'read'),
235
                        )
236
                    ),
237
                    new Measurement(
238
                        $this->metrics['streams.duplex.ticks'],
239
                        new Tags(
240
                            new Tag('event_loop_component', 'streams'),
241
                            new Tag('stream_kind', 'duplex'),
242
                        )
243
                    ),
244
                    new Measurement(
245
                        $this->metrics['streams.write.ticks'],
246
                        new Tags(
247
                            new Tag('event_loop_component', 'streams'),
248
                            new Tag('stream_kind', 'write'),
249
                        )
250
                    ),
251
                    new Measurement(
252
                        $this->metrics['timers.periodic.ticks'],
253
                        new Tags(
254
                            new Tag('event_loop_component', 'timers'),
255
                            new Tag('timer_kind', 'periodic'),
256
                        )
257
                    ),
258
                    new Measurement(
259
                        $this->metrics['timers.once.ticks'],
260
                        new Tags(
261
                            new Tag('event_loop_component', 'timers'),
262
                            new Tag('timer_kind', 'once'),
263
                        )
264
                    ),
265
                    new Measurement(
266
                        $this->metrics['ticks.future.ticks'],
267
                        new Tags(
268
                            new Tag('event_loop_component', 'ticks'),
269
                        )
270
                    ),
271
                    new Measurement(
272
                        $this->metrics['ticks.future.current'],
273
                        new Tags(
274
                            new Tag('event_loop_component', 'ticks'),
275
                            new Tag('future_tick_state', 'active'),
276
                        )
277
                    ),
278
                    new Measurement(
279
                        $this->metrics['ticks.future.total'] - $this->metrics['ticks.future.current'],
280
                        new Tags(
281
                            new Tag('event_loop_component', 'ticks'),
282
                            new Tag('future_tick_state', 'done'),
283
                        )
284
                    ),
285
                )
286
            ),
287
            Metric::create(
288
                new Config(
289
                    'reactphp_signals',
290
                    'gauge',
291
                    ''
292
                ),
293
                new Tags(
294
                    new Tag('reactphp_component', 'event-loop'),
295
                ),
296
                new Measurements(
297
                    new Measurement(
298
                        $this->metrics['signals.current'],
299
                        new Tags(
300
                            new Tag('event_loop_component', 'signals'),
301
                            new Tag('signal_state', 'active'),
302
                        )
303
                    ),
304
                    new Measurement(
305
                        $this->metrics['signals.total'] - $this->metrics['signals.current'],
306
                        new Tags(
307
                            new Tag('event_loop_component', 'signals'),
308
                            new Tag('signal_state', 'done'),
309
                        )
310
                    ),
311
                )
312
            ),
313
            Metric::create(
314
                new Config(
315
                    'reactphp_streams',
316
                    'gauge',
317
                    ''
318
                ),
319
                new Tags(
320
                    new Tag('reactphp_component', 'event-loop'),
321
                ),
322
                new Measurements(
323
                    new Measurement(
324
                        $this->metrics['streams.duplex.current'],
325
                        new Tags(
326
                            new Tag('event_loop_component', 'streams'),
327
                            new Tag('stream_kind', 'duplex'),
328
                            new Tag('stream_state', 'active'),
329
                        )
330
                    ),
331
                    new Measurement(
332
                        $this->metrics['streams.duplex.total'] - $this->metrics['streams.duplex.current'],
333
                        new Tags(
334
                            new Tag('event_loop_component', 'streams'),
335
                            new Tag('stream_kind', 'duplex'),
336
                            new Tag('stream_state', 'done'),
337
                        )
338
                    ),
339
                    new Measurement(
340
                        $this->metrics['streams.read.current'],
341
                        new Tags(
342
                            new Tag('event_loop_component', 'streams'),
343
                            new Tag('stream_kind', 'read'),
344
                            new Tag('stream_state', 'active'),
345
                        )
346
                    ),
347
                    new Measurement(
348
                        $this->metrics['streams.read.total'] - $this->metrics['streams.read.current'],
349
                        new Tags(
350
                            new Tag('event_loop_component', 'streams'),
351
                            new Tag('stream_kind', 'read'),
352
                            new Tag('stream_state', 'done'),
353
                        ),
354
                    ),
355
                    new Measurement(
356
                        $this->metrics['streams.write.current'],
357
                        new Tags(
358
                            new Tag('event_loop_component', 'streams'),
359
                            new Tag('stream_kind', 'write'),
360
                            new Tag('stream_state', 'active'),
361
                        )
362
                    ),
363
                    new Measurement(
364
                        $this->metrics['streams.write.total'] - $this->metrics['streams.write.current'],
365
                        new Tags(
366
                            new Tag('event_loop_component', 'streams'),
367
                            new Tag('stream_kind', 'write'),
368
                            new Tag('stream_state', 'done'),
369
                        )
370
                    ),
371
                )
372
            ),
373
            Metric::create(
374
                new Config(
375
                    'reactphp_timers',
376
                    'gauge',
377
                    ''
378
                ),
379
                new Tags(
380
                    new Tag('reactphp_component', 'event-loop'),
381
                ),
382
                new Measurements(
383
                    new Measurement(
384
                        $this->metrics['timers.periodic.current'],
385
                        new Tags(
386
                            new Tag('event_loop_component', 'timers'),
387
                            new Tag('timer_kind', 'periodic'),
388
                            new Tag('timer_state', 'active'),
389
                        )
390
                    ),
391
                    new Measurement(
392
                        $this->metrics['timers.periodic.total'] - $this->metrics['timers.periodic.current'],
393
                        new Tags(
394
                            new Tag('event_loop_component', 'timers'),
395
                            new Tag('timer_kind', 'periodic'),
396
                            new Tag('timer_state', 'done'),
397
                        )
398
                    ),
399
                    new Measurement(
400
                        $this->metrics['timers.once.current'],
401
                        new Tags(
402
                            new Tag('event_loop_component', 'timers'),
403
                            new Tag('timer_kind', 'once'),
404
                            new Tag('timer_state', 'active'),
405
                        )
406
                    ),
407
                    new Measurement(
408
                        $this->metrics['timers.once.total'] - $this->metrics['timers.once.current'],
409
                        new Tags(
410
                            new Tag('event_loop_component', 'timers'),
411
                            new Tag('timer_kind', 'once'),
412
                            new Tag('timer_state', 'done'),
413
                        )
414
                    ),
415
                )
416
            ),
417
        ]);
418
    }
419
420
    public function cancel(): void
421
    {
422
        // Do nothing
423
    }
424
}
425