From 9999fe8943dec64d8da20f9cf2e8b6265947648f Mon Sep 17 00:00:00 2001 From: Pratik Dulal Date: Mon, 3 Aug 2026 13:02:10 +0545 Subject: [PATCH] fix(pg-protocol): read ParameterDescription type OIDs as unsigned parseField() already reads dataTypeID as uint32 for RowDescription (with a regression test covering OIDs above 2^31-1), but parseParameterDescriptionMessage() was still using the signed int32 reader for the same kind of value, so custom extension types with a high OID would come back negative in ParameterDescriptionMessage.dataTypeIDs. --- packages/pg-protocol/src/inbound-parser.test.ts | 10 ++++++++++ packages/pg-protocol/src/parser.ts | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/pg-protocol/src/inbound-parser.test.ts b/packages/pg-protocol/src/inbound-parser.test.ts index 285f4bf2b..8687194c3 100644 --- a/packages/pg-protocol/src/inbound-parser.test.ts +++ b/packages/pg-protocol/src/inbound-parser.test.ts @@ -161,6 +161,8 @@ const oneParameterDescBuf = buffers.parameterDescription([1111]) const twoParameterDescBuf = buffers.parameterDescription([2222, 3333]) +const bigOidParameterDescBuf = buffers.parameterDescription([3000000003]) + const expectedEmptyParameterDescriptionMessage = { name: 'parameterDescription', length: 6, @@ -182,6 +184,13 @@ const expectedTwoParameterMessage = { dataTypeIDs: [2222, 3333], } +const expectedBigOidParameterMessage = { + name: 'parameterDescription', + length: 10, + parameterCount: 1, + dataTypeIDs: [3000000003], +} + const testForMessage = function (buffer: Buffer, expectedMessage: any) { it('receives and parses ' + expectedMessage.name, async () => { const messages = await parseBuffers([buffer]) @@ -288,6 +297,7 @@ describe('PgPacketStream', function () { testForMessage(emptyParameterDescriptionBuffer, expectedEmptyParameterDescriptionMessage) testForMessage(oneParameterDescBuf, expectedOneParameterMessage) testForMessage(twoParameterDescBuf, expectedTwoParameterMessage) + testForMessage(bigOidParameterDescBuf, expectedBigOidParameterMessage) }) describe('parsing rows', function () { diff --git a/packages/pg-protocol/src/parser.ts b/packages/pg-protocol/src/parser.ts index 3d8ce80c7..df48ca4a1 100644 --- a/packages/pg-protocol/src/parser.ts +++ b/packages/pg-protocol/src/parser.ts @@ -300,7 +300,8 @@ const parseParameterDescriptionMessage = (reader: BufferReader) => { const parameterCount = reader.int16() const message = new ParameterDescriptionMessage(LATEINIT_LENGTH, parameterCount) for (let i = 0; i < parameterCount; i++) { - message.dataTypeIDs[i] = reader.int32() + // OIDs are unsigned, same as dataTypeID in parseField above + message.dataTypeIDs[i] = reader.uint32() } return message }