()
| 95 | } |
| 96 | |
| 97 | func (c *compIO) readCompressedPacket() error { |
| 98 | header, err := c.mc.readNext(7) |
| 99 | if err != nil { |
| 100 | return err |
| 101 | } |
| 102 | _ = header[6] // bounds check hint to compiler; guaranteed by readNext |
| 103 | |
| 104 | // compressed header structure |
| 105 | comprLength := getUint24(header[0:3]) |
| 106 | compressionSequence := header[3] |
| 107 | uncompressedLength := getUint24(header[4:7]) |
| 108 | if debug { |
| 109 | fmt.Printf("uncompress cmplen=%v uncomplen=%v pkt_cmp_seq=%v expected_cmp_seq=%v\n", |
| 110 | comprLength, uncompressedLength, compressionSequence, c.mc.sequence) |
| 111 | } |
| 112 | // Do not return ErrPktSync here. |
| 113 | // Server may return error packet (e.g. 1153 Got a packet bigger than 'max_allowed_packet' bytes) |
| 114 | // before receiving all packets from client. In this case, seqnr is younger than expected. |
| 115 | // NOTE: Both of mariadbclient and mysqlclient do not check seqnr. Only server checks it. |
| 116 | if debug && compressionSequence != c.mc.compressSequence { |
| 117 | fmt.Printf("WARN: unexpected cmpress seq nr: expected %v, got %v", |
| 118 | c.mc.compressSequence, compressionSequence) |
| 119 | } |
| 120 | c.mc.compressSequence = compressionSequence + 1 |
| 121 | |
| 122 | comprData, err := c.mc.readNext(comprLength) |
| 123 | if err != nil { |
| 124 | return err |
| 125 | } |
| 126 | |
| 127 | // if payload is uncompressed, its length will be specified as zero, and its |
| 128 | // true length is contained in comprLength |
| 129 | if uncompressedLength == 0 { |
| 130 | c.buff.Write(comprData) |
| 131 | return nil |
| 132 | } |
| 133 | |
| 134 | // use existing capacity in bytesBuf if possible |
| 135 | c.buff.Grow(uncompressedLength) |
| 136 | nread, err := zDecompress(comprData, &c.buff) |
| 137 | if err != nil { |
| 138 | return err |
| 139 | } |
| 140 | if nread != uncompressedLength { |
| 141 | return fmt.Errorf("invalid compressed packet: uncompressed length in header is %d, actual %d", |
| 142 | uncompressedLength, nread) |
| 143 | } |
| 144 | return nil |
| 145 | } |
| 146 | |
| 147 | const minCompressLength = 150 |
| 148 | const maxPayloadLen = maxPacketSize - 4 |
no test coverage detected