Index: third_party/protobuf/ruby/ext/google/protobuf_c/encode_decode.c |
diff --git a/third_party/protobuf/ruby/ext/google/protobuf_c/encode_decode.c b/third_party/protobuf/ruby/ext/google/protobuf_c/encode_decode.c |
index 08c72bccb53c3e95f06ad206202684bd20ed6e93..f6bea50f3966652a93f0ce56b133fa4cd73633ab 100644 |
--- a/third_party/protobuf/ruby/ext/google/protobuf_c/encode_decode.c |
+++ b/third_party/protobuf/ruby/ext/google/protobuf_c/encode_decode.c |
@@ -54,7 +54,7 @@ VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) { |
static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) { |
size_t* hd_ofs = ALLOC(size_t); |
*hd_ofs = ofs; |
- upb_handlers_addcleanup(h, hd_ofs, xfree); |
+ upb_handlers_addcleanup(h, hd_ofs, free); |
return hd_ofs; |
} |
@@ -69,7 +69,7 @@ static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs, |
submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t); |
hd->ofs = ofs; |
hd->md = upb_fielddef_msgsubdef(f); |
- upb_handlers_addcleanup(h, hd, xfree); |
+ upb_handlers_addcleanup(h, hd, free); |
return hd; |
} |
@@ -99,7 +99,7 @@ static const void *newoneofhandlerdata(upb_handlers *h, |
} else { |
hd->md = NULL; |
} |
- upb_handlers_addcleanup(h, hd, xfree); |
+ upb_handlers_addcleanup(h, hd, free); |
return hd; |
} |
@@ -135,7 +135,7 @@ static void* appendstr_handler(void *closure, |
VALUE ary = (VALUE)closure; |
VALUE str = rb_str_new2(""); |
rb_enc_associate(str, kRubyStringUtf8Encoding); |
- RepeatedField_push_native(ary, &str); |
+ RepeatedField_push(ary, str); |
return (void*)str; |
} |
@@ -146,7 +146,7 @@ static void* appendbytes_handler(void *closure, |
VALUE ary = (VALUE)closure; |
VALUE str = rb_str_new2(""); |
rb_enc_associate(str, kRubyString8bitEncoding); |
- RepeatedField_push_native(ary, &str); |
+ RepeatedField_push(ary, str); |
return (void*)str; |
} |
@@ -182,23 +182,6 @@ static size_t stringdata_handler(void* closure, const void* hd, |
return len; |
} |
-static bool stringdata_end_handler(void* closure, const void* hd) { |
- MessageHeader* msg = closure; |
- const size_t *ofs = hd; |
- VALUE rb_str = DEREF(msg, *ofs, VALUE); |
- rb_obj_freeze(rb_str); |
- return true; |
-} |
- |
-static bool appendstring_end_handler(void* closure, const void* hd) { |
- VALUE ary = (VALUE)closure; |
- int size = RepeatedField_size(ary); |
- VALUE* last = RepeatedField_index_native(ary, size - 1); |
- VALUE rb_str = *last; |
- rb_obj_freeze(rb_str); |
- return true; |
-} |
- |
// Appends a submessage to a repeated field (a regular Ruby array for now). |
static void *appendsubmsg_handler(void *closure, const void *hd) { |
VALUE ary = (VALUE)closure; |
@@ -255,54 +238,10 @@ typedef struct { |
// value into the map. |
typedef struct { |
VALUE map; |
- const map_handlerdata_t* handlerdata; |
char key_storage[NATIVE_SLOT_MAX_SIZE]; |
char value_storage[NATIVE_SLOT_MAX_SIZE]; |
} map_parse_frame_t; |
-static void MapParseFrame_mark(void* _self) { |
- map_parse_frame_t* frame = _self; |
- |
- // This shouldn't strictly be necessary since this should be rooted by the |
- // message itself, but it can't hurt. |
- rb_gc_mark(frame->map); |
- |
- native_slot_mark(frame->handlerdata->key_field_type, &frame->key_storage); |
- native_slot_mark(frame->handlerdata->value_field_type, &frame->value_storage); |
-} |
- |
-void MapParseFrame_free(void* self) { |
- xfree(self); |
-} |
- |
-rb_data_type_t MapParseFrame_type = { |
- "MapParseFrame", |
- { MapParseFrame_mark, MapParseFrame_free, NULL }, |
-}; |
- |
-// Array of Ruby objects wrapping map_parse_frame_t. |
-// We don't allow multiple concurrent decodes, so we assume that this global |
-// variable is specific to the "current" decode. |
-VALUE map_parse_frames; |
- |
-static map_parse_frame_t* map_push_frame(VALUE map, |
- const map_handlerdata_t* handlerdata) { |
- map_parse_frame_t* frame = ALLOC(map_parse_frame_t); |
- frame->handlerdata = handlerdata; |
- frame->map = map; |
- native_slot_init(handlerdata->key_field_type, &frame->key_storage); |
- native_slot_init(handlerdata->value_field_type, &frame->value_storage); |
- |
- rb_ary_push(map_parse_frames, |
- TypedData_Wrap_Struct(rb_cObject, &MapParseFrame_type, frame)); |
- |
- return frame; |
-} |
- |
-static void map_pop_frame() { |
- rb_ary_pop(map_parse_frames); |
-} |
- |
// Handler to begin a map entry: allocates a temporary frame. This is the |
// 'startsubmsg' handler on the msgdef that contains the map field. |
static void *startmapentry_handler(void *closure, const void *hd) { |
@@ -310,7 +249,13 @@ static void *startmapentry_handler(void *closure, const void *hd) { |
const map_handlerdata_t* mapdata = hd; |
VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE); |
- return map_push_frame(map_rb, mapdata); |
+ map_parse_frame_t* frame = ALLOC(map_parse_frame_t); |
+ frame->map = map_rb; |
+ |
+ native_slot_init(mapdata->key_field_type, &frame->key_storage); |
+ native_slot_init(mapdata->value_field_type, &frame->value_storage); |
+ |
+ return frame; |
} |
// Handler to end a map entry: inserts the value defined during the message into |
@@ -336,7 +281,7 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) { |
&frame->value_storage); |
Map_index_set(frame->map, key, value); |
- map_pop_frame(); |
+ free(frame); |
return true; |
} |
@@ -415,13 +360,6 @@ static void *oneofbytes_handler(void *closure, |
return (void*)str; |
} |
-static bool oneofstring_end_handler(void* closure, const void* hd) { |
- MessageHeader* msg = closure; |
- const oneof_handlerdata_t *oneofdata = hd; |
- rb_obj_freeze(DEREF(msg, oneofdata->ofs, VALUE)); |
- return true; |
-} |
- |
// Handler for a submessage field in a oneof. |
static void *oneofsubmsg_handler(void *closure, |
const void *hd) { |
@@ -488,7 +426,6 @@ static void add_handlers_for_repeated_field(upb_handlers *h, |
appendbytes_handler : appendstr_handler, |
NULL); |
upb_handlers_setstring(h, f, stringdata_handler, NULL); |
- upb_handlers_setendstr(h, f, appendstring_end_handler, NULL); |
break; |
} |
case UPB_TYPE_MESSAGE: { |
@@ -525,7 +462,6 @@ static void add_handlers_for_singular_field(upb_handlers *h, |
is_bytes ? bytes_handler : str_handler, |
&attr); |
upb_handlers_setstring(h, f, stringdata_handler, &attr); |
- upb_handlers_setendstr(h, f, stringdata_end_handler, &attr); |
upb_handlerattr_uninit(&attr); |
break; |
} |
@@ -548,7 +484,7 @@ static void add_handlers_for_mapfield(upb_handlers* h, |
map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); |
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
- upb_handlers_addcleanup(h, hd, xfree); |
+ upb_handlers_addcleanup(h, hd, free); |
upb_handlerattr_sethandlerdata(&attr, hd); |
upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); |
upb_handlerattr_uninit(&attr); |
@@ -563,7 +499,7 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef, |
map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc); |
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
- upb_handlers_addcleanup(h, hd, xfree); |
+ upb_handlers_addcleanup(h, hd, free); |
upb_handlerattr_sethandlerdata(&attr, hd); |
upb_handlers_setendmsg(h, endmap_handler, &attr); |
@@ -610,7 +546,6 @@ static void add_handlers_for_oneof_field(upb_handlers *h, |
oneofbytes_handler : oneofstr_handler, |
&attr); |
upb_handlers_setstring(h, f, stringdata_handler, NULL); |
- upb_handlers_setendstr(h, f, oneofstring_end_handler, &attr); |
break; |
} |
case UPB_TYPE_MESSAGE: { |
@@ -775,10 +710,6 @@ VALUE Message_decode(VALUE klass, VALUE data) { |
msg_rb = rb_class_new_instance(0, NULL, msgklass); |
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
- // We generally expect this to be clear already, but clear it in case parsing |
- // previously got interrupted somehow. |
- rb_ary_clear(map_parse_frames); |
- |
{ |
const upb_pbdecodermethod* method = msgdef_decodermethod(desc); |
const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); |
@@ -823,10 +754,6 @@ VALUE Message_decode_json(VALUE klass, VALUE data) { |
msg_rb = rb_class_new_instance(0, NULL, msgklass); |
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
- // We generally expect this to be clear already, but clear it in case parsing |
- // previously got interrupted somehow. |
- rb_ary_clear(map_parse_frames); |
- |
{ |
const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc); |
stackenv se; |
@@ -936,13 +863,9 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { |
assert(BUILTIN_TYPE(str) == RUBY_T_STRING); |
- // We should be guaranteed that the string has the correct encoding because |
- // we ensured this at assignment time and then froze the string. |
- if (upb_fielddef_type(f) == UPB_TYPE_STRING) { |
- assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyStringUtf8Encoding); |
- } else { |
- assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyString8bitEncoding); |
- } |
+ // Ensure that the string has the correct encoding. We also check at field-set |
+ // time, but the user may have mutated the string object since then. |
+ native_slot_validate_string_encoding(upb_fielddef_type(f), str); |
upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str), |
&subsink); |