PHP: Fix in upb for 32-bit platforms.

pull/8000/head
Joshua Haberman 4 years ago
parent f5ab3b166c
commit 314ce3c8a0
  1. 33
      php/ext/google/protobuf/php-upb.c
  2. 26
      php/ext/google/protobuf/php-upb.h

@ -761,7 +761,8 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
int ndx = field->descriptortype;
if (_upb_isrepeated(field)) ndx += 18;
ptr = decode_varint32(d, ptr, &val.size);
if (val.size >= INT32_MAX || ptr - d->end + val.size > d->limit) {
if (val.size >= INT32_MAX ||
ptr - d->end + (int32_t)val.size > d->limit) {
decode_err(d); /* Length overflow. */
}
op = delim_ops[ndx];
@ -1301,7 +1302,7 @@ static const size_t overhead = sizeof(upb_msg_internal);
static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
ptrdiff_t size = sizeof(upb_msg_internal);
return UPB_PTR_AT(msg, -size, upb_msg_internal);
return (upb_msg_internal*)((char*)msg - size);
}
upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) {
@ -1401,13 +1402,16 @@ void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
int elem_size_lg2, upb_arena *arena) {
upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
size_t elem = arr->len;
char *data;
if (!arr) return false;
if (!arr || !_upb_array_resize(arr, elem + 1, arena)) return false;
size_t elems = arr->len;
data = _upb_array_ptr(arr);
memcpy(data + (elem << elem_size_lg2), value, 1 << elem_size_lg2);
if (!_upb_array_resize(arr, elems + 1, arena)) {
return false;
}
char *data = _upb_array_ptr(arr);
memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);
return true;
}
@ -5337,10 +5341,14 @@ static const upb_filedef *_upb_symtab_addfile(
upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
const upb_msglayout **layouts, upb_status *status) {
upb_arena *file_arena = upb_arena_new();
upb_filedef *file = upb_arena_malloc(file_arena, sizeof(*file));
bool ok = true;
upb_filedef *file;
symtab_addctx ctx;
if (!file_arena) return NULL;
file = upb_arena_malloc(file_arena, sizeof(*file));
if (!file) goto done;
ctx.file = file;
ctx.symtab = s;
ctx.file_arena = file_arena;
@ -5354,8 +5362,8 @@ static const upb_filedef *_upb_symtab_addfile(
if (UPB_UNLIKELY(setjmp(ctx.err))) {
UPB_ASSERT(!upb_ok(status));
ok = false;
remove_filedef(s, file);
file = NULL;
} else {
build_filedef(&ctx, file, file_proto);
upb_strtable_insert3(&s->files, file->name, strlen(file->name),
@ -5364,8 +5372,9 @@ static const upb_filedef *_upb_symtab_addfile(
upb_arena_fuse(s->arena, file_arena);
}
done:
upb_arena_free(file_arena);
return ok ? file : NULL;
return file;
}
const upb_filedef *upb_symtab_addfile(
@ -6246,6 +6255,8 @@ static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) {
size_t size = UPB_MAX(8, 2 * oldsize);
*buf = upb_arena_realloc(d->arena, *buf, len, size);
if (!*buf) jsondec_err(d, "Out of memory");
*end = *buf + len;
*buf_end = *buf + size;
}

@ -506,7 +506,7 @@ UPB_INLINE uint64_t _upb_be_swap64(uint64_t val) {
}
UPB_INLINE int _upb_lg2ceil(int x) {
if (x == 0) return 0;
if (x <= 1) return 0;
#ifdef __GNUC__
return 32 - __builtin_clz(x - 1);
#else
@ -1043,7 +1043,8 @@ UPB_INLINE upb_msg *_upb_msg_new_inl(const upb_msglayout *l, upb_arena *a) {
upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a);
UPB_INLINE upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
return UPB_PTR_AT(msg, -sizeof(upb_msg_internal), upb_msg_internal);
ptrdiff_t size = sizeof(upb_msg_internal);
return (upb_msg_internal*)((char*)msg - size);
}
/* Clears the given message. */
@ -1138,9 +1139,11 @@ typedef struct {
uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */
size_t len; /* Measured in elements. */
size_t size; /* Measured in elements. */
uint64_t junk;
} upb_array;
UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) {
UPB_ASSERT((arr->data & 7) <= 4);
return (void*)(arr->data & ~(uintptr_t)7);
}
@ -1150,15 +1153,17 @@ UPB_INLINE void *_upb_array_ptr(upb_array *arr) {
UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) {
UPB_ASSERT(elem_size_lg2 <= 4);
UPB_ASSERT(((uintptr_t)ptr & 7) == 0);
return (uintptr_t)ptr | (unsigned)elem_size_lg2;
}
UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size,
int elem_size_lg2) {
const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_array), 8);
const size_t bytes = sizeof(upb_array) + (init_size << elem_size_lg2);
upb_array *arr = (upb_array*)upb_arena_malloc(a, bytes);
if (!arr) return NULL;
arr->data = _upb_tag_arrptr(arr + 1, elem_size_lg2);
arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2);
arr->len = 0;
arr->size = init_size;
return arr;
@ -1331,17 +1336,17 @@ UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) {
}
}
UPB_INLINE upb_value _upb_map_tovalue(const void *val, size_t size,
upb_arena *a) {
upb_value ret = {0};
UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval,
upb_arena *a) {
if (size == UPB_MAPTYPE_STRING) {
upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp));
if (!strp) return false;
*strp = *(upb_strview*)val;
ret = upb_value_ptr(strp);
*msgval = upb_value_ptr(strp);
} else {
memcpy(&ret, val, size);
memcpy(msgval, val, size);
}
return ret;
return true;
}
UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) {
@ -1383,7 +1388,8 @@ UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) {
UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size,
void *val, size_t val_size, upb_arena *arena) {
upb_strview strkey = _upb_map_tokey(key, key_size);
upb_value tabval = _upb_map_tovalue(val, val_size, arena);
upb_value tabval = {0};
if (!_upb_map_tovalue(val, val_size, &tabval, arena)) return false;
upb_alloc *a = upb_arena_alloc(arena);
/* TODO(haberman): add overwrite operation to minimize number of lookups. */

Loading…
Cancel
Save