From c7e9d935cc5f886f26eca03a0d2d5add2e22f1f6 Mon Sep 17 00:00:00 2001 From: Ram-blip Date: Tue, 7 Jul 2026 16:12:44 +0530 Subject: [PATCH] fix: accept repeated NullValue elements in ProtoJSON --- ext/protojson.js | 6 +++++- tests/api_protojson.js | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ext/protojson.js b/ext/protojson.js index 625cb6d2b..8dea7d961 100644 --- a/ext/protojson.js +++ b/ext/protojson.js @@ -295,7 +295,7 @@ function readField(field, value, options, depth) { throw invalid(field.fullName, value, "expected array"); var arr = [], i = 0; for (; i < value.length; ++i) { - if (value[i] === null && !isValueType(field.resolvedType)) + if (value[i] === null && !isValueType(field.resolvedType) && !isNullValueType(field.resolvedType)) throw invalid(field.fullName, null, "null element"); var el = readSingular(field, value[i], options, depth); if (el !== SKIP) @@ -318,6 +318,10 @@ function isValueType(type) { return type instanceof Type && type.fullName === ".google.protobuf.Value"; } +function isNullValueType(type) { + return type instanceof Enum && type.fullName === ".google.protobuf.NullValue"; +} + function isImplicitDefault(field, value) { if (field.hasPresence || field.repeated || field.map || field.resolvedType instanceof Type) return false; diff --git a/tests/api_protojson.js b/tests/api_protojson.js index e42f4760c..f85c753a2 100644 --- a/tests/api_protojson.js +++ b/tests/api_protojson.js @@ -142,6 +142,7 @@ message NullMsg {\ google.protobuf.Duration duration = 4;\ google.protobuf.StringValue string_wrapper = 5;\ google.protobuf.Value value_msg = 6;\ + repeated google.protobuf.NullValue null_values = 7;\ }", root); return root.resolveAll(); } @@ -536,6 +537,23 @@ tape.test("protojson - rejects null repeated elements and map values", function( test.end(); }); +tape.test("protojson - round trips repeated google.protobuf.NullValue elements", function(test) { + for (var i = 0; i < wktRoots.length; ++i) { + var NullMsg = wktRoots[i].root.lookupType("test.NullMsg"), + label = wktRoots[i].name, + message = protojson.fromJson(NullMsg, { + nullValues: [null, null] + }); + + test.deepEqual(message.nullValues, [0, 0], label + ": parses null elements as NULL_VALUE"); + test.deepEqual(protojson.toJson(NullMsg, message), { + nullValues: [null, null] + }, label + ": emits NULL_VALUE elements as null"); + } + + test.end(); +}); + tape.test("protojson - rejects invalid UTF-16 in well-known values", function(test) { for (var i = 0; i < wktRoots.length; ++i) { var root = wktRoots[i].root,