From 9fbcf179082b6bf4134881193a8764d816800cfc Mon Sep 17 00:00:00 2001 From: Alexandre Weinberger Date: Mon, 13 Jan 2025 16:28:25 -0300 Subject: [PATCH] read dataTypeID and tableID as unsigned uint (#3347) * read dataTypeID and tableID as unsigned uint this is causing issues in other projects, like https://github.com/sequelize/sequelize/issues/15466 * added tests for oids larger than 2^31 --- packages/pg-protocol/src/buffer-reader.ts | 6 ++++ .../pg-protocol/src/inbound-parser.test.ts | 28 +++++++++++++++++++ packages/pg-protocol/src/parser.ts | 4 +-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/pg-protocol/src/buffer-reader.ts b/packages/pg-protocol/src/buffer-reader.ts index 2305e130c..a1b30b875 100644 --- a/packages/pg-protocol/src/buffer-reader.ts +++ b/packages/pg-protocol/src/buffer-reader.ts @@ -31,6 +31,12 @@ export class BufferReader { return result } + public uint32(): number { + const result = this.buffer.readUInt32BE(this.offset) + this.offset += 4 + return result + } + public string(length: number): string { const result = this.buffer.toString(this.encoding, this.offset, this.offset + length) this.offset += length diff --git a/packages/pg-protocol/src/inbound-parser.test.ts b/packages/pg-protocol/src/inbound-parser.test.ts index 0c905c501..adf5aac66 100644 --- a/packages/pg-protocol/src/inbound-parser.test.ts +++ b/packages/pg-protocol/src/inbound-parser.test.ts @@ -39,6 +39,17 @@ var twoRowBuf = buffers.rowDescription([ }, ]) +var rowWithBigOids = { + name: 'bigoid', + tableID: 3000000001, + attributeNumber: 2, + dataTypeID: 3000000003, + dataTypeSize: 4, + typeModifier: 5, + formatCode: 0, +} +var bigOidDescBuff = buffers.rowDescription([rowWithBigOids]) + var emptyRowFieldBuf = new BufferList().addInt16(0).join(true, 'D') var emptyRowFieldBuf = buffers.dataRow([]) @@ -132,6 +143,22 @@ var expectedTwoRowMessage = { }, ], } +var expectedBigOidMessage = { + name: 'rowDescription', + length: 31, + fieldCount: 1, + fields: [ + { + name: 'bigoid', + tableID: 3000000001, + columnID: 2, + dataTypeID: 3000000003, + dataTypeSize: 4, + dataTypeModifier: 5, + format: 'text', + }, + ], +} var emptyParameterDescriptionBuffer = new BufferList() .addInt16(0) // number of parameters @@ -261,6 +288,7 @@ describe('PgPacketStream', function () { testForMessage(emptyRowDescriptionBuffer, expectedEmptyRowDescriptionMessage) testForMessage(oneRowDescBuff, expectedOneRowMessage) testForMessage(twoRowBuf, expectedTwoRowMessage) + testForMessage(bigOidDescBuff, expectedBigOidMessage) }) describe('parameterDescription messages', function () { diff --git a/packages/pg-protocol/src/parser.ts b/packages/pg-protocol/src/parser.ts index 5a3b0f6be..3b901aefe 100644 --- a/packages/pg-protocol/src/parser.ts +++ b/packages/pg-protocol/src/parser.ts @@ -258,9 +258,9 @@ export class Parser { private parseField(): Field { const name = this.reader.cstring() - const tableID = this.reader.int32() + const tableID = this.reader.uint32() const columnID = this.reader.int16() - const dataTypeID = this.reader.int32() + const dataTypeID = this.reader.uint32() const dataTypeSize = this.reader.int16() const dataTypeModifier = this.reader.int32() const mode = this.reader.int16() === 0 ? 'text' : 'binary'