diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index 6951cca0a86c..cf29d133eaf1 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -1766,6 +1766,7 @@ void BinaryAndJsonConformanceSuite::RunJsonTests() { RunJsonTestsForStruct(); RunJsonTestsForValue(); RunJsonTestsForAny(); + RunJsonTestsForUnknownEnumStringValues(); RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNumber", REQUIRED, R"({ @@ -1801,6 +1802,43 @@ void BinaryAndJsonConformanceSuite::RunJsonTests() { ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null"); } +void BinaryAndJsonConformanceSuite::RunJsonTestsForUnknownEnumStringValues() { + // Tests the handling of unknown enum values when encoded as string labels. + // The expected behavior depends on whether unknown fields are ignored: + // * when ignored, the parser should ignore the unknown enum string value. + // * when not ignored, the parser should fail. + struct TestCase { + // Used in the test name. + string enum_location; + // JSON input which will contain the unknown field. + string input_json; + }; + const std::vector test_cases = { + {"InOptionalField", R"json({ + "optional_nested_enum": "UNKNOWN_ENUM_VALUE" + })json"}, + {"InRepeatedField", R"json({ + "repeated_nested_enum": ["UNKNOWN_ENUM_VALUE"] + })json"}, + {"InMapValue", R"json({ + "map_string_nested_enum": {"key": "UNKNOWN_ENUM_VALUE"} + })json"}, + }; + for (const TestCase& test_case : test_cases) { + // Unknown enum string value is a parse failure when not ignoring unknown fields. + ExpectParseFailureForJson( + absl::StrCat("RejectUnknownEnumStringValue", test_case.enum_location), + RECOMMENDED, + test_case.input_json); + // Unknown enum string value is ignored when ignoring unknown fields. + RunValidJsonIgnoreUnknownTest( + absl::StrCat("IgnoreUnknownEnumStringValue", test_case.enum_location), + RECOMMENDED, + test_case.input_json, + ""); + } +} + void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { RunValidJsonTest( "FieldNameInSnakeCase", REQUIRED, diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h index e45a92f89f95..b859921a37f4 100644 --- a/conformance/binary_json_conformance_suite.h +++ b/conformance/binary_json_conformance_suite.h @@ -56,6 +56,7 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { void RunJsonTestsForStruct(); void RunJsonTestsForValue(); void RunJsonTestsForAny(); + void RunJsonTestsForUnknownEnumStringValues(); void RunValidJsonTest(const std::string& test_name, ConformanceLevel level, const std::string& input_json, const std::string& equivalent_text_format); diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index a68602cee968..5af3dfc30082 100644 --- a/conformance/failure_list_cpp.txt +++ b/conformance/failure_list_cpp.txt @@ -17,6 +17,8 @@ Recommended.Proto3.JsonInput.FieldNameDuplicate Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing1 Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing2 Recommended.Proto3.JsonInput.FieldNameNotQuoted +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput Recommended.Proto3.JsonInput.MapFieldValueIsNull Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull diff --git a/conformance/failure_list_php.txt b/conformance/failure_list_php.txt index 3232047aa759..4876e10ba47a 100644 --- a/conformance/failure_list_php.txt +++ b/conformance/failure_list_php.txt @@ -5,6 +5,8 @@ Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator Required.Proto3.JsonInput.DoubleFieldTooSmall diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt index 63c7e8a024cc..284448652f6f 100644 --- a/conformance/failure_list_php_c.txt +++ b/conformance/failure_list_php_c.txt @@ -1,2 +1,4 @@ Recommended.Proto2.JsonInput.FieldNameExtension.Validator +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index e69de29bb2d1..8bbf094293d4 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -0,0 +1,3 @@ +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index 9efb6cf8b77b..de84bd3b0e9a 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -6,3 +6,6 @@ # # TODO(haberman): insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt index 4938202ad70b..3c744391cf75 100644 --- a/conformance/failure_list_ruby.txt +++ b/conformance/failure_list_ruby.txt @@ -27,6 +27,8 @@ Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutp Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput