diff --git a/spa/include/spa/pod/builder.h b/spa/include/spa/pod/builder.h index f4b68fd63..f3277d40a 100644 --- a/spa/include/spa/pod/builder.h +++ b/spa/include/spa/pod/builder.h @@ -167,7 +167,7 @@ SPA_API_POD_BUILDER void spa_pod_builder_remove(struct spa_pod_builder *builder, SPA_API_POD_BUILDER int spa_pod_builder_pad(struct spa_pod_builder *builder, uint32_t size) { uint64_t zeroes = 0; - size = SPA_ROUND_UP_N(size, 8) - size; + size = SPA_ROUND_UP_N(size, SPA_POD_ALIGN) - size; return size ? spa_pod_builder_raw(builder, &zeroes, size) : 0; } diff --git a/spa/include/spa/pod/iter.h b/spa/include/spa/pod/iter.h index f77f47e70..87c5b17a3 100644 --- a/spa/include/spa/pod/iter.h +++ b/spa/include/spa/pod/iter.h @@ -44,7 +44,7 @@ SPA_API_POD_ITER bool spa_pod_is_inside(const void *pod, uint32_t size, const vo SPA_API_POD_ITER void *spa_pod_next(const void *iter) { - return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_SIZE(iter), 8), void); + return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_SIZE(iter), SPA_POD_ALIGN), void); } SPA_API_POD_ITER struct spa_pod_prop *spa_pod_prop_first(const struct spa_pod_object_body *body) @@ -63,7 +63,7 @@ SPA_API_POD_ITER bool spa_pod_prop_is_inside(const struct spa_pod_object_body *b SPA_API_POD_ITER struct spa_pod_prop *spa_pod_prop_next(const struct spa_pod_prop *iter) { - return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_PROP_SIZE(iter), 8), struct spa_pod_prop); + return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_PROP_SIZE(iter), SPA_POD_ALIGN), struct spa_pod_prop); } SPA_API_POD_ITER struct spa_pod_control *spa_pod_control_first(const struct spa_pod_sequence_body *body) @@ -82,7 +82,7 @@ SPA_API_POD_ITER bool spa_pod_control_is_inside(const struct spa_pod_sequence_bo SPA_API_POD_ITER struct spa_pod_control *spa_pod_control_next(const struct spa_pod_control *iter) { - return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_CONTROL_SIZE(iter), 8), struct spa_pod_control); + return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_CONTROL_SIZE(iter), SPA_POD_ALIGN), struct spa_pod_control); } #define SPA_POD_ARRAY_BODY_FOREACH(body, _size, iter) \ @@ -136,19 +136,25 @@ SPA_API_POD_ITER void *spa_pod_from_data(void *data, size_t maxsize, off_t offse maxsize - size < (uint32_t)offset) return NULL; pod = SPA_PTROFF(data, offset, void); + if (!SPA_IS_ALIGNED(pod, SPA_POD_ALIGN)) + return NULL; if (SPA_POD_BODY_SIZE(pod) > size - sizeof(struct spa_pod)) return NULL; return pod; } +#define SPA_POD_CHECK_0(pod,_type) ((pod)->type == (_type) && SPA_IS_ALIGNED(pod, SPA_POD_ALIGN)) +#define SPA_POD_CHECK(pod,_type,_size) \ + (SPA_POD_CHECK_0(pod,_type) && (pod)->size >= (_size)) + SPA_API_POD_ITER int spa_pod_is_none(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_None); + return SPA_POD_CHECK_0(pod, SPA_TYPE_None); } SPA_API_POD_ITER int spa_pod_is_bool(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Bool && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t)); + return SPA_POD_CHECK(pod, SPA_TYPE_Bool, sizeof(int32_t)); } SPA_API_POD_ITER int spa_pod_get_bool(const struct spa_pod *pod, bool *value) @@ -161,7 +167,7 @@ SPA_API_POD_ITER int spa_pod_get_bool(const struct spa_pod *pod, bool *value) SPA_API_POD_ITER int spa_pod_is_id(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Id && SPA_POD_BODY_SIZE(pod) >= sizeof(uint32_t)); + return SPA_POD_CHECK(pod, SPA_TYPE_Id, sizeof(uint32_t)); } SPA_API_POD_ITER int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value) @@ -174,7 +180,7 @@ SPA_API_POD_ITER int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value) SPA_API_POD_ITER int spa_pod_is_int(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Int && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t)); + return SPA_POD_CHECK(pod, SPA_TYPE_Int, sizeof(int32_t)); } SPA_API_POD_ITER int spa_pod_get_int(const struct spa_pod *pod, int32_t *value) @@ -187,7 +193,7 @@ SPA_API_POD_ITER int spa_pod_get_int(const struct spa_pod *pod, int32_t *value) SPA_API_POD_ITER int spa_pod_is_long(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Long && SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t)); + return SPA_POD_CHECK(pod, SPA_TYPE_Long, sizeof(int64_t)); } SPA_API_POD_ITER int spa_pod_get_long(const struct spa_pod *pod, int64_t *value) @@ -200,7 +206,7 @@ SPA_API_POD_ITER int spa_pod_get_long(const struct spa_pod *pod, int64_t *value) SPA_API_POD_ITER int spa_pod_is_float(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Float && SPA_POD_BODY_SIZE(pod) >= sizeof(float)); + return SPA_POD_CHECK(pod, SPA_TYPE_Float, sizeof(float)); } SPA_API_POD_ITER int spa_pod_get_float(const struct spa_pod *pod, float *value) @@ -213,7 +219,7 @@ SPA_API_POD_ITER int spa_pod_get_float(const struct spa_pod *pod, float *value) SPA_API_POD_ITER int spa_pod_is_double(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Double && SPA_POD_BODY_SIZE(pod) >= sizeof(double)); + return SPA_POD_CHECK(pod, SPA_TYPE_Double, sizeof(double)); } SPA_API_POD_ITER int spa_pod_get_double(const struct spa_pod *pod, double *value) @@ -227,9 +233,8 @@ SPA_API_POD_ITER int spa_pod_get_double(const struct spa_pod *pod, double *value SPA_API_POD_ITER int spa_pod_is_string(const struct spa_pod *pod) { const char *s = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod); - return (SPA_POD_TYPE(pod) == SPA_TYPE_String && - SPA_POD_BODY_SIZE(pod) > 0 && - s[SPA_POD_BODY_SIZE(pod)-1] == '\0'); + return SPA_POD_CHECK(pod, SPA_TYPE_String, 1) && + s[pod->size-1] == '\0'; } SPA_API_POD_ITER int spa_pod_get_string(const struct spa_pod *pod, const char **value) @@ -252,7 +257,7 @@ SPA_API_POD_ITER int spa_pod_copy_string(const struct spa_pod *pod, size_t maxle SPA_API_POD_ITER int spa_pod_is_bytes(const struct spa_pod *pod) { - return SPA_POD_TYPE(pod) == SPA_TYPE_Bytes; + return SPA_POD_CHECK_0(pod, SPA_TYPE_Bytes); } SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len) @@ -266,8 +271,7 @@ SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **v SPA_API_POD_ITER int spa_pod_is_pointer(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Pointer && - SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_pointer_body)); + return SPA_POD_CHECK(pod, SPA_TYPE_Pointer, sizeof(struct spa_pod_pointer_body)); } SPA_API_POD_ITER int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value) @@ -281,8 +285,7 @@ SPA_API_POD_ITER int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *ty SPA_API_POD_ITER int spa_pod_is_fd(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Fd && - SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t)); + return SPA_POD_CHECK(pod, SPA_TYPE_Fd, sizeof(int64_t)); } SPA_API_POD_ITER int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value) @@ -295,8 +298,7 @@ SPA_API_POD_ITER int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value) SPA_API_POD_ITER int spa_pod_is_rectangle(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Rectangle && - SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_rectangle)); + return SPA_POD_CHECK(pod, SPA_TYPE_Rectangle, sizeof(struct spa_rectangle)); } SPA_API_POD_ITER int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value) @@ -309,8 +311,7 @@ SPA_API_POD_ITER int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa SPA_API_POD_ITER int spa_pod_is_fraction(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Fraction && - SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_fraction)); + return SPA_POD_CHECK(pod, SPA_TYPE_Fraction, sizeof(struct spa_fraction)); } SPA_API_POD_ITER int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value) @@ -322,14 +323,12 @@ SPA_API_POD_ITER int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_ SPA_API_POD_ITER int spa_pod_is_bitmap(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Bitmap && - SPA_POD_BODY_SIZE(pod) >= sizeof(uint8_t)); + return SPA_POD_CHECK(pod, SPA_TYPE_Bitmap, sizeof(uint8_t)); } SPA_API_POD_ITER int spa_pod_is_array(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Array && - SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_array_body)); + return SPA_POD_CHECK(pod, SPA_TYPE_Array, sizeof(struct spa_pod_array_body)); } SPA_API_POD_ITER void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values) @@ -353,8 +352,7 @@ SPA_API_POD_ITER uint32_t spa_pod_copy_array(const struct spa_pod *pod, uint32_t SPA_API_POD_ITER int spa_pod_is_choice(const struct spa_pod *pod) { - return (SPA_POD_TYPE(pod) == SPA_TYPE_Choice && - SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_choice_body)); + return SPA_POD_CHECK(pod, SPA_TYPE_Choice, sizeof(struct spa_pod_choice_body)); } SPA_API_POD_ITER struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice) diff --git a/spa/include/spa/pod/parser.h b/spa/include/spa/pod/parser.h index 922992e92..a3a5527bc 100644 --- a/spa/include/spa/pod/parser.h +++ b/spa/include/spa/pod/parser.h @@ -79,8 +79,8 @@ spa_pod_parser_deref(struct spa_pod_parser *parser, uint32_t offset, uint32_t si * Check that the pointer is aligned and that the size (rounded * to the next multiple of 8) is in bounds. */ - if (SPA_IS_ALIGNED(pod, __alignof__(struct spa_pod)) && - long_offset + SPA_ROUND_UP_N((uint64_t)SPA_POD_BODY_SIZE(pod), 8) <= size) + if (SPA_IS_ALIGNED(pod, SPA_POD_ALIGN) && + long_offset + SPA_ROUND_UP_N((uint64_t)SPA_POD_BODY_SIZE(pod), SPA_POD_ALIGN) <= size) return (struct spa_pod *)pod; } return NULL; @@ -110,7 +110,7 @@ SPA_API_POD_PARSER struct spa_pod *spa_pod_parser_current(struct spa_pod_parser SPA_API_POD_PARSER void spa_pod_parser_advance(struct spa_pod_parser *parser, const struct spa_pod *pod) { - parser->state.offset += SPA_ROUND_UP_N(SPA_POD_SIZE(pod), 8); + parser->state.offset += SPA_ROUND_UP_N(SPA_POD_SIZE(pod), SPA_POD_ALIGN); } SPA_API_POD_PARSER struct spa_pod *spa_pod_parser_next(struct spa_pod_parser *parser) @@ -125,7 +125,7 @@ SPA_API_POD_PARSER int spa_pod_parser_pop(struct spa_pod_parser *parser, struct spa_pod_frame *frame) { parser->state.frame = frame->parent; - parser->state.offset = frame->offset + SPA_ROUND_UP_N(SPA_POD_SIZE(&frame->pod), 8); + parser->state.offset = frame->offset + SPA_ROUND_UP_N(SPA_POD_SIZE(&frame->pod), SPA_POD_ALIGN); return 0; } diff --git a/spa/include/spa/pod/pod.h b/spa/include/spa/pod/pod.h index 398236e79..854a65abc 100644 --- a/spa/include/spa/pod/pod.h +++ b/spa/include/spa/pod/pod.h @@ -17,6 +17,8 @@ extern "C" { * \{ */ +#define SPA_POD_ALIGN 8 + #define SPA_POD_BODY_SIZE(pod) (((struct spa_pod*)(pod))->size) #define SPA_POD_TYPE(pod) (((struct spa_pod*)(pod))->type) #define SPA_POD_SIZE(pod) ((uint64_t)sizeof(struct spa_pod) + SPA_POD_BODY_SIZE(pod)) @@ -30,7 +32,7 @@ extern "C" { struct spa_pod { uint32_t size; /* size of the body */ uint32_t type; /* a basic id of enum spa_type */ -}; +} SPA_ALIGNED(SPA_POD_ALIGN); #define SPA_POD_VALUE(type,pod) (((type*)(pod))->value) diff --git a/test/test-spa-pod.c b/test/test-spa-pod.c index e84b5a18e..f499e818b 100644 --- a/test/test-spa-pod.c +++ b/test/test-spa-pod.c @@ -524,6 +524,8 @@ PWTEST(pod_build) spa_assert_se(memcmp(&val.F, &SPA_FRACTION(25,1), sizeof(struct spa_fraction)) == 0); spa_assert_se((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod)); + spa_assert_se(array->type == SPA_TYPE_Array); + spa_assert_se(array->size >= sizeof(struct spa_pod_array_body)); spa_assert_se(spa_pod_is_array(pod)); spa_assert_se(SPA_POD_ARRAY_VALUE_TYPE(pod) == SPA_TYPE_Int); spa_assert_se(SPA_POD_ARRAY_VALUE_SIZE(pod) == sizeof(int32_t)); @@ -542,6 +544,8 @@ PWTEST(pod_build) } spa_assert_se((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod)); + spa_assert_se(array->type == SPA_TYPE_Array); + spa_assert_se(array->size >= sizeof(struct spa_pod_array_body)); spa_assert_se(spa_pod_is_array(pod)); spa_assert_se(SPA_POD_ARRAY_VALUE_TYPE(pod) == SPA_TYPE_Long); spa_assert_se(SPA_POD_ARRAY_VALUE_SIZE(pod) == sizeof(int64_t)); @@ -691,6 +695,10 @@ PWTEST(pod_empty) array = spa_pod_builder_pop(&b, &f); spa_assert_se(array != NULL); spa_debug_mem(0, array, 16); + spa_assert_se(array->type == SPA_TYPE_Array); + spa_assert_se(array->size == sizeof(struct spa_pod_array_body)); + spa_assert_se(SPA_POD_ARRAY_VALUE_TYPE(array) == SPA_TYPE_Id); + spa_assert_se(SPA_POD_ARRAY_VALUE_SIZE(array) == 4); spa_assert_se(spa_pod_is_array(array)); a2 = spa_pod_get_array(array, &n_vals); spa_assert_se(a2 != NULL); @@ -700,6 +708,8 @@ PWTEST(pod_empty) spa_assert_se(spa_pod_builder_push_array(&b, &f) == 0); array = spa_pod_builder_pop(&b, &f); spa_assert_se(array != NULL); + spa_assert_se(array->type == SPA_TYPE_Array); + spa_assert_se(array->size >= sizeof(struct spa_pod_array_body)); spa_assert_se(spa_pod_is_array(array)); a2 = spa_pod_get_array(array, &n_vals); spa_assert_se(a2 != NULL); @@ -710,6 +720,8 @@ PWTEST(pod_empty) spa_assert_se(spa_pod_builder_none(&b) == 0); array = spa_pod_builder_pop(&b, &f); spa_assert_se(array != NULL); + spa_assert_se(array->type == SPA_TYPE_Array); + spa_assert_se(array->size >= sizeof(struct spa_pod_array_body)); spa_assert_se(spa_pod_is_array(array)); a2 = spa_pod_get_array(array, &n_vals); spa_assert_se(a2 != NULL); @@ -718,6 +730,8 @@ PWTEST(pod_empty) spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_assert_se(spa_pod_builder_array(&b, 4, SPA_TYPE_Id, 0, NULL) == 0); array = (struct spa_pod*)buffer; + spa_assert_se(array->type == SPA_TYPE_Array); + spa_assert_se(array->size >= sizeof(struct spa_pod_array_body)); spa_assert_se(spa_pod_is_array(array)); a2 = spa_pod_get_array(array, &n_vals); spa_assert_se(a2 != NULL); @@ -730,6 +744,10 @@ PWTEST(pod_empty) choice = spa_pod_builder_pop(&b, &f); spa_assert_se(choice != NULL); spa_debug_mem(0, choice, 32); + spa_assert_se(choice->type == SPA_TYPE_Choice); + spa_assert_se(choice->size == sizeof(struct spa_pod_choice_body)); + spa_assert_se(SPA_POD_CHOICE_TYPE(choice) == SPA_CHOICE_None); + spa_assert_se(SPA_POD_CHOICE_CHILD(choice)->size == 4); spa_assert_se(spa_pod_is_choice(choice)); ch2 = spa_pod_get_values(choice, &n_vals, &ch); spa_assert_se(ch2 != NULL); @@ -739,6 +757,8 @@ PWTEST(pod_empty) spa_assert_se(spa_pod_builder_push_choice(&b, &f, 0, 0) == 0); choice = spa_pod_builder_pop(&b, &f); spa_assert_se(choice != NULL); + spa_assert_se(SPA_POD_CHOICE_TYPE(choice) == SPA_CHOICE_None); + spa_assert_se(SPA_POD_CHOICE_CHILD(choice)->size == 0); spa_assert_se(spa_pod_is_choice(choice)); ch2 = spa_pod_get_values(choice, &n_vals, &ch); spa_assert_se(ch2 != NULL); @@ -749,6 +769,8 @@ PWTEST(pod_empty) spa_assert_se(spa_pod_builder_none(&b) == 0); choice = spa_pod_builder_pop(&b, &f); spa_assert_se(choice != NULL); + spa_assert_se(SPA_POD_CHOICE_TYPE(choice) == SPA_CHOICE_None); + spa_assert_se(SPA_POD_CHOICE_CHILD(choice)->size == 0); spa_assert_se(spa_pod_is_choice(choice)); ch2 = spa_pod_get_values(choice, &n_vals, &ch); spa_assert_se(ch2 != NULL);