|
|
|
@ -6667,6 +6667,19 @@ static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, |
|
|
|
|
field->mode ^= kUpb_LabelFlags_IsPacked; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (field_modifiers & kUpb_EncodedFieldModifier_FlipValidateUtf8) { |
|
|
|
|
if (field->UPB_PRIVATE(descriptortype) != kUpb_FieldType_Bytes || |
|
|
|
|
!(field->mode & kUpb_LabelFlags_IsAlternate)) { |
|
|
|
|
upb_MdDecoder_ErrorJmp( |
|
|
|
|
&d->base, |
|
|
|
|
"Cannot flip ValidateUtf8 on field %" PRIu32 ", type=%d, mode=%d", |
|
|
|
|
field->number, (int)field->UPB_PRIVATE(descriptortype), |
|
|
|
|
(int)field->mode); |
|
|
|
|
} |
|
|
|
|
field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_String; |
|
|
|
|
field->mode &= ~kUpb_LabelFlags_IsAlternate; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular; |
|
|
|
|
bool required = field_modifiers & kUpb_EncodedFieldModifier_IsRequired; |
|
|
|
|
|
|
|
|
@ -7459,6 +7472,10 @@ const int8_t _kUpb_FromBase92[] = { |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <assert.h> |
|
|
|
|
#include <stddef.h> |
|
|
|
|
#include <stdint.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Must be last.
|
|
|
|
|
|
|
|
|
@ -7652,6 +7669,19 @@ static char* _upb_MtDataEncoder_MaybePutModifiers(upb_MtDataEncoder* e, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (type == kUpb_FieldType_String) { |
|
|
|
|
bool field_validates_utf8 = field_mod & kUpb_FieldModifier_ValidateUtf8; |
|
|
|
|
bool message_validates_utf8 = |
|
|
|
|
in->state.msg_state.msg_modifiers & kUpb_MessageModifier_ValidateUtf8; |
|
|
|
|
if (field_validates_utf8 != message_validates_utf8) { |
|
|
|
|
// Old binaries do not recognize the field modifier. We need the failure
|
|
|
|
|
// mode to be too lax rather than too strict. Our caller should have
|
|
|
|
|
// handled this (see _upb_MessageDef_ValidateUtf8()).
|
|
|
|
|
assert(!message_validates_utf8); |
|
|
|
|
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipValidateUtf8; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (field_mod & kUpb_FieldModifier_IsProto3Singular) { |
|
|
|
|
encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular; |
|
|
|
|
} |
|
|
|
@ -8873,6 +8903,7 @@ upb_ExtensionRange* _upb_ExtensionRanges_New( |
|
|
|
|
|
|
|
|
|
#include <ctype.h> |
|
|
|
|
#include <errno.h> |
|
|
|
|
#include <stdbool.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Must be last.
|
|
|
|
@ -9097,6 +9128,29 @@ bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) { |
|
|
|
|
|
|
|
|
|
int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { return f->layout_index; } |
|
|
|
|
|
|
|
|
|
// begin:google_only
|
|
|
|
|
// static bool _upb_FieldDef_EnforceUtf8Option(const upb_FieldDef* f) {
|
|
|
|
|
// #if defined(UPB_BOOTSTRAP_STAGE0)
|
|
|
|
|
// return true;
|
|
|
|
|
// #else
|
|
|
|
|
// return UPB_DESC(FieldOptions_enforce_utf8)(f->opts);
|
|
|
|
|
// #endif
|
|
|
|
|
// }
|
|
|
|
|
// end:google_only
|
|
|
|
|
|
|
|
|
|
// begin:github_only
|
|
|
|
|
static bool _upb_FieldDef_EnforceUtf8Option(const upb_FieldDef* f) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
// end:github_only
|
|
|
|
|
|
|
|
|
|
bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { |
|
|
|
|
if (upb_FieldDef_Type(f) != kUpb_FieldType_String) return false; |
|
|
|
|
return upb_FileDef_Syntax(upb_FieldDef_File(f)) == kUpb_Syntax_Proto3 |
|
|
|
|
? _upb_FieldDef_EnforceUtf8Option(f) |
|
|
|
|
: false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) { |
|
|
|
|
uint64_t out = f->is_packed ? kUpb_FieldModifier_IsPacked : 0; |
|
|
|
|
|
|
|
|
@ -9117,6 +9171,11 @@ uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) { |
|
|
|
|
if (_upb_FieldDef_IsClosedEnum(f)) { |
|
|
|
|
out |= kUpb_FieldModifier_IsClosedEnum; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (_upb_FieldDef_ValidateUtf8(f)) { |
|
|
|
|
out |= kUpb_FieldModifier_ValidateUtf8; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -11112,15 +11171,37 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool _upb_MessageDef_ValidateUtf8(const upb_MessageDef* m) { |
|
|
|
|
bool has_string = false; |
|
|
|
|
for (int i = 0; i < m->field_count; i++) { |
|
|
|
|
const upb_FieldDef* f = upb_MessageDef_Field(m, i); |
|
|
|
|
// Old binaries do not recognize the field-level "FlipValidateUtf8" wire
|
|
|
|
|
// modifier, so we do not actually have field-level control for old
|
|
|
|
|
// binaries. Given this, we judge that the better failure mode is to be
|
|
|
|
|
// more lax than intended, rather than more strict. To achieve this, we
|
|
|
|
|
// only mark the message with the ValidateUtf8 modifier if *all* fields
|
|
|
|
|
// validate UTF-8.
|
|
|
|
|
if (!_upb_FieldDef_ValidateUtf8(f)) return false; |
|
|
|
|
if (upb_FieldDef_Type(f) == kUpb_FieldType_String) has_string = true; |
|
|
|
|
} |
|
|
|
|
return has_string; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) { |
|
|
|
|
uint64_t out = 0; |
|
|
|
|
|
|
|
|
|
if (upb_FileDef_Syntax(m->file) == kUpb_Syntax_Proto3) { |
|
|
|
|
out |= kUpb_MessageModifier_ValidateUtf8; |
|
|
|
|
out |= kUpb_MessageModifier_DefaultIsPacked; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (_upb_MessageDef_ValidateUtf8(m)) { |
|
|
|
|
out |= kUpb_MessageModifier_ValidateUtf8; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (m->ext_range_count) { |
|
|
|
|
out |= kUpb_MessageModifier_IsExtendable; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|