Internal change.

PiperOrigin-RevId: 683782202
pull/18680/head
Xufei Tan 4 months ago committed by Mike Kruskal
parent b51d59e193
commit 49ce8d87b2
  1. 70
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  2. 44
      java/core/src/main/java/com/google/protobuf/TextFormat.java

@ -1616,6 +1616,15 @@ public final class Descriptors {
private final Descriptor extensionScope;
private final boolean isProto3Optional;
private enum Sensitivity {
UNKNOWN,
SENSITIVE,
NOT_SENSITIVE
}
// Caches the result of isSensitive() for performance reasons.
private volatile Sensitivity sensitivity = Sensitivity.UNKNOWN;
// Possibly initialized during cross-linking.
private Type type;
private Descriptor containingType;
@ -1788,6 +1797,67 @@ public final class Descriptors {
file.pool.addSymbol(this);
}
@SuppressWarnings("unchecked") // List<EnumValueDescriptor> guaranteed by protobuf runtime.
private boolean isOptionSensitive(FieldDescriptor field, Object value) {
if (field.getType() == Descriptors.FieldDescriptor.Type.ENUM) {
if (field.isRepeated()) {
for (EnumValueDescriptor v : (List<EnumValueDescriptor>) value) {
if (v.getOptions().getDebugRedact()) {
return true;
}
}
} else {
if (((EnumValueDescriptor) value).getOptions().getDebugRedact()) {
return true;
}
}
} else if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
if (field.isRepeated()) {
for (Message m : (List<Message>) value) {
for (Map.Entry<FieldDescriptor, Object> entry : m.getAllFields().entrySet()) {
if (isOptionSensitive(entry.getKey(), entry.getValue())) {
return true;
}
}
}
} else {
for (Map.Entry<FieldDescriptor, Object> entry :
((Message) value).getAllFields().entrySet()) {
if (isOptionSensitive(entry.getKey(), entry.getValue())) {
return true;
}
}
}
}
return false;
}
// Lazily calculates if the field is marked as sensitive. Is only called upon the first
// access of the isSensitive() method.
boolean isSensitive() {
if (sensitivity == Sensitivity.UNKNOWN) {
// If the field is directly marked with debug_redact=true, then it is sensitive.
synchronized (this) {
if (sensitivity == Sensitivity.UNKNOWN) {
boolean isSensitive = proto.getOptions().getDebugRedact();
if (!isSensitive) {
// Check if the FieldOptions contain any enums that are marked as debug_redact=true,
// either directly or indirectly via a message option.
for (Map.Entry<Descriptors.FieldDescriptor, Object> entry :
proto.getOptions().getAllFields().entrySet()) {
if (isOptionSensitive(entry.getKey(), entry.getValue())) {
isSensitive = true;
break;
}
}
}
sensitivity = isSensitive ? Sensitivity.SENSITIVE : Sensitivity.NOT_SENSITIVE;
}
}
}
return sensitivity == Sensitivity.SENSITIVE;
}
/** See {@link FileDescriptor#resolveAllFeatures}. */
private void resolveAllFeatures() throws DescriptorValidationException {
resolveFeatures(proto.getOptions().getFeatures());

@ -568,51 +568,17 @@ public final class TextFormat {
}
}
private boolean shouldRedactOptionValue(EnumValueDescriptor optionValue) {
if (optionValue.getOptions().hasDebugRedact()) {
return optionValue.getOptions().getDebugRedact();
}
return false;
}
// The criteria for redacting a field is as follows: 1) The enablingSafeDebugFormat printer
// option
// must be on. 2) The field must be marked by a debug_redact=true option, or is marked by an
// option with an enum value that is marked by a debug_redact=true option.
@SuppressWarnings("unchecked") // List<EnumValueDescriptor> guaranteed by protobuf runtime.
// option must be on. 2) The field must be considered "sensitive". A sensitive field can be
// marked as sensitive via two methods: a) via a direct debug_redact=true annotation on the
// field, b) via an enum field marked with debug_redact=true that is within the proto's
// FieldOptions, either directly or indirectly via a message option.
private boolean shouldRedact(final FieldDescriptor field, TextGenerator generator) {
// Skip checking if it's sensitive and potentially reporting it if we don't care about either.
if (!shouldReport(generator.fieldReporterLevel) && !enablingSafeDebugFormat) {
return false;
}
boolean isSensitive = false;
if (field.getOptions().hasDebugRedact() && field.getOptions().getDebugRedact()) {
isSensitive = true;
} else {
// Iterate through every option; if it's an enum, we check each enum value for debug_redact.
for (Map.Entry<Descriptors.FieldDescriptor, Object> entry :
field.getOptions().getAllFields().entrySet()) {
Descriptors.FieldDescriptor option = entry.getKey();
if (option.getType() != Descriptors.FieldDescriptor.Type.ENUM) {
continue;
}
if (option.isRepeated()) {
for (EnumValueDescriptor value : (List<EnumValueDescriptor>) entry.getValue()) {
if (shouldRedactOptionValue(value)) {
isSensitive = true;
break;
}
}
} else {
EnumValueDescriptor optionValue = (EnumValueDescriptor) entry.getValue();
if (shouldRedactOptionValue(optionValue)) {
isSensitive = true;
break;
}
}
}
}
return isSensitive && enablingSafeDebugFormat;
return field.isSensitive() && enablingSafeDebugFormat;
}
private boolean shouldReport(FieldReporterLevel level) {

Loading…
Cancel
Save