@@ -318,8 +318,11 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
318318 this , /* run_proto3_tests=*/ true );
319319 BinaryAndJsonConformanceSuiteImpl<TestAllTypesProto2Editions>(
320320 this , /* run_proto3_tests=*/ false );
321- RunDelimitedFieldTests ();
322- RunUnstableTests ();
321+ if (!this ->performance_ ) {
322+ RunDelimitedFieldTests ();
323+ RunUnstableTests ();
324+ RunUtf8ValidationTests ();
325+ }
323326 }
324327}
325328
@@ -389,6 +392,18 @@ void BinaryAndJsonConformanceSuite::RunUnstableTests() {
389392 R"pb( map_string_bytes { key: "foo" value: "barbaz" })pb" );
390393}
391394
395+ void BinaryAndJsonConformanceSuite::RunUtf8ValidationTests () {
396+ ExpectParseFailureForProto<TestAllTypesEdition2023>(
397+ len (133 , " \xA0\xB0\xC0\xD0 " ), " RejectInvalidUtf8.String.Extension" ,
398+ RECOMMENDED);
399+ RunValidBinaryProtobufTest<
400+ TestAllTypesEdition2023>(absl::StrCat (
401+ " AcceptInvalidUtf8.Bytes.Extension" ),
402+ REQUIRED, len (134 , " \xA0\xB0\xC0\xD0 " ),
403+ R"pb( [protobuf_test_messages.editions
404+ .extension_bytes]: "\xA0\xB0\xC0\xD0")pb" );
405+ }
406+
392407void BinaryAndJsonConformanceSuite::RunMessageSetTests () {
393408 RunValidBinaryProtobufTest<TestAllTypesProto2>(
394409 absl::StrCat (" ValidMessageSetEncoding" ), REQUIRED,
@@ -476,10 +491,9 @@ void BinaryAndJsonConformanceSuite::RunMessageSetTests() {
476491}
477492
478493template <typename MessageType>
479- void BinaryAndJsonConformanceSuiteImpl<MessageType>::
480- ExpectParseFailureForProtoWithProtoVersion (const std::string& proto,
481- const std::string& test_name,
482- ConformanceLevel level) {
494+ void BinaryAndJsonConformanceSuite::ExpectParseFailureForProto (
495+ const std::string& proto, const std::string& test_name,
496+ ConformanceLevel level) {
483497 MessageType prototype;
484498 // We don't expect output, but if the program erroneously accepts the protobuf
485499 // we let it send its response as this. We must not leave it unspecified.
@@ -493,22 +507,34 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
493507 absl::StrCat (setting.ConformanceLevelToString (level), " ." ,
494508 setting.GetSyntaxIdentifier (), " .ProtobufInput." , test_name);
495509
496- if (!suite_. RunTest (effective_test_name, request, &response)) {
510+ if (!RunTest (effective_test_name, request, &response)) {
497511 return ;
498512 }
499513
500514 TestStatus test;
501515 test.set_name (effective_test_name);
502516 if (response.result_case () == ConformanceResponse::kParseError ) {
503- suite_. ReportSuccess (test);
517+ ReportSuccess (test);
504518 } else if (response.result_case () == ConformanceResponse::kSkipped ) {
505- suite_.ReportSkip (test, request, response);
519+ ReportSkip (test, request, response);
520+ } else if (response.result_case () == ConformanceResponse::kRuntimeError ) {
521+ test.set_failure_message (
522+ " Should have failed to parse, but raised an error instead." );
523+ ReportFailure (test, level, request, response);
506524 } else {
507525 test.set_failure_message (" Should have failed to parse, but didn't." );
508- suite_. ReportFailure (test, level, request, response);
526+ ReportFailure (test, level, request, response);
509527 }
510528}
511529
530+ template <typename MessageType>
531+ void BinaryAndJsonConformanceSuiteImpl<MessageType>::
532+ ExpectParseFailureForProtoWithProtoVersion (const std::string& proto,
533+ const std::string& test_name,
534+ ConformanceLevel level) {
535+ suite_.ExpectParseFailureForProto <MessageType>(proto, test_name, level);
536+ }
537+
512538// Expect that this precise protobuf will cause a parse error.
513539template <typename MessageType>
514540void BinaryAndJsonConformanceSuiteImpl<MessageType>::ExpectParseFailureForProto(
@@ -1531,6 +1557,29 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::TestUnknownWireType() {
15311557 }
15321558}
15331559
1560+ template <typename MessageType>
1561+ void BinaryAndJsonConformanceSuiteImpl<MessageType>::TestInvalidUtf8String() {
1562+ if (run_proto3_tests_) {
1563+ ExpectParseFailureForProto (len (14 , " \xA0\xB0\xC0\xD0 " ),
1564+ " RejectInvalidUtf8.String.Singular" ,
1565+ RECOMMENDED);
1566+ ExpectParseFailureForProto (len (44 , " \xA0\xB0\xC0\xD0 " ),
1567+ " RejectInvalidUtf8.String.Repeated" ,
1568+ RECOMMENDED);
1569+ ExpectParseFailureForProto (len (113 , " \xA0\xB0\xC0\xD0 " ),
1570+ " RejectInvalidUtf8.String.Oneof" , RECOMMENDED);
1571+ ExpectParseFailureForProto (
1572+ len (69 , absl::StrCat (len (1 , " \xA0\xB0\xC0\xD0 " ), len (2 , " foo" ))),
1573+ " RejectInvalidUtf8.String.MapKey" , RECOMMENDED);
1574+ ExpectParseFailureForProto (
1575+ len (69 , absl::StrCat (len (1 , " foo" ), len (2 , " \xA0\xB0\xC0\xD0 " ))),
1576+ " RejectInvalidUtf8.String.MapValue" , RECOMMENDED);
1577+ } else {
1578+ // TODO - Once conformance tests can express failures that are
1579+ // not expected to be fixed, add proto2 coverage here.
1580+ }
1581+ }
1582+
15341583template <typename MessageType>
15351584void BinaryAndJsonConformanceSuiteImpl<MessageType>::TestOneofMessage() {
15361585 MessageType message;
@@ -1702,6 +1751,7 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::RunAllTests() {
17021751 TestIllegalTags ();
17031752 TestUnmatchedGroup ();
17041753 TestUnknownWireType ();
1754+ TestInvalidUtf8String ();
17051755
17061756 int64_t kInt64Min = -9223372036854775808ULL ;
17071757 int64_t kInt64Max = 9223372036854775807ULL ;
0 commit comments