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/Factories/Factory.php (1 issue)

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 declare(strict_types=1);
2
3
namespace Neomerx\JsonApi\Factories;
4
5
/**
6
 * Copyright 2015-2020 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface;
22
use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
23
use Neomerx\JsonApi\Contracts\Http\Headers\AcceptMediaTypeInterface;
24
use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
25
use Neomerx\JsonApi\Contracts\Parser\EditableContextInterface;
26
use Neomerx\JsonApi\Contracts\Parser\IdentifierInterface as ParserIdentifierInterface;
27
use Neomerx\JsonApi\Contracts\Parser\ParserInterface;
28
use Neomerx\JsonApi\Contracts\Parser\RelationshipDataInterface;
29
use Neomerx\JsonApi\Contracts\Parser\RelationshipInterface;
30
use Neomerx\JsonApi\Contracts\Parser\ResourceInterface;
31
use Neomerx\JsonApi\Contracts\Representation\DocumentWriterInterface;
32
use Neomerx\JsonApi\Contracts\Representation\ErrorWriterInterface;
33
use Neomerx\JsonApi\Contracts\Representation\FieldSetFilterInterface;
34
use Neomerx\JsonApi\Contracts\Schema\IdentifierInterface as SchemaIdentifierInterface;
35
use Neomerx\JsonApi\Contracts\Schema\LinkInterface;
36
use Neomerx\JsonApi\Contracts\Schema\PositionInterface;
37
use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
38
use Neomerx\JsonApi\Encoder\Encoder;
39
use Neomerx\JsonApi\Http\Headers\AcceptMediaType;
40
use Neomerx\JsonApi\Http\Headers\MediaType;
41
use Neomerx\JsonApi\Parser\IdentifierAndResource;
42
use Neomerx\JsonApi\Parser\Parser;
43
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsCollection;
44
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsIdentifier;
45
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsNull;
46
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsResource;
47
use Neomerx\JsonApi\Representation\DocumentWriter;
48
use Neomerx\JsonApi\Representation\ErrorWriter;
49
use Neomerx\JsonApi\Representation\FieldSetFilter;
50
use Neomerx\JsonApi\Schema\Link;
51
use Neomerx\JsonApi\Schema\SchemaContainer;
52
53
/**
54
 * @package Neomerx\JsonApi
55
 *
56
 * @SuppressWarnings(PHPMD.TooManyFields)
57
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
58
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
59
 */
