From 14f05364a04fe1ca0bfb278b3407e058c6b5a1ab Mon Sep 17 00:00:00 2001 From: Petr Plenkov Date: Tue, 7 Feb 2023 20:48:01 +0530 Subject: [PATCH] fix: do not allow to extend same field twice to prevent the error (#1784) * do not allow to extend same field twice to prevent the error * Ignore gitpod config * unit test for issue #1783 * using existing test file --- .gitignore | 1 + src/root.js | 4 ++++ tests/comp_import_extend.js | 18 ++++++++++++++++++ tests/comp_import_extend.ts | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 tests/comp_import_extend.js create mode 100644 tests/comp_import_extend.ts diff --git a/.gitignore b/.gitignore index 6220e292e..b284f56d0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ coverage/ sandbox/ .nyc_output dist/ +.gitpod.yml diff --git a/src/root.js b/src/root.js index 3eccddab9..9441a7fc3 100644 --- a/src/root.js +++ b/src/root.js @@ -274,6 +274,10 @@ function tryHandleExtension(root, field) { var extendedType = field.parent.lookup(field.extend); if (extendedType) { var sisterField = new Field(field.fullName, field.id, field.type, field.rule, undefined, field.options); + //do not allow to extend same field twice to prevent the error + if (extendedType.get(sisterField.name)) { + return true; + } sisterField.declaringField = field; field.extensionField = sisterField; extendedType.add(sisterField); diff --git a/tests/comp_import_extend.js b/tests/comp_import_extend.js new file mode 100644 index 000000000..f69450369 --- /dev/null +++ b/tests/comp_import_extend.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var path = require("path"); +var tape = require("tape"); +var protobuf = require("../index"); +// to extend Root +require("../ext/descriptor"); +tape.test("extensions", function (test) { + // load document with extended field imported multiple times + var root = protobuf.loadSync(path.resolve(__dirname, "data/test.proto")); + root.resolveAll(); + // convert to Descriptor Set + var decodedDescriptorSet = root.toDescriptor("proto3"); + // load back from descriptor set + var root2 = protobuf.Root.fromDescriptor(decodedDescriptorSet); + test.pass("should parse and resolve without errors"); + test.end(); +}); diff --git a/tests/comp_import_extend.ts b/tests/comp_import_extend.ts new file mode 100644 index 000000000..e25cd224b --- /dev/null +++ b/tests/comp_import_extend.ts @@ -0,0 +1,35 @@ +import path = require("path"); +import * as tape from "tape"; + +import * as protobuf from "../index"; +import { IFileDescriptorSet } from "../ext/descriptor"; +// to extend Root +require("../ext/descriptor"); + +interface Descriptor { + toDescriptor( + protoVersion: string + ): protobuf.Message & IFileDescriptorSet; + fromDescriptor( + descriptor: IFileDescriptorSet | protobuf.Reader | Uint8Array + ): protobuf.Root; +} + +tape.test("extensions", function (test) { + // load document with extended field imported multiple times + const root = protobuf.loadSync(path.resolve(__dirname, "data/test.proto")); + root.resolveAll(); + + // convert to Descriptor Set + const decodedDescriptorSet = (root as unknown as Descriptor).toDescriptor( + "proto3" + ); + + // load back from descriptor set + const root2 = (protobuf.Root as unknown as Descriptor).fromDescriptor( + decodedDescriptorSet + ); + + test.pass("should parse and resolve without errors"); + test.end(); +});