From 762d06362baa729b73966c8866cdc1dc40b7a058 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 16 Sep 2024 14:45:34 -0400 Subject: [PATCH 1/4] fix: make getters convert uuid to string when calling toObject() and toJSON() Fix #14869 --- lib/schema/uuid.js | 27 ++++++++++++--------------- test/model.populate.test.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/lib/schema/uuid.js b/lib/schema/uuid.js index aa72c42107f..0c64ac07eeb 100644 --- a/lib/schema/uuid.js +++ b/lib/schema/uuid.js @@ -26,19 +26,6 @@ function hex2buffer(hex) { return buff; } -/** - * Helper function to convert the buffer input to a string - * @param {Buffer} buf The buffer to convert to a hex-string - * @returns {String} The buffer as a hex-string - * @api private - */ - -function binary2hex(buf) { - // use buffer built-in function to convert from buffer to hex-string - const hex = buf != null && buf.toString('hex'); - return hex; -} - /** * Convert a String to Binary * @param {String} uuidStr The value to process @@ -67,7 +54,7 @@ function binaryToString(uuidBin) { // i(hasezoey) dont quite know why, but "uuidBin" may sometimes also be the already processed string let hex; if (typeof uuidBin !== 'string' && uuidBin != null) { - hex = binary2hex(uuidBin); + hex = uuidBin != null && uuidBin.toString('hex'); const uuidStr = hex.substring(0, 8) + '-' + hex.substring(8, 8 + 4) + '-' + hex.substring(12, 12 + 4) + '-' + hex.substring(16, 16 + 4) + '-' + hex.substring(20, 20 + 12); return uuidStr; } @@ -90,7 +77,17 @@ function SchemaUUID(key, options) { if (value != null && value.$__ != null) { return value; } - return binaryToString(value); + if (Buffer.isBuffer(value)) { + return binaryToString(value); + } else if (value instanceof Binary) { + if (value instanceof Binary) { + return binaryToString(value.buffer); + } + } else if (utils.isPOJO(value) && value.type === 'Buffer' && Array.isArray(value.data)) { + // Cloned buffers look like `{ type: 'Buffer', data: [5, 224, ...] }` + return binaryToString(Buffer.from(value.data)); + } + return value; }); } diff --git a/test/model.populate.test.js b/test/model.populate.test.js index 7f0fe844eb8..be7933882f1 100644 --- a/test/model.populate.test.js +++ b/test/model.populate.test.js @@ -11131,4 +11131,41 @@ describe('model: populate:', function() { } assert.equal(posts.length, 2); }); + + it('handles converting uuid documents to strings when calling toObject() (gh-14869)', async function() { + const nodeSchema = new Schema({ _id: { type: 'UUID' }, name: 'String' }); + const rootSchema = new Schema({ + _id: { type: 'UUID' }, + status: 'String', + node: [{ type: 'UUID', ref: 'Child' }] + }); + + const Node = db.model('Child', nodeSchema); + const Root = db.model('Parent', rootSchema); + + const node = new Node({ + _id: '65c7953e-c6e9-4c2f-8328-fe2de7df560d', + name: 'test' + }); + await node.save(); + + const root = new Root({ + _id: '05c7953e-c6e9-4c2f-8328-fe2de7df560d', + status: 'ok', + node: [node._id] + }); + await root.save(); + + const foundRoot = await Root.findById(root._id).populate('node'); + + let doc = foundRoot.toJSON({ getters: true }); + assert.strictEqual(doc._id, '05c7953e-c6e9-4c2f-8328-fe2de7df560d'); + assert.strictEqual(doc.node.length, 1); + assert.strictEqual(doc.node[0]._id, '65c7953e-c6e9-4c2f-8328-fe2de7df560d'); + + doc = foundRoot.toObject({ getters: true }); + assert.strictEqual(doc._id, '05c7953e-c6e9-4c2f-8328-fe2de7df560d'); + assert.strictEqual(doc.node.length, 1); + assert.strictEqual(doc.node[0]._id, '65c7953e-c6e9-4c2f-8328-fe2de7df560d'); + }); }); From 5b5f3d822f49908c4e257ee7350880eba9bf0bb2 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 16 Sep 2024 14:48:14 -0400 Subject: [PATCH 2/4] style: fix lint --- lib/schema/uuid.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/schema/uuid.js b/lib/schema/uuid.js index 0c64ac07eeb..cbee764e4ab 100644 --- a/lib/schema/uuid.js +++ b/lib/schema/uuid.js @@ -80,9 +80,9 @@ function SchemaUUID(key, options) { if (Buffer.isBuffer(value)) { return binaryToString(value); } else if (value instanceof Binary) { - if (value instanceof Binary) { - return binaryToString(value.buffer); - } + if (value instanceof Binary) { + return binaryToString(value.buffer); + } } else if (utils.isPOJO(value) && value.type === 'Buffer' && Array.isArray(value.data)) { // Cloned buffers look like `{ type: 'Buffer', data: [5, 224, ...] }` return binaryToString(Buffer.from(value.data)); From 499582a46e8680a9af084e16c5062e786282d6f9 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Tue, 17 Sep 2024 11:18:46 -0400 Subject: [PATCH 3/4] Update lib/schema/uuid.js Co-authored-by: hasezoey --- lib/schema/uuid.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/schema/uuid.js b/lib/schema/uuid.js index cbee764e4ab..37906e3c4f0 100644 --- a/lib/schema/uuid.js +++ b/lib/schema/uuid.js @@ -80,9 +80,7 @@ function SchemaUUID(key, options) { if (Buffer.isBuffer(value)) { return binaryToString(value); } else if (value instanceof Binary) { - if (value instanceof Binary) { - return binaryToString(value.buffer); - } + return binaryToString(value.buffer); } else if (utils.isPOJO(value) && value.type === 'Buffer' && Array.isArray(value.data)) { // Cloned buffers look like `{ type: 'Buffer', data: [5, 224, ...] }` return binaryToString(Buffer.from(value.data)); From 02162ff62d13a23a2785532cabb5c3fbac2abb26 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Tue, 17 Sep 2024 11:18:58 -0400 Subject: [PATCH 4/4] Update lib/schema/uuid.js Co-authored-by: hasezoey --- lib/schema/uuid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/schema/uuid.js b/lib/schema/uuid.js index 37906e3c4f0..1fbfc38654d 100644 --- a/lib/schema/uuid.js +++ b/lib/schema/uuid.js @@ -54,7 +54,7 @@ function binaryToString(uuidBin) { // i(hasezoey) dont quite know why, but "uuidBin" may sometimes also be the already processed string let hex; if (typeof uuidBin !== 'string' && uuidBin != null) { - hex = uuidBin != null && uuidBin.toString('hex'); + hex = uuidBin.toString('hex'); const uuidStr = hex.substring(0, 8) + '-' + hex.substring(8, 8 + 4) + '-' + hex.substring(12, 12 + 4) + '-' + hex.substring(16, 16 + 4) + '-' + hex.substring(20, 20 + 12); return uuidStr; }