Skip to content

Commit

Permalink
Merge pull request #5562 from planetscale/sa-fix-preparedstatements
Browse files Browse the repository at this point in the history
Fix prepared statement buffer overwriting bug
  • Loading branch information
sougou authored Dec 13, 2019
2 parents e140145 + 93e0b21 commit e7f6f68
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
14 changes: 14 additions & 0 deletions go/mysql/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,17 @@ func readLenEncStringAsBytes(data []byte, pos int) ([]byte, int, bool) {
}
return data[pos : pos+s], pos + s, true
}

func readLenEncStringAsBytesCopy(data []byte, pos int) ([]byte, int, bool) {
size, pos, ok := readLenEncInt(data, pos)
if !ok {
return nil, 0, false
}
s := int(size)
if pos+s-1 >= len(data) {
return nil, 0, false
}
result := make([]byte, size)
copy(result, data[pos:pos+s])
return result, pos + s, true
}
18 changes: 18 additions & 0 deletions go/mysql/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,24 @@ func TestEncString(t *testing.T) {
t.Errorf("readLenEncStringAsBytes returned ok=true for empty value %v", test.value)
}

// Check successful decoding as bytes.
gotbcopy, posCopy, ok := readLenEncStringAsBytesCopy(test.lenEncoded, 0)
if !ok || string(gotb) != test.value || pos != len(test.lenEncoded) {
t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", gotbcopy, posCopy, ok, test.value, len(test.lenEncoded), true)
}

// Check failed decoding as bytes with shorter data.
_, _, ok = readLenEncStringAsBytesCopy(test.lenEncoded[:len(test.lenEncoded)-1], 0)
if ok {
t.Errorf("readLenEncStringAsBytes returned ok=true for shorter value %v", test.value)
}

// Check failed decoding as bytes with no data.
_, _, ok = readLenEncStringAsBytesCopy([]byte{}, 0)
if ok {
t.Errorf("readLenEncStringAsBytes returned ok=true for empty value %v", test.value)
}

// null encoded tests.

// Check successful encoding.
Expand Down
4 changes: 2 additions & 2 deletions go/mysql/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func (c *Conn) parseRow(data []byte, fields []*querypb.Field) ([]sqltypes.Value,
}
var s []byte
var ok bool
s, pos, ok = readLenEncStringAsBytes(data, pos)
s, pos, ok = readLenEncStringAsBytesCopy(data, pos)
if !ok {
return nil, NewSQLError(CRMalformedPacket, SSUnknownSQLState, "decoding string failed")
}
Expand Down Expand Up @@ -823,7 +823,7 @@ func (c *Conn) parseStmtArgs(data []byte, typ querypb.Type, pos int) (sqltypes.V
}
case sqltypes.Decimal, sqltypes.Text, sqltypes.Blob, sqltypes.VarChar, sqltypes.VarBinary, sqltypes.Char,
sqltypes.Bit, sqltypes.Enum, sqltypes.Set, sqltypes.Geometry, sqltypes.Binary, sqltypes.TypeJSON:
val, pos, ok := readLenEncStringAsBytes(data, pos)
val, pos, ok := readLenEncStringAsBytesCopy(data, pos)
return sqltypes.MakeTrusted(sqltypes.VarBinary, val), pos, ok
default:
return sqltypes.NULL, pos, false
Expand Down

0 comments on commit e7f6f68

Please sign in to comment.