| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | declare(strict_types=1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | namespace BitWasp\Trezor\Bridge\Codec\CallMessage; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use BitWasp\Trezor\Bridge\Exception\InvalidMessageException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use Psr\Http\Message\StreamInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | class HexCodec | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 | 32 |  |     private function intcmp(int $a, int $b): int | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 | 32 |  |         return ($a < $b) ? -1 : (($a > $b) ? 1 : 0); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 | 33 |  |     private function hex2bin(StreamInterface $stream): \Protobuf\Stream | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 | 33 |  |         $hex = $stream->getContents(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 | 33 |  |         if (!ctype_xdigit($hex)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 | 1 |  |             throw new InvalidMessageException("Invalid hex as input"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 | 32 |  |         return \Protobuf\Stream::fromString(pack("H*", $hex)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 26 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 27 | 39 |  |     public function parsePayload(StreamInterface $stream): array | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 29 | 39 |  |         if ($stream->getSize() < 12) { | 
            
                                                                        
                            
            
                                    
            
            
                | 30 | 6 |  |             throw new InvalidMessageException("Malformed data (size too small)"); | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 33 | 33 |  |         $stream = $this->hex2bin($stream); | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |         // relies on php returning the variables in order defined in unpack string | 
            
                                                                        
                            
            
                                    
            
            
                | 36 | 32 |  |         list ($type, $size) = array_values(unpack('n1type/N1size', $stream->read(6))); | 
            
                                                                        
                            
            
                                    
            
            
                | 37 | 32 |  |         $stream->seek(6); | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 39 | 32 |  |         $lCmp = $this->intcmp($stream->getSize() - 6, $size); | 
            
                                                                        
                            
            
                                    
            
            
                | 40 | 32 |  |         if ($lCmp < 0) { | 
            
                                                                        
                            
            
                                    
            
            
                | 41 | 1 |  |             throw new InvalidMessageException("Malformed data (not enough data)"); | 
            
                                                                        
                            
            
                                    
            
            
                | 42 | 31 |  |         } else if ($lCmp > 0) { | 
            
                                                                        
                            
            
                                    
            
            
                | 43 | 1 |  |             throw new InvalidMessageException("Malformed data (too much data)"); | 
            
                                                                        
                            
            
                                    
            
            
                | 44 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 45 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 46 | 30 |  |         return [$type, \Protobuf\Stream::wrap($stream->read($size))]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 | 30 |  |     public function encode(int $messageType, \Protobuf\Message $protobuf): string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 | 30 |  |         $stream = $protobuf->toStream(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 | 30 |  |         return unpack('H*', pack('nN', $messageType, $stream->getSize()) . $stream->getContents())[1]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 54 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 55 |  |  |  |