From a2f1209d39dd42c812e515369ed21e39430048fb Mon Sep 17 00:00:00 2001 From: Eugene Blikh Date: Sat, 16 May 2026 00:22:27 +0300 Subject: [PATCH] json: drop unrecognized enum string names per proto3 spec decode_enum returned the raw input string for unknown enum names, which then propagated through the codec and errored at encode time with "unknown enum value '...'". For repeated and map fields the spec requires *dropping* the element (not substituting 0), so the encoded output should be shorter than the input. decode_enum now returns nil for unrecognized names. The optional / repeated / map call sites in decode_message skip nil values: optional leaves the field unset (encoded as default), repeated compacts the array, map omits the entry. Numeric and known-name inputs are unchanged. Drops 5 entries from test/conformance/known_failures.txt: IgnoreUnknownEnumStringValueIn{Optional,Repeated,RepeatedPart, MapPart,MapValue}. --- runtime/pb/json.lua | 19 +++++++++++++++---- test/conformance/known_failures.txt | 5 ----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/runtime/pb/json.lua b/runtime/pb/json.lua index 456266999c60d54f08baf1dc30fdaa907074184c..ca0931b8167de8da2a18ed4946bd301dd20f668e 100644 --- a/runtime/pb/json.lua +++ b/runtime/pb/json.lua @@ -364,7 +364,10 @@ local function decode_enum(enum_desc, v) local n = enum_desc.by_name[v] if n ~= nil then return n end end - return tonumber(v) or v + -- proto3 JSON: unrecognized integer enum values pass through; unrecognized + -- string names yield nil so the caller can drop the element (repeated/map) + -- or fall back to the field default (singular). + return tonumber(v) end local function decode_field_value(field, v) @@ -518,15 +521,23 @@ decode_message = function(desc, v) if f.kind == 'map' then local m = {} for mk, mv in pairs(jv) do - m[decode_map_key(f.key, mk)] = decode_field_value(f.value, mv) + local dv = decode_field_value(f.value, mv) + if dv ~= nil then + m[decode_map_key(f.key, mk)] = dv + end end out[f.name] = m elseif f.repeated then local arr = {} - for i = 1, #jv do arr[i] = decode_field_value(f, jv[i]) end + local n = 0 + for i = 1, #jv do + local dv = decode_field_value(f, jv[i]) + if dv ~= nil then n = n + 1; arr[n] = dv end + end out[f.name] = arr else - out[f.name] = decode_field_value(f, jv) + local dv = decode_field_value(f, jv) + if dv ~= nil then out[f.name] = dv end end end -- Unknown JSON keys are silently ignored (per spec). diff --git a/test/conformance/known_failures.txt b/test/conformance/known_failures.txt index 81377d55fb2bbe3be55c10d6378407101e1034e4..c97776fcf23eb0cce2a3798e736fe0aeb963899b 100644 --- a/test/conformance/known_failures.txt +++ b/test/conformance/known_failures.txt @@ -19,11 +19,6 @@ # # Re-generate this file after fixes via `just conformance-refresh-failures`. Recommended.Proto3.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput -Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapPart.ProtobufOutput -Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput -Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput -Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput -Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedPart.ProtobufOutput Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator Recommended.Proto3.ProtobufInput.RejectInvalidUtf8.String.MapKey Recommended.Proto3.ProtobufInput.RejectInvalidUtf8.String.MapValue