mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Add UTF-8 validation documentation and tests for proto2, proto3, and editions for Java Protobuf
PiperOrigin-RevId: 931326656
This commit is contained in:
parent
b721c4cad5
commit
bf5f97bcbb
11 changed files with 1278 additions and 0 deletions
|
|
@ -0,0 +1,180 @@
|
|||
package com.google.protobuf.utf8validation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
import com.google.protobuf.Descriptors.Descriptor;
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
import com.google.protobuf.DynamicMessage;
|
||||
import com.google.protobuf.ExtensionRegistry;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class Utf8ValidationDynamicMessageTest {
|
||||
enum Validates {
|
||||
NEVER,
|
||||
ALWAYS
|
||||
}
|
||||
|
||||
private final Case testCase;
|
||||
|
||||
public Utf8ValidationDynamicMessageTest(Case testCase) {
|
||||
this.testCase = testCase;
|
||||
}
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static List<Object[]> data() {
|
||||
List<Object[]> p = new ArrayList<>();
|
||||
Descriptor d;
|
||||
|
||||
d = Utf8TestProto2.getDescriptor();
|
||||
Case.create(p, d, "file_unset_field_unset", Validates.NEVER);
|
||||
Case.create(p, d, "file_unset_field_enforced", Validates.NEVER);
|
||||
Case.create(p, d, "ext_file_unset_field_unset", Validates.NEVER);
|
||||
Case.create(p, d, "ext_file_unset_field_enforced", Validates.NEVER);
|
||||
|
||||
d = Utf8TestProto2Unchecked.getDescriptor();
|
||||
Case.create(p, d, "file_unchecked_field_unset", Validates.NEVER);
|
||||
Case.create(p, d, "file_unchecked_field_enforced", Validates.NEVER);
|
||||
Case.create(p, d, "ext_file_unchecked_field_unset", Validates.NEVER);
|
||||
Case.create(p, d, "ext_file_unchecked_field_enforced", Validates.NEVER);
|
||||
|
||||
d = Utf8TestProto2Checked.getDescriptor();
|
||||
Case.create(p, d, "file_checked_field_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "file_checked_field_enforced", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_file_checked_field_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_file_checked_field_enforced", Validates.ALWAYS);
|
||||
|
||||
d = Utf8TestProto3.getDescriptor();
|
||||
Case.create(p, d, "file_unset_field_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "file_unset_field_enforced", Validates.ALWAYS);
|
||||
|
||||
d = Utf8TestProto3Unchecked.getDescriptor();
|
||||
Case.create(p, d, "file_unchecked_field_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "file_unchecked_field_enforced", Validates.ALWAYS);
|
||||
|
||||
d = Utf8TestProto3Checked.getDescriptor();
|
||||
Case.create(p, d, "file_checked_field_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "file_checked_field_enforced", Validates.ALWAYS);
|
||||
|
||||
d = Utf8TestEdition2023.getDescriptor();
|
||||
Case.create(p, d, "global_unset_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_unset_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_unset_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_verify_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_verify_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_verify_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_none_java_unset", Validates.NEVER);
|
||||
Case.create(p, d, "global_none_java_default", Validates.NEVER);
|
||||
Case.create(p, d, "global_none_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_unset_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_unset_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_unset_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_verify_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_verify_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_verify_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_none_java_unset", Validates.NEVER);
|
||||
Case.create(p, d, "ext_global_none_java_default", Validates.NEVER);
|
||||
Case.create(p, d, "ext_global_none_java_verify", Validates.ALWAYS);
|
||||
|
||||
d = Utf8TestEdition2024.getDescriptor();
|
||||
Case.create(p, d, "global_unset_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_unset_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_unset_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_verify_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_verify_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_verify_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "global_none_java_unset", Validates.NEVER);
|
||||
Case.create(p, d, "global_none_java_default", Validates.NEVER);
|
||||
Case.create(p, d, "global_none_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_unset_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_unset_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_unset_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_verify_java_unset", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_verify_java_default", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_verify_java_verify", Validates.ALWAYS);
|
||||
Case.create(p, d, "ext_global_none_java_unset", Validates.NEVER);
|
||||
Case.create(p, d, "ext_global_none_java_default", Validates.NEVER);
|
||||
Case.create(p, d, "ext_global_none_java_verify", Validates.ALWAYS);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
FieldDescriptor field = testCase.getFieldDescriptor();
|
||||
|
||||
byte[] serializedPayload = buildSerialized(field.getNumber());
|
||||
|
||||
ExtensionRegistry registry = ExtensionRegistry.newInstance();
|
||||
if (field.isExtension()) {
|
||||
registry.add(field);
|
||||
}
|
||||
|
||||
if (testCase.expectedToValidate()) {
|
||||
assertThrows(
|
||||
InvalidProtocolBufferException.class,
|
||||
() -> DynamicMessage.parseFrom(testCase.descriptor, serializedPayload, registry));
|
||||
} else {
|
||||
DynamicMessage msg =
|
||||
DynamicMessage.parseFrom(testCase.descriptor, serializedPayload, registry);
|
||||
assertTrue(msg.hasField(field));
|
||||
assertEquals("\uFFFD\uFFFD", msg.getField(field));
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] buildSerialized(int fieldNumber) throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
CodedOutputStream codedOut = CodedOutputStream.newInstance(out);
|
||||
codedOut.writeByteArray(fieldNumber, new byte[] {(byte) 0xC0, (byte) 0x80});
|
||||
codedOut.flush();
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
private static class Case {
|
||||
final Descriptor descriptor;
|
||||
final String fieldName;
|
||||
final Validates expected;
|
||||
|
||||
static void create(
|
||||
List<Object[]> params, Descriptor descriptor, String fieldName, Validates expected) {
|
||||
params.add(new Object[] {new Case(descriptor, fieldName, expected)});
|
||||
}
|
||||
|
||||
private Case(Descriptor descriptor, String fieldName, Validates expected) {
|
||||
this.descriptor = descriptor;
|
||||
this.fieldName = fieldName;
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s#%s-->%s",
|
||||
descriptor.getName(),
|
||||
fieldName,
|
||||
expected == Validates.ALWAYS ? "validates" : "doesNotValidate");
|
||||
}
|
||||
|
||||
FieldDescriptor getFieldDescriptor() {
|
||||
FieldDescriptor fieldDescriptor = descriptor.findFieldByName(fieldName);
|
||||
if (fieldDescriptor == null) {
|
||||
fieldDescriptor = descriptor.getFile().findExtensionByName(fieldName);
|
||||
}
|
||||
return fieldDescriptor;
|
||||
}
|
||||
|
||||
boolean expectedToValidate() {
|
||||
return expected == Validates.ALWAYS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,751 @@
|
|||
package com.google.protobuf.utf8validation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
import com.google.protobuf.ExtensionLite;
|
||||
import com.google.protobuf.ExtensionRegistryLite;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.MessageLite;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class Utf8ValidationGeneratedMessageTest {
|
||||
private static final boolean isLite =
|
||||
true
|
||||
|
||||
// BEGIN FULL-RUNTIME
|
||||
&& false
|
||||
|
||||
// END FULL-RUNTIME
|
||||
;
|
||||
|
||||
enum Validates {
|
||||
NEVER,
|
||||
ALWAYS,
|
||||
FULL_RUNTIME_ONLY
|
||||
}
|
||||
|
||||
private final Case<?> testCase;
|
||||
|
||||
public Utf8ValidationGeneratedMessageTest(Case<?> testCase) {
|
||||
this.testCase = testCase;
|
||||
}
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static List<Case<?>> data() throws Exception {
|
||||
List<Case<?>> params = new ArrayList<>();
|
||||
|
||||
addProto2(params);
|
||||
addProto3(params);
|
||||
addEditions2023(params);
|
||||
addEditions2024(params);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
private static void addProto2(List<Case<?>> params) {
|
||||
// java_string_check_utf8: {unset, false, true}
|
||||
// x enforce_utf8: {unset, false, true}
|
||||
// x {regular, extension}
|
||||
// TODO: should be 18 once our test proto is on the allowlist for
|
||||
// enforce_utf8=false
|
||||
final int casesToAdd = 12;
|
||||
final int casesBefore = params.size();
|
||||
|
||||
// java_string_check_utf8: unset
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=unset enforce_utf8=unset",
|
||||
Utf8TestProto2.FILE_UNSET_FIELD_UNSET_FIELD_NUMBER,
|
||||
Utf8TestProto2::parseFrom,
|
||||
Utf8TestProto2::hasFileUnsetFieldUnset,
|
||||
Utf8TestProto2::getFileUnsetFieldUnset,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=unset enforce_utf8=true",
|
||||
Utf8TestProto2.FILE_UNSET_FIELD_ENFORCED_FIELD_NUMBER,
|
||||
Utf8TestProto2::parseFrom,
|
||||
Utf8TestProto2::hasFileUnsetFieldEnforced,
|
||||
Utf8TestProto2::getFileUnsetFieldEnforced,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=unset enforce_utf8=unset extension",
|
||||
Utf8TestProto2Proto.extFileUnsetFieldUnset,
|
||||
Utf8TestProto2::parseFrom,
|
||||
Utf8TestProto2::hasExtension,
|
||||
Utf8TestProto2::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=unset enforce_utf8=true extension",
|
||||
Utf8TestProto2Proto.extFileUnsetFieldEnforced,
|
||||
Utf8TestProto2::parseFrom,
|
||||
Utf8TestProto2::hasExtension,
|
||||
Utf8TestProto2::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
// java_string_check_utf8: false
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=false enforce_utf8=unset",
|
||||
Utf8TestProto2Unchecked.FILE_UNCHECKED_FIELD_UNSET_FIELD_NUMBER,
|
||||
Utf8TestProto2Unchecked::parseFrom,
|
||||
Utf8TestProto2Unchecked::hasFileUncheckedFieldUnset,
|
||||
Utf8TestProto2Unchecked::getFileUncheckedFieldUnset,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=false enforce_utf8=true",
|
||||
Utf8TestProto2Unchecked.FILE_UNCHECKED_FIELD_ENFORCED_FIELD_NUMBER,
|
||||
Utf8TestProto2Unchecked::parseFrom,
|
||||
Utf8TestProto2Unchecked::hasFileUncheckedFieldEnforced,
|
||||
Utf8TestProto2Unchecked::getFileUncheckedFieldEnforced,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=false enforce_utf8=unset extension",
|
||||
Utf8TestProto2UncheckedProto.extFileUncheckedFieldUnset,
|
||||
Utf8TestProto2Unchecked::parseFrom,
|
||||
Utf8TestProto2Unchecked::hasExtension,
|
||||
Utf8TestProto2Unchecked::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=false enforce_utf8=true extension",
|
||||
Utf8TestProto2UncheckedProto.extFileUncheckedFieldEnforced,
|
||||
Utf8TestProto2Unchecked::parseFrom,
|
||||
Utf8TestProto2Unchecked::hasExtension,
|
||||
Utf8TestProto2Unchecked::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
// java_string_check_utf8: true
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=true enforce_utf8=unset",
|
||||
Utf8TestProto2Checked.FILE_CHECKED_FIELD_UNSET_FIELD_NUMBER,
|
||||
Utf8TestProto2Checked::parseFrom,
|
||||
Utf8TestProto2Checked::hasFileCheckedFieldUnset,
|
||||
Utf8TestProto2Checked::getFileCheckedFieldUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=true enforce_utf8=true",
|
||||
Utf8TestProto2Checked.FILE_CHECKED_FIELD_ENFORCED_FIELD_NUMBER,
|
||||
Utf8TestProto2Checked::parseFrom,
|
||||
Utf8TestProto2Checked::hasFileCheckedFieldEnforced,
|
||||
Utf8TestProto2Checked::getFileCheckedFieldEnforced,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=true enforce_utf8=unset extension",
|
||||
Utf8TestProto2CheckedProto.extFileCheckedFieldUnset,
|
||||
Utf8TestProto2Checked::parseFrom,
|
||||
Utf8TestProto2Checked::hasExtension,
|
||||
Utf8TestProto2Checked::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto2 java_string_check_utf8=true enforce_utf8=true extension",
|
||||
Utf8TestProto2CheckedProto.extFileCheckedFieldEnforced,
|
||||
Utf8TestProto2Checked::parseFrom,
|
||||
Utf8TestProto2Checked::hasExtension,
|
||||
Utf8TestProto2Checked::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
if (casesBefore + casesToAdd != params.size()) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addProto3(List<Case<?>> params) {
|
||||
// java_string_check_utf8: {unset, false, true}
|
||||
// x enforce_utf8: {unset, false, true}
|
||||
// No extensions for proto3.
|
||||
// TODO: should be 9 once our test proto is on the allowlist for
|
||||
// enforce_utf8=false
|
||||
final int casesToAdd = 6;
|
||||
final int casesBefore = params.size();
|
||||
|
||||
// java_string_check_utf8: unset
|
||||
Case.create(
|
||||
params,
|
||||
"proto3 java_string_check_utf8=unset enforce_utf8=unset",
|
||||
Utf8TestProto3.FILE_UNSET_FIELD_UNSET_FIELD_NUMBER,
|
||||
Utf8TestProto3::parseFrom,
|
||||
Utf8TestProto3::hasFileUnsetFieldUnset,
|
||||
Utf8TestProto3::getFileUnsetFieldUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto3 java_string_check_utf8=unset enforce_utf8=true",
|
||||
Utf8TestProto3.FILE_UNSET_FIELD_ENFORCED_FIELD_NUMBER,
|
||||
Utf8TestProto3::parseFrom,
|
||||
Utf8TestProto3::hasFileUnsetFieldEnforced,
|
||||
Utf8TestProto3::getFileUnsetFieldEnforced,
|
||||
Validates.ALWAYS);
|
||||
|
||||
// java_string_check_utf8: false
|
||||
Case.create(
|
||||
params,
|
||||
"proto3 java_string_check_utf8=false enforce_utf8=unset",
|
||||
Utf8TestProto3Unchecked.FILE_UNCHECKED_FIELD_UNSET_FIELD_NUMBER,
|
||||
Utf8TestProto3Unchecked::parseFrom,
|
||||
Utf8TestProto3Unchecked::hasFileUncheckedFieldUnset,
|
||||
Utf8TestProto3Unchecked::getFileUncheckedFieldUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto3 java_string_check_utf8=false enforce_utf8=true",
|
||||
Utf8TestProto3Unchecked.FILE_UNCHECKED_FIELD_ENFORCED_FIELD_NUMBER,
|
||||
Utf8TestProto3Unchecked::parseFrom,
|
||||
Utf8TestProto3Unchecked::hasFileUncheckedFieldEnforced,
|
||||
Utf8TestProto3Unchecked::getFileUncheckedFieldEnforced,
|
||||
Validates.ALWAYS);
|
||||
|
||||
// java_string_check_utf8: true
|
||||
Case.create(
|
||||
params,
|
||||
"proto3 java_string_check_utf8=true enforce_utf8=unset",
|
||||
Utf8TestProto3Checked.FILE_CHECKED_FIELD_UNSET_FIELD_NUMBER,
|
||||
Utf8TestProto3Checked::parseFrom,
|
||||
Utf8TestProto3Checked::hasFileCheckedFieldUnset,
|
||||
Utf8TestProto3Checked::getFileCheckedFieldUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"proto3 java_string_check_utf8=true enforce_utf8=true",
|
||||
Utf8TestProto3Checked.FILE_CHECKED_FIELD_ENFORCED_FIELD_NUMBER,
|
||||
Utf8TestProto3Checked::parseFrom,
|
||||
Utf8TestProto3Checked::hasFileCheckedFieldEnforced,
|
||||
Utf8TestProto3Checked::getFileCheckedFieldEnforced,
|
||||
Validates.ALWAYS);
|
||||
if (casesBefore + casesToAdd != params.size()) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addEditions2023(List<Case<?>> params) {
|
||||
// features.utf8_validation: {unset, verify, none}
|
||||
// x features.(pb.java).utf8_validation: {unset, default, verify}
|
||||
// x {regular, extension}
|
||||
final int casesToAdd = 18;
|
||||
final int casesBefore = params.size();
|
||||
|
||||
// features.utf8_validation: unset
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=unset",
|
||||
Utf8TestEdition2023.GLOBAL_UNSET_JAVA_UNSET_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalUnsetJavaUnset,
|
||||
Utf8TestEdition2023::getGlobalUnsetJavaUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT",
|
||||
Utf8TestEdition2023.GLOBAL_UNSET_JAVA_DEFAULT_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalUnsetJavaDefault,
|
||||
Utf8TestEdition2023::getGlobalUnsetJavaDefault,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY",
|
||||
Utf8TestEdition2023.GLOBAL_UNSET_JAVA_VERIFY_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalUnsetJavaVerify,
|
||||
Utf8TestEdition2023::getGlobalUnsetJavaVerify,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=unset"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalUnsetJavaUnset,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalUnsetJavaDefault,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalUnsetJavaVerify,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
// features.utf8_validation: verify
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset",
|
||||
Utf8TestEdition2023.GLOBAL_VERIFY_JAVA_UNSET_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalVerifyJavaUnset,
|
||||
Utf8TestEdition2023::getGlobalVerifyJavaUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT",
|
||||
Utf8TestEdition2023.GLOBAL_VERIFY_JAVA_DEFAULT_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalVerifyJavaDefault,
|
||||
Utf8TestEdition2023::getGlobalVerifyJavaDefault,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY",
|
||||
Utf8TestEdition2023.GLOBAL_VERIFY_JAVA_VERIFY_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalVerifyJavaVerify,
|
||||
Utf8TestEdition2023::getGlobalVerifyJavaVerify,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalVerifyJavaUnset,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalVerifyJavaDefault,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalVerifyJavaVerify,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
// features.utf8_validation: none
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset",
|
||||
Utf8TestEdition2023.GLOBAL_NONE_JAVA_UNSET_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalNoneJavaUnset,
|
||||
Utf8TestEdition2023::getGlobalNoneJavaUnset,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT",
|
||||
Utf8TestEdition2023.GLOBAL_NONE_JAVA_DEFAULT_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalNoneJavaDefault,
|
||||
Utf8TestEdition2023::getGlobalNoneJavaDefault,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY",
|
||||
Utf8TestEdition2023.GLOBAL_NONE_JAVA_VERIFY_FIELD_NUMBER,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasGlobalNoneJavaVerify,
|
||||
Utf8TestEdition2023::getGlobalNoneJavaVerify,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalNoneJavaUnset,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalNoneJavaDefault,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY"
|
||||
+ " extension",
|
||||
Utf8TestEdition2023Proto.extGlobalNoneJavaVerify,
|
||||
Utf8TestEdition2023::parseFrom,
|
||||
Utf8TestEdition2023::hasExtension,
|
||||
Utf8TestEdition2023::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
if (casesBefore + casesToAdd != params.size()) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addEditions2024(List<Case<?>> params) {
|
||||
// features.utf8_validation: {unset, verify, none}
|
||||
// x features.(pb.java).utf8_validation: {unset, default, verify}
|
||||
// x {regular, extension}
|
||||
final int casesToAdd = 18;
|
||||
final int casesBefore = params.size();
|
||||
|
||||
// features.utf8_validation: unset
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=unset",
|
||||
Utf8TestEdition2024.GLOBAL_UNSET_JAVA_UNSET_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalUnsetJavaUnset,
|
||||
Utf8TestEdition2024::getGlobalUnsetJavaUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT",
|
||||
Utf8TestEdition2024.GLOBAL_UNSET_JAVA_DEFAULT_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalUnsetJavaDefault,
|
||||
Utf8TestEdition2024::getGlobalUnsetJavaDefault,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY",
|
||||
Utf8TestEdition2024.GLOBAL_UNSET_JAVA_VERIFY_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalUnsetJavaVerify,
|
||||
Utf8TestEdition2024::getGlobalUnsetJavaVerify,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=unset"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalUnsetJavaUnset,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalUnsetJavaDefault,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalUnsetJavaVerify,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
// features.utf8_validation: verify
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset",
|
||||
Utf8TestEdition2024.GLOBAL_VERIFY_JAVA_UNSET_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalVerifyJavaUnset,
|
||||
Utf8TestEdition2024::getGlobalVerifyJavaUnset,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT",
|
||||
Utf8TestEdition2024.GLOBAL_VERIFY_JAVA_DEFAULT_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalVerifyJavaDefault,
|
||||
Utf8TestEdition2024::getGlobalVerifyJavaDefault,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY",
|
||||
Utf8TestEdition2024.GLOBAL_VERIFY_JAVA_VERIFY_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalVerifyJavaVerify,
|
||||
Utf8TestEdition2024::getGlobalVerifyJavaVerify,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalVerifyJavaUnset,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalVerifyJavaDefault,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalVerifyJavaVerify,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
// features.utf8_validation: none
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset",
|
||||
Utf8TestEdition2024.GLOBAL_NONE_JAVA_UNSET_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalNoneJavaUnset,
|
||||
Utf8TestEdition2024::getGlobalNoneJavaUnset,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT",
|
||||
Utf8TestEdition2024.GLOBAL_NONE_JAVA_DEFAULT_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalNoneJavaDefault,
|
||||
Utf8TestEdition2024::getGlobalNoneJavaDefault,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY",
|
||||
Utf8TestEdition2024.GLOBAL_NONE_JAVA_VERIFY_FIELD_NUMBER,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasGlobalNoneJavaVerify,
|
||||
Utf8TestEdition2024::getGlobalNoneJavaVerify,
|
||||
Validates.ALWAYS);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalNoneJavaUnset,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalNoneJavaDefault,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.NEVER);
|
||||
|
||||
Case.create(
|
||||
params,
|
||||
"edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY"
|
||||
+ " extension",
|
||||
Utf8TestEdition2024Proto.extGlobalNoneJavaVerify,
|
||||
Utf8TestEdition2024::parseFrom,
|
||||
Utf8TestEdition2024::hasExtension,
|
||||
Utf8TestEdition2024::getExtension,
|
||||
Validates.FULL_RUNTIME_ONLY);
|
||||
|
||||
if (casesBefore + casesToAdd != params.size()) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratedMessageUtf8Validation() throws Exception {
|
||||
byte[] serializedPayload = buildSerialized(testCase.fieldNumber);
|
||||
|
||||
if (testCase.expectedToValidate()) {
|
||||
assertThrows(InvalidProtocolBufferException.class, () -> testCase.parse(serializedPayload));
|
||||
} else {
|
||||
MessageLite msg = testCase.parse(serializedPayload);
|
||||
assertTrue(testCase.has(msg));
|
||||
assertEquals("\uFFFD\uFFFD", testCase.get(msg));
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] buildSerialized(int fieldNumber) throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
CodedOutputStream codedOut = CodedOutputStream.newInstance(out);
|
||||
codedOut.writeByteArray(fieldNumber, new byte[] {(byte) 0xC0, (byte) 0x80});
|
||||
codedOut.flush();
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
private interface MessageParser<T extends MessageLite> {
|
||||
T parse(byte[] data, ExtensionRegistryLite registry) throws InvalidProtocolBufferException;
|
||||
}
|
||||
|
||||
private static class Case<T extends MessageLite> {
|
||||
private final String label;
|
||||
private final int fieldNumber;
|
||||
private final ExtensionRegistryLite registry;
|
||||
private final MessageParser<T> parser;
|
||||
private final Predicate<T> hazzer;
|
||||
private final Function<T, String> getter;
|
||||
private final Validates expected;
|
||||
|
||||
static <T extends MessageLite> void create(
|
||||
List<Case<?>> params,
|
||||
String syntax,
|
||||
int fieldNumber,
|
||||
MessageParser<T> parser,
|
||||
Predicate<T> hazzer,
|
||||
Function<T, String> getter,
|
||||
Validates expected) {
|
||||
params.add(
|
||||
new Case<T>(
|
||||
syntax,
|
||||
ExtensionRegistryLite.getEmptyRegistry(),
|
||||
fieldNumber,
|
||||
parser,
|
||||
hazzer,
|
||||
getter,
|
||||
expected));
|
||||
}
|
||||
|
||||
static <T extends MessageLite> void create(
|
||||
List<Case<?>> params,
|
||||
String label,
|
||||
ExtensionLite<T, String> extensionDescriptor,
|
||||
MessageParser<T> parser,
|
||||
BiFunction<? super T, ExtensionLite<T, String>, Boolean> hazzer,
|
||||
BiFunction<? super T, ExtensionLite<T, String>, String> getter,
|
||||
Validates expected) {
|
||||
ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
|
||||
registry.add(extensionDescriptor);
|
||||
params.add(
|
||||
new Case<T>(
|
||||
label,
|
||||
registry,
|
||||
extensionDescriptor.getNumber(),
|
||||
parser,
|
||||
(T msg) -> hazzer.apply(msg, extensionDescriptor),
|
||||
(T msg) -> getter.apply(msg, extensionDescriptor),
|
||||
expected));
|
||||
}
|
||||
|
||||
private Case(
|
||||
String label,
|
||||
ExtensionRegistryLite registry,
|
||||
int fieldNumber,
|
||||
MessageParser<T> parser,
|
||||
Predicate<T> hazzer,
|
||||
Function<T, String> getter,
|
||||
Validates expected) {
|
||||
this.label = label;
|
||||
this.registry = registry;
|
||||
this.fieldNumber = fieldNumber;
|
||||
this.parser = parser;
|
||||
this.hazzer = hazzer;
|
||||
this.getter = getter;
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s-->%s", label, expectedToValidate() ? "validates" : "doesNotValidate");
|
||||
}
|
||||
|
||||
T parse(byte[] data) throws InvalidProtocolBufferException {
|
||||
return parser.parse(data, registry);
|
||||
}
|
||||
|
||||
boolean expectedToValidate() {
|
||||
return expected == Validates.ALWAYS || (!isLite && expected == Validates.FULL_RUNTIME_ONLY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param msg must be of type {@code T} or test will fail anyway.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
boolean has(MessageLite msg) {
|
||||
return hazzer.test((T) msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param msg must be of type {@code T} or test will fail anyway.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
String get(MessageLite msg) {
|
||||
return getter.apply((T) msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Remove code enclosed by "BEGIN FULL-RUNTIME" and "END FULL-RUNTIME" to
|
||||
# create the lite-only version of a test file.
|
||||
|
||||
BEGIN {
|
||||
in_full_runtime = 0;
|
||||
}
|
||||
|
||||
/BEGIN FULL-RUNTIME/ {
|
||||
in_full_runtime = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
/END FULL-RUNTIME/ {
|
||||
in_full_runtime = 0;
|
||||
next;
|
||||
}
|
||||
|
||||
in_full_runtime {
|
||||
# Skip full runtime code path.
|
||||
next;
|
||||
}
|
||||
|
||||
{
|
||||
print;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
edition = "2023";
|
||||
|
||||
package utf8validation.edition2023;
|
||||
|
||||
import "google/protobuf/java_features.proto";
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
option java_outer_classname = "Utf8TestEdition2023Proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
// Naming convention for test fields:
|
||||
// global_[features.utf8_validation state {unset, verify,
|
||||
// none}]_java_[features.(pb.java).utf8_validation state {unset, verify,
|
||||
// default}]
|
||||
message Utf8TestEdition2023 {
|
||||
// Regular fields
|
||||
string global_unset_java_unset = 1;
|
||||
|
||||
string global_unset_java_default = 2
|
||||
[features.(pb.java).utf8_validation = DEFAULT];
|
||||
|
||||
string global_unset_java_verify = 3
|
||||
[features.(pb.java).utf8_validation = VERIFY];
|
||||
|
||||
string global_verify_java_unset = 4 [features.utf8_validation = VERIFY];
|
||||
|
||||
string global_verify_java_default = 5 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string global_verify_java_verify = 6 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
|
||||
string global_none_java_unset = 7 [features.utf8_validation = NONE];
|
||||
|
||||
string global_none_java_default = 8 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string global_none_java_verify = 9 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
|
||||
extensions 100 to 200;
|
||||
}
|
||||
|
||||
extend Utf8TestEdition2023 {
|
||||
string ext_global_unset_java_unset = 101;
|
||||
|
||||
string ext_global_unset_java_default = 102
|
||||
[features.(pb.java).utf8_validation = DEFAULT];
|
||||
|
||||
string ext_global_unset_java_verify = 103
|
||||
[features.(pb.java).utf8_validation = VERIFY];
|
||||
|
||||
string ext_global_verify_java_unset = 104 [features.utf8_validation = VERIFY];
|
||||
|
||||
string ext_global_verify_java_default = 105 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string ext_global_verify_java_verify = 106 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
|
||||
string ext_global_none_java_unset = 107 [features.utf8_validation = NONE];
|
||||
|
||||
string ext_global_none_java_default = 108 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string ext_global_none_java_verify = 109 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
|
||||
edition = "2024";
|
||||
|
||||
package utf8validation.edition2024;
|
||||
|
||||
import "google/protobuf/java_features.proto";
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
|
||||
// Naming convention for test fields:
|
||||
// global_[features.utf8_validation state {unset, verify,
|
||||
// none}]_java_[features.(pb.java).utf8_validation state {unset, verify,
|
||||
// default}]
|
||||
message Utf8TestEdition2024 {
|
||||
// Regular fields
|
||||
string global_unset_java_unset = 1;
|
||||
|
||||
string global_unset_java_default = 2
|
||||
[features.(pb.java).utf8_validation = DEFAULT];
|
||||
|
||||
string global_unset_java_verify = 3
|
||||
[features.(pb.java).utf8_validation = VERIFY];
|
||||
|
||||
string global_verify_java_unset = 4 [features.utf8_validation = VERIFY];
|
||||
|
||||
string global_verify_java_default = 5 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string global_verify_java_verify = 6 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
|
||||
string global_none_java_unset = 7 [features.utf8_validation = NONE];
|
||||
|
||||
string global_none_java_default = 8 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string global_none_java_verify = 9 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
|
||||
extensions 100 to 200;
|
||||
}
|
||||
|
||||
extend Utf8TestEdition2024 {
|
||||
string ext_global_unset_java_unset = 101;
|
||||
|
||||
string ext_global_unset_java_default = 102
|
||||
[features.(pb.java).utf8_validation = DEFAULT];
|
||||
|
||||
string ext_global_unset_java_verify = 103
|
||||
[features.(pb.java).utf8_validation = VERIFY];
|
||||
|
||||
string ext_global_verify_java_unset = 104 [features.utf8_validation = VERIFY];
|
||||
|
||||
string ext_global_verify_java_default = 105 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string ext_global_verify_java_verify = 106 [
|
||||
features.utf8_validation = VERIFY,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
|
||||
string ext_global_none_java_unset = 107 [features.utf8_validation = NONE];
|
||||
|
||||
string ext_global_none_java_default = 108 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = DEFAULT
|
||||
];
|
||||
|
||||
string ext_global_none_java_verify = 109 [
|
||||
features.utf8_validation = NONE,
|
||||
features.(pb.java).utf8_validation = VERIFY
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
syntax = "proto2";
|
||||
|
||||
package utf8validation.proto2;
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
option java_outer_classname = "Utf8TestProto2Proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
// Naming convention for test fields:
|
||||
// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8
|
||||
// state {unset, enforced}]
|
||||
message Utf8TestProto2 {
|
||||
optional string file_unset_field_unset = 1;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string file_unset_field_unenforced = 2 [enforce_utf8 = false];
|
||||
|
||||
optional string file_unset_field_enforced = 3 [enforce_utf8 = true];
|
||||
|
||||
extensions 100 to 200;
|
||||
}
|
||||
|
||||
extend Utf8TestProto2 {
|
||||
optional string ext_file_unset_field_unset = 100;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string ext_file_unset_field_unenforced = 101 [enforce_utf8 =
|
||||
// false];
|
||||
|
||||
optional string ext_file_unset_field_enforced = 102 [enforce_utf8 = true];
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
syntax = "proto2";
|
||||
|
||||
package utf8validation.proto2;
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
option java_outer_classname = "Utf8TestProto2CheckedProto";
|
||||
option java_multiple_files = true;
|
||||
option java_string_check_utf8 = true;
|
||||
|
||||
// Naming convention for test fields:
|
||||
// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8
|
||||
// state {unset, enforced}]
|
||||
message Utf8TestProto2Checked {
|
||||
optional string file_checked_field_unset = 1;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string file_checked_field_unenforced = 2 [enforce_utf8 = false];
|
||||
|
||||
optional string file_checked_field_enforced = 3 [enforce_utf8 = true];
|
||||
|
||||
extensions 100 to 200;
|
||||
}
|
||||
|
||||
extend Utf8TestProto2Checked {
|
||||
optional string ext_file_checked_field_unset = 100;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string ext_file_checked_field_unenforced = 101 [enforce_utf8 =
|
||||
// false];
|
||||
|
||||
optional string ext_file_checked_field_enforced = 102 [enforce_utf8 = true];
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
syntax = "proto2";
|
||||
|
||||
package utf8validation.proto2;
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
option java_outer_classname = "Utf8TestProto2UncheckedProto";
|
||||
option java_multiple_files = true;
|
||||
option java_string_check_utf8 = false;
|
||||
|
||||
// Naming convention for test fields:
|
||||
// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8
|
||||
// state {unset, enforced}]
|
||||
message Utf8TestProto2Unchecked {
|
||||
optional string file_unchecked_field_unset = 1;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string file_unchecked_field_unenforced = 2 [enforce_utf8 = false];
|
||||
|
||||
optional string file_unchecked_field_enforced = 3 [enforce_utf8 = true];
|
||||
|
||||
extensions 100 to 200;
|
||||
}
|
||||
|
||||
extend Utf8TestProto2Unchecked {
|
||||
optional string ext_file_unchecked_field_unset = 100;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string ext_file_unchecked_field_unenforced = 101 [enforce_utf8 =
|
||||
// false];
|
||||
|
||||
optional string ext_file_unchecked_field_enforced = 102 [enforce_utf8 = true];
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package utf8validation.proto3;
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
option java_outer_classname = "Utf8TestProto3Proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
// Naming convention for test fields:
|
||||
// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8
|
||||
// state {unset, enforced}]
|
||||
message Utf8TestProto3 {
|
||||
optional string file_unset_field_unset = 1;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string file_unset_field_unenforced = 2 [enforce_utf8 = false];
|
||||
|
||||
optional string file_unset_field_enforced = 3 [enforce_utf8 = true];
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package utf8validation.proto3;
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
option java_outer_classname = "Utf8TestProto3CheckedProto";
|
||||
option java_multiple_files = true;
|
||||
option java_string_check_utf8 = true;
|
||||
|
||||
// Naming convention for test fields:
|
||||
// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8
|
||||
// state {unset, enforced}]
|
||||
message Utf8TestProto3Checked {
|
||||
optional string file_checked_field_unset = 1;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string file_checked_field_unenforced = 2 [enforce_utf8 = false];
|
||||
|
||||
optional string file_checked_field_enforced = 3 [enforce_utf8 = true];
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package utf8validation.proto3;
|
||||
|
||||
option java_package = "com.google.protobuf.utf8validation";
|
||||
option java_outer_classname = "Utf8TestProto3UncheckedProto";
|
||||
option java_multiple_files = true;
|
||||
option java_string_check_utf8 = false;
|
||||
|
||||
// Naming convention for test fields:
|
||||
// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8
|
||||
// state {unset, enforced}]
|
||||
message Utf8TestProto3Unchecked {
|
||||
optional string file_unchecked_field_unset = 1;
|
||||
|
||||
// TODO: Enable once allowlist entry is built into protoc.
|
||||
// optional string file_unchecked_field_unenforced = 2 [enforce_utf8 = false];
|
||||
|
||||
optional string file_unchecked_field_enforced = 3 [enforce_utf8 = true];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue