| Index: third_party/protobuf/ruby/ext/google/protobuf_c/storage.c
|
| diff --git a/third_party/protobuf/ruby/ext/google/protobuf_c/storage.c b/third_party/protobuf/ruby/ext/google/protobuf_c/storage.c
|
| index 3ff2bda6bbc146b0efbd178be6326f8ad9b51ddb..b1f65f413b53d3b46047c83c46a55103d9134596 100644
|
| --- a/third_party/protobuf/ruby/ext/google/protobuf_c/storage.c
|
| +++ b/third_party/protobuf/ruby/ext/google/protobuf_c/storage.c
|
| @@ -57,37 +57,6 @@ size_t native_slot_size(upb_fieldtype_t type) {
|
| }
|
| }
|
|
|
| -static VALUE value_from_default(const upb_fielddef *field) {
|
| - switch (upb_fielddef_type(field)) {
|
| - case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
|
| - case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
|
| - case UPB_TYPE_BOOL:
|
| - return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
|
| - case UPB_TYPE_MESSAGE: return Qnil;
|
| - case UPB_TYPE_ENUM: {
|
| - const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
|
| - int32_t num = upb_fielddef_defaultint32(field);
|
| - const char *label = upb_enumdef_iton(enumdef, num);
|
| - if (label) {
|
| - return ID2SYM(rb_intern(label));
|
| - } else {
|
| - return INT2NUM(num);
|
| - }
|
| - }
|
| - case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
|
| - case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
|
| - case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
|
| - case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
|
| - case UPB_TYPE_STRING:
|
| - case UPB_TYPE_BYTES: {
|
| - size_t size;
|
| - const char *str = upb_fielddef_defaultstr(field, &size);
|
| - return rb_str_new(str, size);
|
| - }
|
| - default: return Qnil;
|
| - }
|
| -}
|
| -
|
| static bool is_ruby_num(VALUE value) {
|
| return (TYPE(value) == T_FLOAT ||
|
| TYPE(value) == T_FIXNUM ||
|
| @@ -117,24 +86,25 @@ void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
|
| }
|
| }
|
|
|
| -VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value) {
|
| - rb_encoding* desired_encoding = (type == UPB_TYPE_STRING) ?
|
| - kRubyStringUtf8Encoding : kRubyString8bitEncoding;
|
| - VALUE desired_encoding_value = rb_enc_from_encoding(desired_encoding);
|
| -
|
| - // Note: this will not duplicate underlying string data unless necessary.
|
| - value = rb_str_encode(value, desired_encoding_value, 0, Qnil);
|
| -
|
| - if (type == UPB_TYPE_STRING &&
|
| - rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
|
| - rb_raise(rb_eEncodingError, "String is invalid UTF-8");
|
| +void native_slot_validate_string_encoding(upb_fieldtype_t type, VALUE value) {
|
| + bool bad_encoding = false;
|
| + rb_encoding* string_encoding = rb_enc_from_index(ENCODING_GET(value));
|
| + if (type == UPB_TYPE_STRING) {
|
| + bad_encoding =
|
| + string_encoding != kRubyStringUtf8Encoding &&
|
| + string_encoding != kRubyStringASCIIEncoding;
|
| + } else {
|
| + bad_encoding =
|
| + string_encoding != kRubyString8bitEncoding;
|
| + }
|
| + // Check that encoding is UTF-8 or ASCII (for string fields) or ASCII-8BIT
|
| + // (for bytes fields).
|
| + if (bad_encoding) {
|
| + rb_raise(rb_eTypeError, "Encoding for '%s' fields must be %s (was %s)",
|
| + (type == UPB_TYPE_STRING) ? "string" : "bytes",
|
| + (type == UPB_TYPE_STRING) ? "UTF-8 or ASCII" : "ASCII-8BIT",
|
| + rb_enc_name(string_encoding));
|
| }
|
| -
|
| - // Ensure the data remains valid. Since we called #encode a moment ago,
|
| - // this does not freeze the string the user assigned.
|
| - rb_obj_freeze(value);
|
| -
|
| - return value;
|
| }
|
|
|
| void native_slot_set(upb_fieldtype_t type, VALUE type_class,
|
| @@ -180,8 +150,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
| if (CLASS_OF(value) != rb_cString) {
|
| rb_raise(rb_eTypeError, "Invalid argument for string field.");
|
| }
|
| -
|
| - DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
|
| + native_slot_validate_string_encoding(type, value);
|
| + DEREF(memory, VALUE) = value;
|
| break;
|
| }
|
| case UPB_TYPE_MESSAGE: {
|
| @@ -567,7 +537,7 @@ VALUE layout_get(MessageLayout* layout,
|
|
|
| if (upb_fielddef_containingoneof(field)) {
|
| if (*oneof_case != upb_fielddef_number(field)) {
|
| - return value_from_default(field);
|
| + return Qnil;
|
| }
|
| return native_slot_get(upb_fielddef_type(field),
|
| field_type_class(field),
|
|
|