@@ -3026,12 +3026,70 @@ void TextFormat::Printer::PrintUnknownFields(
3026
3026
}
3027
3027
}
3028
3028
3029
+ // Traverse the tree of field options and check if any of them are sensitive.
3030
+ // We check for sensitive enum values in the options and in the fields of the
3031
+ // message-type options, recursively.
3032
+ TextFormat::RedactionState TextFormat::IsOptionSensitive (
3033
+ const Message& opts, const Reflection* reflection,
3034
+ const FieldDescriptor* option) {
3035
+ if (option->type () == FieldDescriptor::TYPE_ENUM) {
3036
+ auto count =
3037
+ option->is_repeated () ? reflection->FieldSize (opts, option) : 1 ;
3038
+ for (auto i = 0 ; i < count; i++) {
3039
+ int enum_val = option->is_repeated ()
3040
+ ? reflection->GetRepeatedEnumValue (opts, option, i)
3041
+ : reflection->GetEnumValue (opts, option);
3042
+ const EnumValueDescriptor* option_value =
3043
+ option->enum_type ()->FindValueByNumber (enum_val);
3044
+ if (option_value->options ().debug_redact ()) {
3045
+ return TextFormat::RedactionState{true , false };
3046
+ }
3047
+ }
3048
+ } else if (option->cpp_type () == FieldDescriptor::CPPTYPE_MESSAGE) {
3049
+ auto count =
3050
+ option->is_repeated () ? reflection->FieldSize (opts, option) : 1 ;
3051
+ for (auto i = 0 ; i < count; i++) {
3052
+ const Message& sub_message =
3053
+ option->is_repeated ()
3054
+ ? reflection->GetRepeatedMessage (opts, option, i)
3055
+ : reflection->GetMessage (opts, option);
3056
+ const Reflection* sub_reflection = sub_message.GetReflection ();
3057
+ std::vector<const FieldDescriptor*> message_fields;
3058
+ sub_reflection->ListFields (sub_message, &message_fields);
3059
+ for (const FieldDescriptor* message_field : message_fields) {
3060
+ auto result = TextFormat::IsOptionSensitive (sub_message, sub_reflection,
3061
+ message_field);
3062
+ if (result.redact ) {
3063
+ return result;
3064
+ }
3065
+ }
3066
+ }
3067
+ }
3068
+ return TextFormat::RedactionState{false , false };
3069
+ }
3070
+
3071
+ TextFormat::RedactionState TextFormat::GetRedactionState (
3072
+ const FieldDescriptor* field) {
3073
+ auto options = field->options ();
3074
+ auto state = TextFormat::RedactionState{options.debug_redact (), false };
3075
+ std::vector<const FieldDescriptor*> field_options;
3076
+ const Reflection* reflection = options.GetReflection ();
3077
+ reflection->ListFields (options, &field_options);
3078
+ for (const FieldDescriptor* option : field_options) {
3079
+ auto result = TextFormat::IsOptionSensitive (options, reflection, option);
3080
+ state = TextFormat::RedactionState{state.redact || result.redact ,
3081
+ state.report || result.report };
3082
+ }
3083
+ return state;
3084
+ }
3029
3085
bool TextFormat::Printer::TryRedactFieldValue (
3030
3086
const Message& message, const FieldDescriptor* field,
3031
3087
BaseTextGenerator* generator, bool insert_value_separator) const {
3032
- RedactionState redaction_state = field->options ().debug_redact ()
3033
- ? RedactionState{true , false }
3034
- : RedactionState{false , false };
3088
+ TextFormat::RedactionState redaction_state =
3089
+ field->file ()->pool ()->MemoizeProjection (
3090
+ field, [](const FieldDescriptor* field) {
3091
+ return TextFormat::GetRedactionState (field);
3092
+ });
3035
3093
if (redaction_state.redact ) {
3036
3094
if (redact_debug_string_) {
3037
3095
IncrementRedactedFieldCounter ();
@@ -3051,7 +3109,6 @@ bool TextFormat::Printer::TryRedactFieldValue(
3051
3109
}
3052
3110
return false ;
3053
3111
}
3054
-
3055
3112
} // namespace protobuf
3056
3113
} // namespace google
3057
3114
0 commit comments