Skip to content

Commit 03f08ab

Browse files
committed
Fix in Unmarshal function rather than DecodeValue
This preserves backwards compatibility in the unlikely event someone is using an alternative XML unmarshaler that does support unmarshalling into *any.
1 parent 329cb45 commit 03f08ab

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

pgtype/pgtype_default.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,25 @@ func initDefaultMap() {
9191
defaultMap.RegisterType(&Type{Name: "varchar", OID: VarcharOID, Codec: TextCodec{}})
9292
defaultMap.RegisterType(&Type{Name: "xid", OID: XIDOID, Codec: Uint32Codec{}})
9393
defaultMap.RegisterType(&Type{Name: "xid8", OID: XID8OID, Codec: Uint64Codec{}})
94-
defaultMap.RegisterType(&Type{Name: "xml", OID: XMLOID, Codec: &XMLCodec{Marshal: xml.Marshal, Unmarshal: xml.Unmarshal}})
94+
defaultMap.RegisterType(&Type{Name: "xml", OID: XMLOID, Codec: &XMLCodec{
95+
Marshal: xml.Marshal,
96+
// xml.Unmarshal does not support unmarshalling into *any. However, XMLCodec.DecodeValue calls Unmarshal with a
97+
// *any. Wrap xml.Marshal with a function that copies the data into a new byte slice in this case. Not implementing
98+
// directly in XMLCodec.DecodeValue to allow for the unlikely possibility that someone uses an alternative XML
99+
// unmarshaler that does support unmarshalling into *any.
100+
//
101+
// https://github.com/jackc/pgx/issues/2227
102+
// https://github.com/jackc/pgx/pull/2228
103+
Unmarshal: func(data []byte, v any) error {
104+
if v, ok := v.(*any); ok {
105+
dstBuf := make([]byte, len(data))
106+
copy(dstBuf, data)
107+
*v = dstBuf
108+
return nil
109+
}
110+
return xml.Unmarshal(data, v)
111+
},
112+
}})
95113

96114
// Range types
97115
defaultMap.RegisterType(&Type{Name: "daterange", OID: DaterangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[DateOID]}})

pgtype/xml.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ func (c *XMLCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (an
192192
return nil, nil
193193
}
194194

195-
dstBuf := make([]byte, len(src))
196-
copy(dstBuf, src)
197-
return dstBuf, nil
195+
var dst any
196+
err := c.Unmarshal(src, &dst)
197+
return dst, err
198198
}

0 commit comments

Comments
 (0)