60
class Factory implements FactoryInterface
61
{
62
    /**
63
     * @inheritdoc
64
     */
65 81
    public function createEncoder(SchemaContainerInterface $container): EncoderInterface
66
    {
67 81
        return new Encoder($this, $container);
68
    }
69
70
    /**
71
     * @inheritdoc
72
     */
73 94
    public function createSchemaContainer(iterable $schemas): SchemaContainerInterface
74
    {
75 94
        return new SchemaContainer($this, $schemas);
76
    }
77
78
    /**
79
     * @inheritdoc
80
     */
81 80
    public function createPosition(
82
        int $level,
83
        string $path,
84
        ?string $parentType,
85
        ?string $parentRelationship
86
    ): PositionInterface {
87
        return new class ($level, $path, $parentType, $parentRelationship) implements PositionInterface
88
        {
89
            /**
90
             * @var int
91
             */
92
            private $level;
93
94
            /**
95
             * @var string
96
             */
97
            private $path;
98
99
            /**
100
             * @var null|string
101
             */
102
            private $parentType;
103
104
            /**
105
             * @var null|string
106
             */
107
            private $parentRelationship;
108
109
            /**
110
             * @param int         $level
111
             * @param string      $path
112
             * @param null|string $parentType
113
             * @param null|string $parentRelationship
114
             */
115
            public function __construct(int $level, string $path, ?string $parentType, ?string $parentRelationship)
116
            {
117 80
                $this->level              = $level;
118 80
                $this->path               = $path;
119 80
                $this->parentType         = $parentType;
120 80
                $this->parentRelationship = $parentRelationship;
121 80
            }
122
123
            /**
124
             * @inheritdoc
125
             */
126 75
            public function getLevel(): int
127
            {
128 75
                return $this->level;
129
            }
130
131
            /**
132
             * @inheritdoc
133
             */
134 65
            public function getPath(): string
135
            {
136 65
                return $this->path;
137
            }
138
139
            /**
140
             * @inheritdoc
141
             */
142 25
            public function getParentType(): ?string
143
            {
144 25
                return $this->parentType;
145
            }
146
147
            /**
148
             * @inheritdoc
149
             */
150 7
            public function getParentRelationship(): ?string
151
            {
152 7
                return $this->parentRelationship;
153
            }
154
        };
155
    }
156
157
    /**
158
     * @inheritdoc
159
     */
160 74
    public function createParser(
161
        SchemaContainerInterface $container,
162
        EditableContextInterface $context
163
    ): ParserInterface {
164 74
        return new Parser($this, $container, $context);
165
    }
166
167
    /**
168
     * @inheritdoc
169
     */
170 78
    public function createDocumentWriter(): DocumentWriterInterface
171
    {
172 78
        return new DocumentWriter();
173
    }
174
175
    /**
176
     * @inheritdoc
177
     */
178 7
    public function createErrorWriter(): ErrorWriterInterface
179
    {
180 7
        return new ErrorWriter();
181
    }
182
183
    /**
184
     * @inheritdoc
185
     */
186 75
    public function createFieldSetFilter(array $fieldSets): FieldSetFilterInterface
187
    {
188 75
        return new FieldSetFilter($fieldSets);
189
    }
190
191
    /**
192
     * @inheritdoc
193
     */
194 64
    public function createParsedResource(
195
        EditableContextInterface $context,
196
        PositionInterface $position,
197
        SchemaContainerInterface $container,
198
        $data
199
    ): ResourceInterface {
200 64
        return new IdentifierAndResource($context, $position, $this, $container, $data);
201
    }
202
203
    /**
204
     * @inheritdoc
205
     */
206 2
    public function createParsedIdentifier(
207
        PositionInterface $position,
208
        SchemaIdentifierInterface $identifier
209
    ): ParserIdentifierInterface {
210
        return new class ($position, $identifier) implements ParserIdentifierInterface
211
        {
212
            /**
213
             * @var PositionInterface
214
             */
215
            private $position;
216
217
            /**
218
             * @var SchemaIdentifierInterface
219
             */
220
            private $identifier;
221
222
            /**
223
             * @param PositionInterface         $position
224
             * @param SchemaIdentifierInterface $identifier
225
             */
226
            public function __construct(
227
                PositionInterface $position,
228
                SchemaIdentifierInterface $identifier
229
            ) {
230 2
                $this->position   = $position;
231 2
                $this->identifier = $identifier;
232
233
                // for test coverage only
234 2
                \assert($this->getPosition() !== null);
235 2
            }
236
237
            /**
238
             * @inheritdoc
239
             */
240 2
            public function getType(): string
241
            {
242 2
                return $this->identifier->getType();
243
            }
244
245
            /**
246
             * @inheritdoc
247
             */
248 2
            public function getId(): ?string
249
            {
250 2
                return $this->identifier->getId();
251
            }
252
253
            /**
254
             * @inheritdoc
255
             */
256 2
            public function hasIdentifierMeta(): bool
257
            {
258 2
                return $this->identifier->hasIdentifierMeta();
259
            }
260
261
            /**
262
             * @inheritdoc
263
             */
264 1
            public function getIdentifierMeta()
265
            {
266 1
                return $this->identifier->getIdentifierMeta();
267
            }
268
269
            /**
270
             * @inheritdoc
271
             */
272
            public function getPosition(): PositionInterface
273
            {
274 2
                return $this->position;
275
            }
276
        };
277
    }
278
279
    /**
280
     * @inheritdoc
281
     */
282 67
    public function createLink(bool $isSubUrl, string $value, bool $hasMeta, $meta = null): LinkInterface
283
    {
284 67
        return new Link($isSubUrl, $value, $hasMeta, $meta);
285
    }
286
287
    /**
288
     * @inheritdoc
289
     *
290
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
291
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
292
     */
293 50
    public function createRelationship(
294
        PositionInterface $position,
295
        bool $hasData,
296
        ?RelationshipDataInterface $data,
297
        bool $hasLinks,
298
        ?iterable $links,
299
        bool $hasMeta,
300
        $meta
301
    ): RelationshipInterface {
302
        return new class (
303 50
            $position,
304 50
            $hasData,
305 50
            $data,
306 50
            $hasLinks,
307 50
            $links,
308 50
            $hasMeta,
309 50
            $meta
310
        ) implements RelationshipInterface
311
        {
312
            /**
313
             * @var PositionInterface
314
             */
315
            private $position;
316
317
            /**
318
             * @var bool
319
             */
320
            private $hasData;
321
322
            /**
323
             * @var ?RelationshipDataInterface
324
             */
325
            private $data;
326
327
            /**
328
             * @var bool
329
             */
330
            private $hasLinks;
331
332
            /**
333
             * @var ?iterable
334
             */
335
            private $links;
336
337
            /**
338
             * @var bool
339
             */
340
            private $hasMeta;
341
342
            /**
343
             * @var mixed
344
             */
345
            private $meta;
346
347
            /**
348
             * @var bool
349
             */
350
            private $metaIsCallable;
351
352
            /**
353
             * @param PositionInterface              $position
354
             * @param bool                           $hasData
355
             * @param RelationshipDataInterface|null $data
356
             * @param bool                           $hasLinks
357
             * @param iterable|null                  $links
358
             * @param bool                           $hasMeta
359
             * @param mixed                          $meta
360
             */
361
            public function __construct(
362
                PositionInterface $position,
363
                bool $hasData,
364
                ?RelationshipDataInterface $data,
365
                bool $hasLinks,
366
                ?iterable $links,
367
                bool $hasMeta,
368
                $meta
369
            ) {
370 50
                \assert($position->getLevel() > ParserInterface::ROOT_LEVEL);
371 50
                \assert(empty($position->getPath()) === false);
372 50
                \assert(($hasData === false && $data === null) || ($hasData === true && $data !== null));
373 50
                \assert(($hasLinks === false && $links === null) || ($hasLinks === true && $links !== null));
374
375 50
                $this->position       = $position;
376 50
                $this->hasData        = $hasData;
377 50
                $this->data           = $data;
378 50
                $this->hasLinks       = $hasLinks;
379 50
                $this->links          = $links;
380 50
                $this->hasMeta        = $hasMeta;
381 50
                $this->meta           = $meta;
382 50
                $this->metaIsCallable = \is_callable($meta);
383 50
            }
384
385
            /**
386
             * @inheritdoc
387
             */
388
            public function getPosition(): PositionInterface
389
            {
390 50
                return $this->position;
391
            }
392
393
            /**
394
             * @inheritdoc
395
             */
396 45
            public function hasData(): bool
397
            {
398 45
                return $this->hasData;
399
            }
400
401
            /**
402
             * @inheritdoc
403
             */
404 38
            public function getData(): RelationshipDataInterface
405
            {
406 38
                \assert($this->hasData());
407
408 38
                return $this->data;
409
            }
410
411
            /**
412
             * @inheritdoc
413
             */
414 44
            public function hasLinks(): bool
415
            {
416 44
                return $this->hasLinks;
417
            }
418
419
            /**
420
             * @inheritdoc
421
             */
422 27
            public function getLinks(): iterable
423
            {
424 27
                \assert($this->hasLinks());
425
426 27
                return $this->links;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->links; of type Neomerx\JsonApi\Factories\iterable|null adds the type Neomerx\JsonApi\Factories\iterable to the return on line 426 which is incompatible with the return type declared by the interface Neomerx\JsonApi\Contract...shipInterface::getLinks of type Neomerx\JsonApi\Contracts\Parser\iterable.
Loading history...
427
            }
428
429
            /**
430
             * @inheritdoc
431
             */
432 44
            public function hasMeta(): bool
433
            {
434 44
                return $this->hasMeta;
435
            }
436
437
            /**
438
             * @inheritdoc
439
             */
440 2
            public function getMeta()
441
            {
442 2
                \assert($this->hasMeta());
443
444 2
                if ($this->metaIsCallable === true) {
445 1
                    $this->meta           = \call_user_func($this->meta);
446 1
                    $this->metaIsCallable = false;
447
                }
448
449 2
                return $this->meta;
450
            }
451
        };
452
    }
453
454
    /**
455
     * @inheritdoc
456
     */
457 27
    public function createRelationshipDataIsResource(
458
        SchemaContainerInterface $schemaContainer,
459
        EditableContextInterface $context,
460
        PositionInterface $position,
461
        $resource
462
    ): RelationshipDataInterface {
463 27
        return new RelationshipDataIsResource($this, $schemaContainer, $context, $position, $resource);
464
    }
465
466
    /**
467
     * @inheritdoc
468
     */
469 1
    public function createRelationshipDataIsIdentifier(
470
        SchemaContainerInterface $schemaContainer,
471
        EditableContextInterface $context,
472
        PositionInterface $position,
473
        SchemaIdentifierInterface $identifier
474
    ): RelationshipDataInterface {
475 1
        return new RelationshipDataIsIdentifier($this, $schemaContainer, $context, $position, $identifier);
476
    }
477
478
    /**
479
     * @inheritdoc
480
     */
481 35
    public function createRelationshipDataIsCollection(
482
        SchemaContainerInterface $schemaContainer,
483
        EditableContextInterface $context,
484
        PositionInterface $position,
485
        iterable $resources
486
    ): RelationshipDataInterface {
487 35
        return new RelationshipDataIsCollection($this, $schemaContainer, $context, $position, $resources);
488
    }
489
490
    /**
491
     * @inheritdoc
492
     */
493 5
    public function createRelationshipDataIsNull(): RelationshipDataInterface
494
    {
495 5
        return new RelationshipDataIsNull();
496
    }
497
498
    /**
499
     * @inheritdoc
500
     */
501 4
    public function createMediaType(string $type, string $subType, array $parameters = null): MediaTypeInterface
502
    {
503 4
        return new MediaType($type, $subType, $parameters);
504
    }
505
506
    /**
507
     * @inheritdoc
508
     */
509 12
    public function createAcceptMediaType(
510
        int $position,
511
        string $type,
512
        string $subType,
513
        array $parameters = null,
514
        float $quality = 1.0
515
    ): AcceptMediaTypeInterface {
516 12
        return new AcceptMediaType($position, $type, $subType, $parameters, $quality);
517
    }
518
519
    /**
520
     * @inheritdoc
521
     *
522
     * @SuppressWarnings(PHPMD.UndefinedVariable) PHPMD currently has a glitch with `$position` in `setPosition`
523
     */
524 80
    public function createParserContext(array $fieldSets, array $includePaths): EditableContextInterface
525
    {
526
        return new class ($fieldSets, $includePaths) implements EditableContextInterface
527
        {
528
            /**
529
             * @var array
530
             */
531
            private $fieldSets;
532
533
            /**
534
             * @var array
535
             */
536
            private $includePaths;
537
538
            /**
539
             * @var PositionInterface|null
540
             */
541
            private $position = null;
542
543
            /**
544
             * @param array $fieldSets
545
             * @param array $includePaths
546
             */
547
            public function __construct(array $fieldSets, array $includePaths)
548
            {
549 80
                $this->fieldSets    = $fieldSets;
550 80
                $this->includePaths = $includePaths;
551 80
            }
552
553
            /**
554
             * @inheritdoc
555
             */
556 35
            public function getFieldSets(): array
557
            {
558 35
                return $this->fieldSets;
559
            }
560
561
            /**
562
             * @inheritdoc
563
             */
564 35
            public function getIncludePaths(): array
565
            {
566 35
                return $this->includePaths;
567
            }
568
569
            /**
570
             * @inheritdoc
571
             */
572
            public function getPosition(): PositionInterface
573
            {
574
                // parser's implementation should guarantee that position will always be initialized
575
                // before use in a schema.
576 35
                \assert($this->position !== null);
577
578 35
                return $this->position;
579
            }
580
581
            /**
582
             * @inheritdoc
583
             */
584 65
            public function setPosition(PositionInterface $position): void
585
            {
586 65
                $this->position = $position;
587 65
            }
588
        };
589
    }
590
}
591