Bugfix for JSON decoding: only check real oneofs for duplicates.

Also fixed upb_msg_whichoneof() to work properly for synthetic
fields, and to be simpler in general.
pull/13171/head
Joshua Haberman 4 years ago
parent 496f638025
commit dd0994d377
  1. 2
      upb/json_decode.c
  2. 25
      upb/reflection.c

@ -910,7 +910,7 @@ static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
return; return;
} }
if (upb_fielddef_containingoneof(f) && if (upb_fielddef_realcontainingoneof(f) &&
upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) { upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
jsondec_err(d, "More than one field for this oneof."); jsondec_err(d, "More than one field for this oneof.");
} }

@ -96,20 +96,17 @@ bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg, const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg,
const upb_oneofdef *o) { const upb_oneofdef *o) {
upb_oneof_iter i; const upb_fielddef *f = upb_oneofdef_field(o, 0);
const upb_fielddef *f; if (upb_oneofdef_issynthetic(o)) {
const upb_msglayout_field *field; UPB_ASSERT(upb_oneofdef_fieldcount(o) == 1);
const upb_msgdef *m = upb_oneofdef_containingtype(o); return upb_msg_has(msg, f) ? f : NULL;
uint32_t oneof_case; } else {
const upb_msglayout_field *field = upb_fielddef_layout(f);
/* This is far from optimal. */ uint32_t oneof_case = _upb_getoneofcase_field(msg, field);
upb_oneof_begin(&i, o); f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL;
if (upb_oneof_done(&i)) return false; UPB_ASSERT((f != NULL) == (oneof_case != 0));
f = upb_oneof_iter_field(&i); return f;
field = upb_fielddef_layout(f); }
oneof_case = _upb_getoneofcase_field(msg, field);
return oneof_case ? upb_msgdef_itof(m, oneof_case) : NULL;
} }
upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) { upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {

Loading…
Cancel
Save