Rework undefined behavior fixes.
Previous commit broke using_union_messages example.
diff --git a/pb_common.c b/pb_common.c
index 636d73a..911ae4c 100644
--- a/pb_common.c
+++ b/pb_common.c
@@ -67,31 +67,40 @@
iter->data_size = (pb_size_t)word3;
}
- iter->pField = (char*)iter->message + data_offset;
-
- if (size_offset)
+ if (!iter->message)
{
- iter->pSize = (char*)iter->pField - size_offset;
- }
- else if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED &&
- (PB_ATYPE(iter->type) == PB_ATYPE_STATIC ||
- PB_ATYPE(iter->type) == PB_ATYPE_POINTER))
- {
- /* Fixed count array */
- iter->pSize = &iter->array_size;
- }
- else
- {
+ /* Avoid doing arithmetic on null pointers, it is undefined */
+ iter->pField = NULL;
iter->pSize = NULL;
}
-
- if (PB_ATYPE(iter->type) == PB_ATYPE_POINTER && iter->pField != NULL)
- {
- iter->pData = *(void**)iter->pField;
- }
else
{
- iter->pData = iter->pField;
+ iter->pField = (char*)iter->message + data_offset;
+
+ if (size_offset)
+ {
+ iter->pSize = (char*)iter->pField - size_offset;
+ }
+ else if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED &&
+ (PB_ATYPE(iter->type) == PB_ATYPE_STATIC ||
+ PB_ATYPE(iter->type) == PB_ATYPE_POINTER))
+ {
+ /* Fixed count array */
+ iter->pSize = &iter->array_size;
+ }
+ else
+ {
+ iter->pSize = NULL;
+ }
+
+ if (PB_ATYPE(iter->type) == PB_ATYPE_POINTER && iter->pField != NULL)
+ {
+ iter->pData = *(void**)iter->pField;
+ }
+ else
+ {
+ iter->pData = iter->pField;
+ }
}
if (PB_LTYPE_IS_SUBMSG(iter->type))
@@ -151,11 +160,6 @@
iter->descriptor = desc;
iter->message = message;
- if (!desc || !message)
- {
- return false;
- }
-
return load_descriptor_values(iter);
}
diff --git a/pb_decode.c b/pb_decode.c
index 484c1cd..4244fe0 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -819,9 +819,9 @@
pb_field_iter_t iter;
if (!pb_field_iter_begin_extension(&iter, extension))
- return true; /* Empty field list or extension->dest is null for static fields */
+ PB_RETURN_ERROR(stream, "invalid extension");
- if (iter.tag != tag)
+ if (iter.tag != tag || !iter.message)
return true;
extension->found = true;