Addressed PR comments.

pull/13171/head
Joshua Haberman 3 years ago
parent d80e682a9c
commit b3c91c276b
  1. 59
      upb/decode.c

@ -83,13 +83,13 @@ static const uint8_t desctype_to_mapsize[] = {
8, /* SINT64 */ 8, /* SINT64 */
}; };
static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) | static const unsigned FIXED32_OK_MASK = (1 << UPB_DTYPE_FLOAT) |
(1 << UPB_DTYPE_FIXED32) | (1 << UPB_DTYPE_FIXED32) |
(1 << UPB_DTYPE_SFIXED32); (1 << UPB_DTYPE_SFIXED32);
static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) | static const unsigned FIXED64_OK_MASK = (1 << UPB_DTYPE_DOUBLE) |
(1 << UPB_DTYPE_FIXED64) | (1 << UPB_DTYPE_FIXED64) |
(1 << UPB_DTYPE_SFIXED64); (1 << UPB_DTYPE_SFIXED64);
/* Op: an action to be performed for a wire-type/field-type combination. */ /* Op: an action to be performed for a wire-type/field-type combination. */
#define OP_UNKNOWN -1 #define OP_UNKNOWN -1
@ -175,7 +175,9 @@ typedef union {
static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout); const upb_msglayout *layout);
UPB_NORETURN static void decode_err(upb_decstate *d) { UPB_LONGJMP(d->err, 1); } UPB_NORETURN static const char *decode_err(upb_decstate *d) {
UPB_LONGJMP(d->err, 1);
}
// We don't want to mark this NORETURN, see comment in .h. // We don't want to mark this NORETURN, see comment in .h.
// Unfortunately this code to suppress the warning doesn't appear to be working. // Unfortunately this code to suppress the warning doesn't appear to be working.
@ -251,7 +253,7 @@ static const char *decode_varint64(upb_decstate *d, const char *ptr,
return ptr + 1; return ptr + 1;
} else { } else {
decode_vret res = decode_longvarint64(ptr, byte); decode_vret res = decode_longvarint64(ptr, byte);
if (!res.ptr) decode_err(d); if (!res.ptr) return decode_err(d);
*val = res.val; *val = res.val;
return res.ptr; return res.ptr;
} }
@ -269,7 +271,7 @@ static const char *decode_tag(upb_decstate *d, const char *ptr,
decode_vret res = decode_longvarint64(ptr, byte); decode_vret res = decode_longvarint64(ptr, byte);
ptr = res.ptr; ptr = res.ptr;
*val = res.val; *val = res.val;
if (!ptr || *val > UINT32_MAX || ptr - start > 5) decode_err(d); if (!ptr || *val > UINT32_MAX || ptr - start > 5) return decode_err(d);
return ptr; return ptr;
} }
} }
@ -310,7 +312,7 @@ const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
int overrun) { int overrun) {
ptr = decode_isdonefallback_inl(d, ptr, overrun); ptr = decode_isdonefallback_inl(d, ptr, overrun);
if (ptr == NULL) { if (ptr == NULL) {
decode_err(d); return decode_err(d);
} }
return ptr; return ptr;
} }
@ -321,7 +323,7 @@ static const char *decode_readstr(upb_decstate *d, const char *ptr, int size,
str->data = ptr; str->data = ptr;
} else { } else {
char *data = upb_arena_malloc(&d->arena, size); char *data = upb_arena_malloc(&d->arena, size);
if (!data) decode_err(d); if (!data) return decode_err(d);
memcpy(data, ptr, size); memcpy(data, ptr, size);
str->data = data; str->data = data;
} }
@ -336,11 +338,11 @@ static const char *decode_tosubmsg(upb_decstate *d, const char *ptr,
const upb_msglayout_field *field, int size) { const upb_msglayout_field *field, int size) {
const upb_msglayout *subl = subs[field->submsg_index].submsg; const upb_msglayout *subl = subs[field->submsg_index].submsg;
int saved_delta = decode_pushlimit(d, ptr, size); int saved_delta = decode_pushlimit(d, ptr, size);
if (--d->depth < 0) decode_err(d); if (--d->depth < 0) return decode_err(d);
if (!decode_isdone(d, &ptr)) { if (!decode_isdone(d, &ptr)) {
ptr = decode_msg(d, ptr, submsg, subl); ptr = decode_msg(d, ptr, submsg, subl);
} }
if (d->end_group != DECODE_NOGROUP) decode_err(d); if (d->end_group != DECODE_NOGROUP) return decode_err(d);
decode_poplimit(d, ptr, saved_delta); decode_poplimit(d, ptr, saved_delta);
d->depth++; d->depth++;
return ptr; return ptr;
@ -350,12 +352,12 @@ UPB_FORCEINLINE
static const char *decode_group(upb_decstate *d, const char *ptr, static const char *decode_group(upb_decstate *d, const char *ptr,
upb_msg *submsg, const upb_msglayout *subl, upb_msg *submsg, const upb_msglayout *subl,
uint32_t number) { uint32_t number) {
if (--d->depth < 0) decode_err(d); if (--d->depth < 0) return decode_err(d);
if (decode_isdone(d, &ptr)) { if (decode_isdone(d, &ptr)) {
decode_err(d); return decode_err(d);
} }
ptr = decode_msg(d, ptr, submsg, subl); ptr = decode_msg(d, ptr, submsg, subl);
if (d->end_group != number) decode_err(d); if (d->end_group != number) return decode_err(d);
d->end_group = DECODE_NOGROUP; d->end_group = DECODE_NOGROUP;
d->depth++; d->depth++;
return ptr; return ptr;
@ -384,7 +386,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
} else { } else {
size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype]; size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype];
arr = _upb_array_new(&d->arena, 4, lg2); arr = _upb_array_new(&d->arena, 4, lg2);
if (!arr) decode_err(d); if (!arr) return decode_err(d);
*arrp = arr; *arrp = arr;
} }
@ -425,7 +427,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
int mask = (1 << lg2) - 1; int mask = (1 << lg2) - 1;
size_t count = val->size >> lg2; size_t count = val->size >> lg2;
if ((val->size & mask) != 0) { if ((val->size & mask) != 0) {
decode_err(d); /* Length isn't a round multiple of elem size. */ return decode_err(d); /* Length isn't a round multiple of elem size. */
} }
decode_reserve(d, arr, count); decode_reserve(d, arr, count);
mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
@ -589,7 +591,7 @@ static const upb_msglayout_field *decode_findfield(upb_decstate *d,
} }
} }
for (idx = 0; idx < last; idx++) { for (idx = l->dense_below; idx < last; idx++) {
if (l->fields[idx].number == field_number) { if (l->fields[idx].number == field_number) {
goto found; goto found;
} }
@ -623,13 +625,17 @@ static const char *decode_wireval(upb_decstate *d, const char *ptr,
memcpy(&val->uint32_val, ptr, 4); memcpy(&val->uint32_val, ptr, 4);
val->uint32_val = _upb_be_swap32(val->uint32_val); val->uint32_val = _upb_be_swap32(val->uint32_val);
*op = OP_SCALAR_LG2(2); *op = OP_SCALAR_LG2(2);
if (((1 << field->descriptortype) & fixed32_ok) == 0) *op = OP_UNKNOWN; if (((1 << field->descriptortype) & FIXED32_OK_MASK) == 0) {
*op = OP_UNKNOWN;
}
return ptr + 4; return ptr + 4;
case UPB_WIRE_TYPE_64BIT: case UPB_WIRE_TYPE_64BIT:
memcpy(&val->uint64_val, ptr, 8); memcpy(&val->uint64_val, ptr, 8);
val->uint64_val = _upb_be_swap64(val->uint64_val); val->uint64_val = _upb_be_swap64(val->uint64_val);
*op = OP_SCALAR_LG2(3); *op = OP_SCALAR_LG2(3);
if (((1 << field->descriptortype) & fixed64_ok) == 0) *op = OP_UNKNOWN; if (((1 << field->descriptortype) & FIXED64_OK_MASK) == 0) {
*op = OP_UNKNOWN;
}
return ptr + 8; return ptr + 8;
case UPB_WIRE_TYPE_DELIMITED: { case UPB_WIRE_TYPE_DELIMITED: {
int ndx = field->descriptortype; int ndx = field->descriptortype;
@ -637,7 +643,7 @@ static const char *decode_wireval(upb_decstate *d, const char *ptr,
if (_upb_getmode(field) == _UPB_MODE_ARRAY) ndx += 18; if (_upb_getmode(field) == _UPB_MODE_ARRAY) ndx += 18;
ptr = decode_varint64(d, ptr, &size); ptr = decode_varint64(d, ptr, &size);
if (size >= INT32_MAX || ptr - d->end + (int32_t)size > d->limit) { if (size >= INT32_MAX || ptr - d->end + (int32_t)size > d->limit) {
decode_err(d); /* Length overflow. */ break; /* Length overflow. */
} }
*op = delim_ops[ndx]; *op = delim_ops[ndx];
val->size = size; val->size = size;
@ -649,8 +655,9 @@ static const char *decode_wireval(upb_decstate *d, const char *ptr,
if (field->descriptortype != UPB_DTYPE_GROUP) *op = OP_UNKNOWN; if (field->descriptortype != UPB_DTYPE_GROUP) *op = OP_UNKNOWN;
return ptr; return ptr;
default: default:
decode_err(d); break;
} }
return decode_err(d);
} }
UPB_FORCEINLINE UPB_FORCEINLINE
@ -664,7 +671,7 @@ static const char *decode_known(upb_decstate *d, const char *ptr, upb_msg *msg,
if (UPB_UNLIKELY(mode & _UPB_MODE_IS_EXTENSION)) { if (UPB_UNLIKELY(mode & _UPB_MODE_IS_EXTENSION)) {
const upb_msglayout_ext *ext_layout = (const upb_msglayout_ext*)field; const upb_msglayout_ext *ext_layout = (const upb_msglayout_ext*)field;
upb_msg_ext *ext = _upb_msg_getorcreateext(msg, ext_layout, &d->arena); upb_msg_ext *ext = _upb_msg_getorcreateext(msg, ext_layout, &d->arena);
if (UPB_UNLIKELY(!ext)) decode_err(d); if (UPB_UNLIKELY(!ext)) return decode_err(d);
msg = &ext->data; msg = &ext->data;
subs = &ext->ext->sub; subs = &ext->ext->sub;
} }
@ -685,7 +692,7 @@ UPB_FORCEINLINE
static const char *decode_unknown(upb_decstate *d, const char *ptr, static const char *decode_unknown(upb_decstate *d, const char *ptr,
upb_msg *msg, int field_number, int wire_type, upb_msg *msg, int field_number, int wire_type,
wireval val, const char **field_start) { wireval val, const char **field_start) {
if (field_number == 0) decode_err(d); if (field_number == 0) return decode_err(d);
if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size; if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size;
if (msg) { if (msg) {
if (wire_type == UPB_WIRE_TYPE_START_GROUP) { if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
@ -697,7 +704,7 @@ static const char *decode_unknown(upb_decstate *d, const char *ptr,
} }
if (!_upb_msg_addunknown(msg, *field_start, ptr - *field_start, if (!_upb_msg_addunknown(msg, *field_start, ptr - *field_start,
&d->arena)) { &d->arena)) {
decode_err(d); return decode_err(d);
} }
} else if (wire_type == UPB_WIRE_TYPE_START_GROUP) { } else if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
ptr = decode_group(d, ptr, NULL, NULL, field_number); ptr = decode_group(d, ptr, NULL, NULL, field_number);

Loading…
Cancel
Save