Sfoglia il codice sorgente

frame: fix header over read

If we make a request with a protocol version which assumes the header
length is 9 but we get a response back with a header of length 8, ensure
we only read 8 bytes of the header.
Chris Bannister 9 anni fa
parent
commit
e79953ea9b
1 ha cambiato i file con 15 aggiunte e 3 eliminazioni
  1. 15 3
      frame.go

+ 15 - 3
frame.go

@@ -339,7 +339,7 @@ type frame interface {
 }
 }
 
 
 func readHeader(r io.Reader, p []byte) (head frameHeader, err error) {
 func readHeader(r io.Reader, p []byte) (head frameHeader, err error) {
-	_, err = io.ReadFull(r, p)
+	_, err = io.ReadFull(r, p[:1])
 	if err != nil {
 	if err != nil {
 		return frameHeader{}, err
 		return frameHeader{}, err
 	}
 	}
@@ -350,6 +350,18 @@ func readHeader(r io.Reader, p []byte) (head frameHeader, err error) {
 		return frameHeader{}, fmt.Errorf("gocql: unsupported response version: %d", version)
 		return frameHeader{}, fmt.Errorf("gocql: unsupported response version: %d", version)
 	}
 	}
 
 
+	headSize := 9
+	if version < protoVersion3 {
+		headSize = 8
+	}
+
+	_, err = io.ReadFull(r, p[1:headSize])
+	if err != nil {
+		return frameHeader{}, err
+	}
+
+	p = p[:headSize]
+
 	head.version = protoVersion(p[0])
 	head.version = protoVersion(p[0])
 	head.flags = p[1]
 	head.flags = p[1]
 
 
@@ -400,9 +412,9 @@ func (f *framer) readFrame(head *frameHeader) error {
 	}
 	}
 
 
 	// assume the underlying reader takes care of timeouts and retries
 	// assume the underlying reader takes care of timeouts and retries
-	_, err := io.ReadFull(f.r, f.rbuf)
+	n, err := io.ReadFull(f.r, f.rbuf)
 	if err != nil {
 	if err != nil {
-		return err
+		return fmt.Errorf("unable to read frame body: read %d/%d bytes: %v", n, head.length, err)
 	}
 	}
 
 
 	if head.flags&flagCompress == flagCompress {
 	if head.flags&flagCompress == flagCompress {