Fix encoding/decoding for def-to-proto on big-endian systems

In a big-endian system, the 64-bit value of 1 is represented as:

```
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x1
```

However, when `d.int32_val` is used, this truncates this and takes the
first four bytes:

```
0x0 0x0 0x0 0x0
```

As a result, we lose the value of 1 from this truncation and the value
beocmes 0. This doesn't happen in a little-endian system because the 1
is in the lowest memory address, so truncating the value to 32 bits
doesn't change anything.

Previously the DefToProto test was failing on a big-endian system
because this truncation caused the key to be incorrectly set to 0.

We now use the type-specific functions
(e.g. `upb_fielddef_defaultint32`) to do this conversion.

Closes https://github.com/protocolbuffers/upb/issues/442
pull/13171/head
Stan Hu 3 years ago
parent 0cb7f72c02
commit 53250c8504
No known key found for this signature in database
GPG Key ID: 8D3931AD39CC7A20
  1. 40
      upb/def.c

@ -574,17 +574,39 @@ const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) {
upb_msgval upb_fielddef_default(const upb_fielddef *f) {
UPB_ASSERT(!upb_fielddef_issubmsg(f));
upb_msgval ret;
if (upb_fielddef_isstring(f)) {
str_t *str = f->defaultval.str;
if (str) {
ret.str_val.data = str->str;
ret.str_val.size = str->len;
} else {
ret.str_val.size = 0;
switch (upb_fielddef_type(f)) {
case UPB_TYPE_BOOL:
ret.bool_val = upb_fielddef_defaultbool(f);
break;
case UPB_TYPE_INT64:
ret.int64_val = upb_fielddef_defaultint64(f);
break;
case UPB_TYPE_UINT64:
ret.uint64_val = upb_fielddef_defaultuint64(f);
break;
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32:
ret.int32_val = upb_fielddef_defaultint32(f);
break;
case UPB_TYPE_UINT32:
ret.uint32_val = upb_fielddef_defaultuint32(f);
break;
case UPB_TYPE_FLOAT:
ret.float_val = upb_fielddef_defaultfloat(f);
break;
case UPB_TYPE_DOUBLE:
ret.double_val = upb_fielddef_defaultdouble(f);
break;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES: {
ret.str_val.data = upb_fielddef_defaultstr(f, &ret.str_val.size);
break;
}
} else {
memcpy(&ret, &f->defaultval, 8);
default:
UPB_UNREACHABLE();
}
return ret;
}

Loading…
Cancel
Save