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.
Completed
Push — master ( a25647...c0e57f )
by Joni
03:42
created

Identifier::tag()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace ASN1\Component;
4
5
use ASN1\Exception\DecodeException;
6
use ASN1\Feature\Encodable;
7
8
9
/**
10
 * Class to represent BER/DER identifier octets.
11
 */
12
class Identifier implements Encodable
13
{
14
	// Type class enumerations
15
	const CLASS_UNIVERSAL = 0b00;
16
	const CLASS_APPLICATION = 0b01;
17
	const CLASS_CONTEXT_SPECIFIC = 0b10;
18
	const CLASS_PRIVATE = 0b11;
19
	
20
	/**
21
	 * Mapping from type class to human readable name.
22
	 *
23
	 * @internal
24
	 *
25
	 * @var array
26
	 */
27
	const MAP_CLASS_TO_NAME = array(
28
		/* @formatter:off */
29
		self::CLASS_UNIVERSAL => "UNIVERSAL", 
30
		self::CLASS_APPLICATION => "APPLICATION", 
31
		self::CLASS_CONTEXT_SPECIFIC => "CONTEXT SPECIFIC", 
32
		self::CLASS_PRIVATE => "PRIVATE"
33
		/* @formatter:on */
34
	);
35
	
36
	// P/C enumerations
37
	const PRIMITIVE = 0b0;
38
	const CONSTRUCTED = 0b1;
39
	
40
	/**
41
	 * Type class.
42
	 *
43
	 * @var int
44
	 */
45
	private $_class;
46
	
47
	/**
48
	 * Primitive or Constructed.
49
	 *
50
	 * @var int
51
	 */
52
	private $_pc;
53
	
54
	/**
55
	 * Content type tag.
56
	 *
57
	 * @var int|string
58
	 */
59
	private $_tag;
60
	
61
	/**
62
	 * Constructor
63
	 *
64
	 * @param int $class Type class
65
	 * @param int $pc Privitive / Constructed
66
	 * @param int|string $tag Type tag number
67
	 */
68 313
	public function __construct($class, $pc, $tag) {
69 313
		$this->_class = 0b11 & $class;
70 313
		$this->_pc = 0b1 & $pc;
71 313
		$this->_tag = $tag;
72 313
	}
73
	
74
	/**
75
	 * Decode identifier component from DER data.
76
	 *
77
	 * @param string $data DER encoded data
78
	 * @param int|null $offset Reference to the variable that contains offset
79
	 *        into the data where to start parsing. Variable is updated to
80
	 *        the offset next to the parsed identifier. If null, start from
81
	 *        offset 0.
82
	 * @throws DecodeException If decoding fails
83
	 * @return self
84
	 */
85 216
	public static function fromDER($data, &$offset = null) {
86 216
		assert('is_string($data)', "got " . gettype($data));
87 215
		$idx = $offset ? $offset : 0;
88 215
		$datalen = strlen($data);
89 215
		if ($idx >= $datalen) {
90 1
			throw new DecodeException("Invalid offset.");
91
		}
92 214
		$byte = ord($data[$idx++]);
93
		// bits 8 and 7 (class)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
94
		// 0 = universal, 1 = application, 2 = context-specific, 3 = private
95 214
		$class = (0b11000000 & $byte) >> 6;
96
		// bit 6 (0 = primitive / 1 = constructed)
97 214
		$pc = (0b00100000 & $byte) >> 5;
98
		// bits 5 to 1 (tag number)
99 214
		$tag = (0b00011111 & $byte);
100
		// long-form identifier
101 214
		if (0x1f == $tag) {
102 7
			$tag = self::_decodeLongFormTag($data, $idx);
103 6
		}
104 213
		if (isset($offset)) {
105 201
			$offset = $idx;
106 201
		}
107 213
		return new self($class, $pc, $tag);
108
	}
109
	
110
	/**
111
	 * Parse long form tag.
112
	 *
113
	 * @param string $data DER data
114
	 * @param int $offset Reference to the variable containing offset to data
115
	 * @throws DecodeException If decoding fails
116
	 * @return int|string Tag number
117
	 */
118 7
	private static function _decodeLongFormTag($data, &$offset) {
119 7
		$datalen = strlen($data);
120 7
		$tag = gmp_init(0, 10);
121 7
		while (true) {
122 7
			if ($offset >= $datalen) {
123 1
				throw new DecodeException(
124
					"Unexpected end of data while decoding" .
125 1
						 " long form identifier.");
126
			}
127 7
			$byte = ord($data[$offset++]);
128 7
			$tag <<= 7;
129 7
			$tag |= 0x7f & $byte;
130
			// last byte has bit 8 set to zero
131 7
			if (!(0x80 & $byte)) {
132 6
				break;
133
			}
134 3
		}
135 6
		return gmp_strval($tag, 10);
136
	}
137
	
138
	/**
139
	 *
140
	 * @see Encodable::toDER()
141
	 * @return string
142
	 */
143 117
	public function toDER() {
144 117
		$bytes = array();
145 117
		$byte = $this->_class << 6 | $this->_pc << 5;
146 117
		$tag = gmp_init($this->_tag, 10);
147 117
		if ($tag < 0x1f) {
148 114
			$bytes[] = $byte | $tag;
149 114
		} else { // long-form identifier
150 4
			$bytes[] = $byte | 0x1f;
151 4
			$octets = array();
152 4
			for (; $tag > 0; $tag >>= 7) {
153 4
				array_push($octets, gmp_intval(0x80 | ($tag & 0x7f)));
154 4
			}
155
			// last octet has bit 8 set to zero
156 4
			$octets[0] &= 0x7f;
157 4
			foreach (array_reverse($octets) as $octet) {
158 4
				$bytes[] = $octet;
159 4
			}
160
		}
161 117
		return pack("C*", ...$bytes);
162
	}
163
	
164
	/**
165
	 * Get class of the type.
166
	 *
167
	 * @return int
168
	 */
169 6
	public function typeClass() {
170 6
		return $this->_class;
171
	}
172
	
173
	/**
174
	 * Get P/C.
175
	 *
176
	 * @return int
177
	 */
178 1
	public function pc() {
179 1
		return $this->_pc;
180
	}
181
	
182
	/**
183
	 * Get the tag number.
184
	 *
185
	 * @return int|string
186
	 */
187 203
	public function tag() {
188 203
		return $this->_tag;
189
	}
190
	
191
	/**
192
	 * Check whether type is of an universal class.
193
	 *
194
	 * @return boolean
195
	 */
196 186
	public function isUniversal() {
197 186
		return self::CLASS_UNIVERSAL == $this->_class;
198
	}
199
	
200
	/**
201
	 * Check whether type is of an application class.
202
	 *
203
	 * @return boolean
204
	 */
205 1
	public function isApplication() {
206 1
		return self::CLASS_APPLICATION == $this->_class;
207
	}
208
	
209
	/**
210
	 * Check whether type is of a context specific class.
211
	 *
212
	 * @return boolean
213
	 */
214 194
	public function isContextSpecific() {
215 194
		return self::CLASS_CONTEXT_SPECIFIC == $this->_class;
216
	}
217
	
218
	/**
219
	 * Check whether type is of a private class.
220
	 *
221
	 * @return boolean
222
	 */
223 1
	public function isPrivate() {
224 1
		return self::CLASS_PRIVATE == $this->_class;
225
	}
226
	
227
	/**
228
	 * Check whether content is primitive type.
229
	 *
230
	 * @return boolean
231
	 */
232 79
	public function isPrimitive() {
233 79
		return self::PRIMITIVE == $this->_pc;
234
	}
235
	
236
	/**
237
	 * Check hether content is constructed type.
238
	 *
239
	 * @return boolean
240
	 */
241 23
	public function isConstructed() {
242 23
		return self::CONSTRUCTED == $this->_pc;
243
	}
244
	
245
	/**
246
	 * Get self with given type class.
247
	 *
248
	 * @param int $class One of <code>CLASS_*</code> enumerations
249
	 * @return self
250
	 */
251 6
	public function withClass($class) {
252 6
		$obj = clone $this;
253 6
		$obj->_class = $class;
254 6
		return $obj;
255
	}
256
	
257
	/**
258
	 * Get self with given type tag.
259
	 *
260
	 * @param int|string $tag Tag number
261
	 * @return self
262
	 */
263 6
	public function withTag($tag) {
264 6
		$obj = clone $this;
265 6
		$obj->_tag = $tag;
266 6
		return $obj;
267
	}
268
	
269
	/**
270
	 * Get human readable name of the type class.
271
	 *
272
	 * @param int $class
273
	 * @return string
274
	 */
275 8
	public static function classToName($class) {
276 8
		if (!array_key_exists($class, self::MAP_CLASS_TO_NAME)) {
277 1
			return "CLASS $class";
278
		}
279 7
		return self::MAP_CLASS_TO_NAME[$class];
280
	}
281
}
282