Skip to content

Commit 20344df

Browse files
committed
Check for overflow on uint16 sizes in pgproto3
1 parent adbb38f commit 20344df

9 files changed

+53
-0
lines changed

pgproto3/bind.go

+11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"encoding/binary"
66
"encoding/hex"
77
"encoding/json"
8+
"errors"
89
"fmt"
10+
"math"
911

1012
"github.com/jackc/pgx/v5/internal/pgio"
1113
)
@@ -116,11 +118,17 @@ func (src *Bind) Encode(dst []byte) ([]byte, error) {
116118
dst = append(dst, src.PreparedStatement...)
117119
dst = append(dst, 0)
118120

121+
if len(src.ParameterFormatCodes) > math.MaxUint16 {
122+
return nil, errors.New("too many parameter format codes")
123+
}
119124
dst = pgio.AppendUint16(dst, uint16(len(src.ParameterFormatCodes)))
120125
for _, fc := range src.ParameterFormatCodes {
121126
dst = pgio.AppendInt16(dst, fc)
122127
}
123128

129+
if len(src.Parameters) > math.MaxUint16 {
130+
return nil, errors.New("too many parameters")
131+
}
124132
dst = pgio.AppendUint16(dst, uint16(len(src.Parameters)))
125133
for _, p := range src.Parameters {
126134
if p == nil {
@@ -132,6 +140,9 @@ func (src *Bind) Encode(dst []byte) ([]byte, error) {
132140
dst = append(dst, p...)
133141
}
134142

143+
if len(src.ResultFormatCodes) > math.MaxUint16 {
144+
return nil, errors.New("too many result format codes")
145+
}
135146
dst = pgio.AppendUint16(dst, uint16(len(src.ResultFormatCodes)))
136147
for _, fc := range src.ResultFormatCodes {
137148
dst = pgio.AppendInt16(dst, fc)

pgproto3/copy_both_response.go

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/binary"
66
"encoding/json"
77
"errors"
8+
"math"
89

910
"github.com/jackc/pgx/v5/internal/pgio"
1011
)
@@ -47,6 +48,9 @@ func (dst *CopyBothResponse) Decode(src []byte) error {
4748
func (src *CopyBothResponse) Encode(dst []byte) ([]byte, error) {
4849
dst, sp := beginMessage(dst, 'W')
4950
dst = append(dst, src.OverallFormat)
51+
if len(src.ColumnFormatCodes) > math.MaxUint16 {
52+
return nil, errors.New("too many column format codes")
53+
}
5054
dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
5155
for _, fc := range src.ColumnFormatCodes {
5256
dst = pgio.AppendUint16(dst, fc)

pgproto3/copy_in_response.go

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/binary"
66
"encoding/json"
77
"errors"
8+
"math"
89

910
"github.com/jackc/pgx/v5/internal/pgio"
1011
)
@@ -48,6 +49,9 @@ func (src *CopyInResponse) Encode(dst []byte) ([]byte, error) {
4849
dst, sp := beginMessage(dst, 'G')
4950

5051
dst = append(dst, src.OverallFormat)
52+
if len(src.ColumnFormatCodes) > math.MaxUint16 {
53+
return nil, errors.New("too many column format codes")
54+
}
5155
dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
5256
for _, fc := range src.ColumnFormatCodes {
5357
dst = pgio.AppendUint16(dst, fc)

pgproto3/copy_out_response.go

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/binary"
66
"encoding/json"
77
"errors"
8+
"math"
89

910
"github.com/jackc/pgx/v5/internal/pgio"
1011
)
@@ -48,6 +49,9 @@ func (src *CopyOutResponse) Encode(dst []byte) ([]byte, error) {
4849

4950
dst = append(dst, src.OverallFormat)
5051

52+
if len(src.ColumnFormatCodes) > math.MaxUint16 {
53+
return nil, errors.New("too many column format codes")
54+
}
5155
dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
5256
for _, fc := range src.ColumnFormatCodes {
5357
dst = pgio.AppendUint16(dst, fc)

pgproto3/data_row.go

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"encoding/binary"
55
"encoding/hex"
66
"encoding/json"
7+
"errors"
8+
"math"
79

810
"github.com/jackc/pgx/v5/internal/pgio"
911
)
@@ -66,6 +68,9 @@ func (dst *DataRow) Decode(src []byte) error {
6668
func (src *DataRow) Encode(dst []byte) ([]byte, error) {
6769
dst, sp := beginMessage(dst, 'D')
6870

71+
if len(src.Values) > math.MaxUint16 {
72+
return nil, errors.New("too many values")
73+
}
6974
dst = pgio.AppendUint16(dst, uint16(len(src.Values)))
7075
for _, v := range src.Values {
7176
if v == nil {

pgproto3/function_call.go

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package pgproto3
22

33
import (
44
"encoding/binary"
5+
"errors"
6+
"math"
57

68
"github.com/jackc/pgx/v5/internal/pgio"
79
)
@@ -74,10 +76,18 @@ func (dst *FunctionCall) Decode(src []byte) error {
7476
func (src *FunctionCall) Encode(dst []byte) ([]byte, error) {
7577
dst, sp := beginMessage(dst, 'F')
7678
dst = pgio.AppendUint32(dst, src.Function)
79+
80+
if len(src.ArgFormatCodes) > math.MaxUint16 {
81+
return nil, errors.New("too many arg format codes")
82+
}
7783
dst = pgio.AppendUint16(dst, uint16(len(src.ArgFormatCodes)))
7884
for _, argFormatCode := range src.ArgFormatCodes {
7985
dst = pgio.AppendUint16(dst, argFormatCode)
8086
}
87+
88+
if len(src.Arguments) > math.MaxUint16 {
89+
return nil, errors.New("too many arguments")
90+
}
8191
dst = pgio.AppendUint16(dst, uint16(len(src.Arguments)))
8292
for _, argument := range src.Arguments {
8393
if argument == nil {

pgproto3/parameter_description.go

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"bytes"
55
"encoding/binary"
66
"encoding/json"
7+
"errors"
8+
"math"
79

810
"github.com/jackc/pgx/v5/internal/pgio"
911
)
@@ -42,6 +44,9 @@ func (dst *ParameterDescription) Decode(src []byte) error {
4244
func (src *ParameterDescription) Encode(dst []byte) ([]byte, error) {
4345
dst, sp := beginMessage(dst, 't')
4446

47+
if len(src.ParameterOIDs) > math.MaxUint16 {
48+
return nil, errors.New("too many parameter oids")
49+
}
4550
dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs)))
4651
for _, oid := range src.ParameterOIDs {
4752
dst = pgio.AppendUint32(dst, oid)

pgproto3/parse.go

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"bytes"
55
"encoding/binary"
66
"encoding/json"
7+
"errors"
8+
"math"
79

810
"github.com/jackc/pgx/v5/internal/pgio"
911
)
@@ -60,6 +62,9 @@ func (src *Parse) Encode(dst []byte) ([]byte, error) {
6062
dst = append(dst, src.Query...)
6163
dst = append(dst, 0)
6264

65+
if len(src.ParameterOIDs) > math.MaxUint16 {
66+
return nil, errors.New("too many parameter oids")
67+
}
6368
dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs)))
6469
for _, oid := range src.ParameterOIDs {
6570
dst = pgio.AppendUint32(dst, oid)

pgproto3/row_description.go

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"bytes"
55
"encoding/binary"
66
"encoding/json"
7+
"errors"
8+
"math"
79

810
"github.com/jackc/pgx/v5/internal/pgio"
911
)
@@ -102,6 +104,9 @@ func (dst *RowDescription) Decode(src []byte) error {
102104
func (src *RowDescription) Encode(dst []byte) ([]byte, error) {
103105
dst, sp := beginMessage(dst, 'T')
104106

107+
if len(src.Fields) > math.MaxUint16 {
108+
return nil, errors.New("too many fields")
109+
}
105110
dst = pgio.AppendUint16(dst, uint16(len(src.Fields)))
106111
for _, fd := range src.Fields {
107112
dst = append(dst, fd.Name...)

0 commit comments

Comments
 (0)