From c4407fb36e71015eaa2fd129d7c9a6554b038eee Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Wed, 12 Oct 2022 19:46:15 -0500 Subject: [PATCH] Prevent infinite loop for driver.Valuer / Codec edge case A `driver.Valuer()` results in a `string` that the `Codec` for the PostgreSQL type doesn't know how to handle. That string is scanned into whatever the default type for that `Codec` is. That new value is encoded. If the new value is the same type as the original type than an infinite loop occured. Check that the types are different. https://github.com/jackc/pgx/issues/1331 --- pgtype/pgtype.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pgtype/pgtype.go b/pgtype/pgtype.go index 6b96eff6..a17c25a3 100644 --- a/pgtype/pgtype.go +++ b/pgtype/pgtype.go @@ -1389,6 +1389,11 @@ func (plan *encodePlanDriverValuer) Encode(value any, buf []byte) (newBuf []byte return nil, err } + // Prevent infinite loop. We can't encode this. See https://github.com/jackc/pgx/issues/1331. + if reflect.TypeOf(value) == reflect.TypeOf(scannedValue) { + return nil, fmt.Errorf("tried to encode %v via encoding to text and scanning but failed due to receiving same type back", value) + } + var err2 error newBuf, err2 = plan.m.Encode(plan.oid, BinaryFormatCode, scannedValue, buf) if err2 != nil {