Bit-Wasp /
buffertools-php
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace BitWasp\Buffertools; |
||
| 6 | |||
| 7 | use BitWasp\Buffertools\Exceptions\ParserOutOfRange; |
||
| 8 | |||
| 9 | class Parser |
||
| 10 | { |
||
| 11 | /** |
||
| 12 | * @var string |
||
| 13 | */ |
||
| 14 | private $string; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * @var int |
||
| 18 | */ |
||
| 19 | private $size = 0; |
||
| 20 | |||
| 21 | /** |
||
| 22 | * @var int |
||
| 23 | */ |
||
| 24 | private $position = 0; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Instantiate class, optionally taking Buffer or HEX. |
||
| 28 | * |
||
| 29 | * @param null|string|BufferInterface $input |
||
| 30 | */ |
||
| 31 | 164 | public function __construct($input = null) |
|
| 32 | { |
||
| 33 | 164 | if (null === $input) { |
|
| 34 | 14 | $input = ''; |
|
| 35 | } |
||
| 36 | |||
| 37 | 164 | if (is_string($input)) { |
|
| 38 | 24 | $bin = Buffer::hex($input, null)->getBinary(); |
|
| 39 | 142 | } elseif ($input instanceof BufferInterface) { |
|
| 40 | 142 | $bin = $input->getBinary(); |
|
| 41 | } else { |
||
| 42 | throw new \InvalidArgumentException("Invalid argument to Parser"); |
||
| 43 | } |
||
| 44 | |||
| 45 | 164 | $this->string = $bin; |
|
| 46 | 164 | $this->position = 0; |
|
| 47 | 164 | $this->size = strlen($this->string); |
|
| 48 | 164 | } |
|
| 49 | |||
| 50 | /** |
||
| 51 | * Get the position pointer of the parser - ie, how many bytes from 0 |
||
| 52 | * |
||
| 53 | * @return int |
||
| 54 | */ |
||
| 55 | 148 | public function getPosition(): int |
|
| 56 | { |
||
| 57 | 148 | return $this->position; |
|
| 58 | } |
||
| 59 | |||
| 60 | /** |
||
| 61 | * Get the total size of the parser |
||
| 62 | * |
||
| 63 | * @return int |
||
| 64 | */ |
||
| 65 | 16 | public function getSize() |
|
| 66 | { |
||
| 67 | 16 | return $this->size; |
|
| 68 | } |
||
| 69 | |||
| 70 | /** |
||
| 71 | * Parse $bytes bytes from the string, and return the obtained buffer |
||
| 72 | * |
||
| 73 | * @param int $numBytes |
||
| 74 | * @param bool $flipBytes |
||
| 75 | * @return BufferInterface |
||
| 76 | * @throws \Exception |
||
| 77 | */ |
||
| 78 | 146 | public function readBytes(int $numBytes, bool $flipBytes = false): BufferInterface |
|
| 79 | { |
||
| 80 | 146 | $string = substr($this->string, $this->getPosition(), $numBytes); |
|
| 81 | 146 | $length = strlen($string); |
|
| 82 | |||
| 83 | 146 | if ($length === 0) { |
|
| 84 | 4 | throw new ParserOutOfRange('Could not parse string of required length (empty)'); |
|
| 85 | 144 | } elseif ($length < $numBytes) { |
|
| 86 | 2 | throw new ParserOutOfRange('Could not parse string of required length (too short)'); |
|
| 87 | } |
||
| 88 | |||
| 89 | 142 | $this->position += $numBytes; |
|
| 90 | |||
| 91 | 142 | if ($flipBytes) { |
|
| 92 | 2 | $string = Buffertools::flipBytes($string); |
|
| 93 | /** @var string $string */ |
||
| 94 | } |
||
| 95 | |||
| 96 | 142 | return new Buffer($string, $length); |
|
|
0 ignored issues
–
show
|
|||
| 97 | } |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Write $data as $bytes bytes. Can be flipped if needed. |
||
| 101 | * |
||
| 102 | * @param integer $numBytes - number of bytes to write |
||
| 103 | * @param SerializableInterface|BufferInterface|string $data - buffer, serializable or hex |
||
| 104 | * @param bool $flipBytes |
||
| 105 | * @return Parser |
||
| 106 | */ |
||
| 107 | 10 | public function writeBytes(int $numBytes, $data, bool $flipBytes = false): Parser |
|
| 108 | { |
||
| 109 | // Treat $data to ensure it's a buffer, with the correct size |
||
| 110 | 10 | if ($data instanceof SerializableInterface) { |
|
| 111 | $data = $data->getBuffer(); |
||
| 112 | } |
||
| 113 | |||
| 114 | 10 | if (is_string($data)) { |
|
| 115 | // Convert to a buffer |
||
| 116 | $data = Buffer::hex($data, $numBytes); |
||
| 117 | 10 | } else if (!($data instanceof BufferInterface)) { |
|
| 118 | throw new \RuntimeException('Invalid data passed to Parser::writeBytes'); |
||
| 119 | } |
||
| 120 | |||
| 121 | 10 | $this->writeBuffer($numBytes, $data, $flipBytes); |
|
| 122 | |||
| 123 | 10 | return $this; |
|
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Write $data as $bytes bytes. Can be flipped if needed. |
||
| 128 | * |
||
| 129 | * @param integer $numBytes |
||
| 130 | * @param string $data |
||
| 131 | * @param bool $flipBytes |
||
| 132 | * @return Parser |
||
| 133 | */ |
||
| 134 | public function writeRawBinary(int $numBytes, string $data, bool $flipBytes = false): Parser |
||
| 135 | { |
||
| 136 | return $this->writeBuffer($numBytes, new Buffer($data, $numBytes), $flipBytes); |
||
| 137 | } |
||
| 138 | |||
| 139 | /** |
||
| 140 | * @param BufferInterface $buffer |
||
| 141 | * @param bool $flipBytes |
||
| 142 | * @param int $numBytes |
||
| 143 | * @return Parser |
||
| 144 | */ |
||
| 145 | 10 | public function writeBuffer(int $numBytes, BufferInterface $buffer, bool $flipBytes = false): Parser |
|
| 146 | { |
||
| 147 | // only create a new buffer if the size does not match |
||
| 148 | 10 | if ($buffer->getSize() != $numBytes) { |
|
| 149 | 4 | $buffer = new Buffer($buffer->getBinary(), $numBytes); |
|
| 150 | } |
||
| 151 | |||
| 152 | 10 | $this->appendBuffer($buffer, $flipBytes); |
|
| 153 | |||
| 154 | 10 | return $this; |
|
| 155 | } |
||
| 156 | |||
| 157 | /** |
||
| 158 | * @param BufferInterface $buffer |
||
| 159 | * @param bool $flipBytes |
||
| 160 | * @return Parser |
||
| 161 | */ |
||
| 162 | 10 | public function appendBuffer(BufferInterface $buffer, bool $flipBytes = false): Parser |
|
| 163 | { |
||
| 164 | 10 | $this->appendBinary($buffer->getBinary(), $flipBytes); |
|
| 165 | 10 | return $this; |
|
| 166 | } |
||
| 167 | |||
| 168 | /** |
||
| 169 | * @param string $binary |
||
| 170 | * @param bool $flipBytes |
||
| 171 | * @return Parser |
||
| 172 | */ |
||
| 173 | 10 | public function appendBinary(string $binary, bool $flipBytes = false): Parser |
|
| 174 | { |
||
| 175 | 10 | if ($flipBytes) { |
|
| 176 | 4 | $binary = Buffertools::flipBytes($binary); |
|
| 177 | } |
||
| 178 | |||
| 179 | 10 | $this->string .= $binary; |
|
| 180 | 10 | $this->size += strlen($binary); |
|
| 181 | 10 | return $this; |
|
| 182 | } |
||
| 183 | |||
| 184 | /** |
||
| 185 | * Take an array containing serializable objects. |
||
| 186 | * @param SerializableInterface[]|BufferInterface[] $serializable |
||
| 187 | * @return Parser |
||
| 188 | */ |
||
| 189 | 2 | public function writeArray(array $serializable): Parser |
|
| 190 | { |
||
| 191 | 2 | $parser = new Parser(Buffertools::numToVarInt(count($serializable))); |
|
| 192 | 2 | foreach ($serializable as $object) { |
|
| 193 | 2 | if ($object instanceof SerializableInterface) { |
|
| 194 | $object = $object->getBuffer(); |
||
| 195 | } |
||
| 196 | |||
| 197 | 2 | if ($object instanceof BufferInterface) { |
|
| 198 | 2 | $parser->writeBytes($object->getSize(), $object); |
|
| 199 | } else { |
||
| 200 | 2 | throw new \RuntimeException('Input to writeArray must be Buffer[], or SerializableInterface[]'); |
|
| 201 | } |
||
| 202 | } |
||
| 203 | |||
| 204 | 2 | $this->string .= $parser->getBuffer()->getBinary(); |
|
| 205 | 2 | $this->size += $parser->getSize(); |
|
| 206 | |||
| 207 | 2 | return $this; |
|
| 208 | } |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Return the string as a buffer |
||
| 212 | * |
||
| 213 | * @return BufferInterface |
||
| 214 | */ |
||
| 215 | 16 | public function getBuffer(): BufferInterface |
|
| 216 | { |
||
| 217 | 16 | return new Buffer($this->string, null); |
|
| 218 | } |
||
| 219 | } |
||
| 220 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.