PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.0.1
Defender Security – Malware Scanner, Login Security & Firewall v3.0.1
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / vendor / spomky-labs / cbor-php / src / Decoder.php

Decoder.php in Defender Security – Malware Scanner, Login Security & Firewall 3.0.1, at vendor/spomky-labs/cbor-php/src/Decoder.php

161 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 /*
6 * The MIT License (MIT)
7 *
8 * Copyright (c) 2018-2020 Spomky-Labs
9 *
10 * This software may be modified and distributed under the terms
11 * of the MIT license. See the LICENSE file for details.
12 */
13
14 namespace CBOR;
15
16 use CBOR\OtherObject\BreakObject;
17 use CBOR\OtherObject\OtherObjectManager;
18 use CBOR\Tag\TagObjectManager;
19 use InvalidArgumentException;
20 use function ord;
21 use RuntimeException;
22
23 final class Decoder
24 {
25 /**
26 * @var TagObjectManager
27 */
28 private $tagObjectManager;
29
30 /**
31 * @var OtherObjectManager
32 */
33 private $otherTypeManager;
34
35 public function __construct(TagObjectManager $tagObjectManager, OtherObjectManager $otherTypeManager)
36 {
37 $this->tagObjectManager = $tagObjectManager;
38 $this->otherTypeManager = $otherTypeManager;
39 }
40
41 public function decode(Stream $stream): CBORObject
42 {
43 return $this->process($stream);
44 }
45
46 private function process(Stream $stream, bool $breakable = false): CBORObject
47 {
48 $ib = ord($stream->read(1));
49 $mt = $ib >> 5;
50 $ai = $ib & 0b00011111;
51 $val = null;
52 switch ($ai) {
53 case 0b00011000: //24
54 case 0b00011001: //25
55 case 0b00011010: //26
56 case 0b00011011: //27
57 $val = $stream->read(2 ** ($ai & 0b00000111));
58 break;
59 case 0b00011100: //28
60 case 0b00011101: //29
61 case 0b00011110: //30
62 throw new InvalidArgumentException(sprintf('Cannot parse the data. Found invalid Additional Information "%s" (%d).', str_pad(decbin($ai), 5, '0', STR_PAD_LEFT), $ai));
63 case 0b00011111: //31
64 return $this->processInfinite($stream, $mt, $breakable);
65 }
66
67 return $this->processFinite($stream, $mt, $ai, $val);
68 }
69
70 private function processFinite(Stream $stream, int $mt, int $ai, ?string $val): CBORObject
71 {
72 switch ($mt) {
73 case 0b000: //0
74 return UnsignedIntegerObject::createObjectForValue($ai, $val);
75 case 0b001: //1
76 return SignedIntegerObject::createObjectForValue($ai, $val);
77 case 0b010: //2
78 $length = null === $val ? $ai : Utils::binToInt($val);
79
80 return new ByteStringObject($stream->read($length));
81 case 0b011: //3
82 $length = null === $val ? $ai : Utils::binToInt($val);
83
84 return new TextStringObject($stream->read($length));
85 case 0b100: //4
86 $object = new ListObject();
87 $nbItems = null === $val ? $ai : Utils::binToInt($val);
88 for ($i = 0; $i < $nbItems; ++$i) {
89 $object->add($this->process($stream));
90 }
91
92 return $object;
93 case 0b101: //5
94 $object = new MapObject();
95 $nbItems = null === $val ? $ai : Utils::binToInt($val);
96 for ($i = 0; $i < $nbItems; ++$i) {
97 $object->add($this->process($stream), $this->process($stream));
98 }
99
100 return $object;
101 case 0b110: //6
102 return $this->tagObjectManager->createObjectForValue($ai, $val, $this->process($stream));
103 case 0b111: //7
104 return $this->otherTypeManager->createObjectForValue($ai, $val);
105 default:
106 throw new RuntimeException(sprintf('Unsupported major type "%s" (%d).', str_pad(decbin($mt), 5, '0', STR_PAD_LEFT), $mt)); // Should never append
107 }
108 }
109
110 private function processInfinite(Stream $stream, int $mt, bool $breakable): CBORObject
111 {
112 switch ($mt) {
113 case 0b010: //2
114 $object = new ByteStringWithChunkObject();
115 while (!($it = $this->process($stream, true)) instanceof BreakObject) {
116 if (!$it instanceof ByteStringObject) {
117 throw new RuntimeException('Unable to parse the data. Infinite Byte String object can only get Byte String objects.');
118 }
119 $object->add($it);
120 }
121
122 return $object;
123 case 0b011: //3
124 $object = new TextStringWithChunkObject();
125 while (!($it = $this->process($stream, true)) instanceof BreakObject) {
126 if (!$it instanceof TextStringObject) {
127 throw new RuntimeException('Unable to parse the data. Infinite Text String object can only get Text String objects.');
128 }
129 $object->add($it);
130 }
131
132 return $object;
133 case 0b100: //4
134 $object = new InfiniteListObject();
135 while (!($it = $this->process($stream, true)) instanceof BreakObject) {
136 $object->add($it);
137 }
138
139 return $object;
140 case 0b101: //5
141 $object = new InfiniteMapObject();
142 while (!($it = $this->process($stream, true)) instanceof BreakObject) {
143 $object->append($it, $this->process($stream));
144 }
145
146 return $object;
147 case 0b111: //7
148 if (!$breakable) {
149 throw new InvalidArgumentException('Cannot parse the data. No enclosing indefinite.');
150 }
151
152 return new BreakObject();
153 case 0b000: //0
154 case 0b001: //1
155 case 0b110: //6
156 default:
157 throw new InvalidArgumentException(sprintf('Cannot parse the data. Found infinite length for Major Type "%s" (%d).', str_pad(decbin($mt), 5, '0', STR_PAD_LEFT), $mt));
158 }
159 }
160 }
161